Skip to content

bpo-41919: Move the codecs.register operation to the setup of testcases. #22513

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Oct 16, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions Lib/test/test_charmapcodec.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,15 @@ def codec_search_function(encoding):
return tuple(testcodec.getregentry())
return None

codecs.register(codec_search_function)

# test codec's name (see test/testcodec.py)
codecname = 'testcodec'

class CharmapCodecTest(unittest.TestCase):

def setUp(self):
codecs.register(codec_search_function)
self.addCleanup(codecs.unregister, codec_search_function)

def test_constructorx(self):
self.assertEqual(str(b'abc', codecname), 'abc')
self.assertEqual(str(b'xdef', codecname), 'abcdef')
Expand Down
25 changes: 3 additions & 22 deletions Lib/test/test_codecs.py
Original file line number Diff line number Diff line change
Expand Up @@ -2754,29 +2754,14 @@ def test_uu_invalid(self):

def _get_test_codec(codec_name):
return _TEST_CODECS.get(codec_name)
codecs.register(_get_test_codec) # Returns None, not usable as a decorator

try:
# Issue #22166: Also need to clear the internal cache in CPython
from _codecs import _forget_codec
except ImportError:
def _forget_codec(codec_name):
pass


class ExceptionChainingTest(unittest.TestCase):

def setUp(self):
# There's no way to unregister a codec search function, so we just
# ensure we render this one fairly harmless after the test
# case finishes by using the test case repr as the codec name
# The codecs module normalizes codec names, although this doesn't
# appear to be formally documented...
# We also make sure we use a truly unique id for the custom codec
# to avoid issues with the codec cache when running these tests
# multiple times (e.g. when hunting for refleaks)
unique_id = repr(self) + str(id(self))
self.codec_name = encodings.normalize_encoding(unique_id).lower()
self.codec_name = 'exception_chaining_test'
codecs.register(_get_test_codec)
self.addCleanup(codecs.unregister, _get_test_codec)

# We store the object to raise on the instance because of a bad
# interaction between the codec caching (which means we can't
Expand All @@ -2791,10 +2776,6 @@ def tearDown(self):
_TEST_CODECS.pop(self.codec_name, None)
# Issue #22166: Also pop from caches to avoid appearance of ref leaks
encodings._cache.pop(self.codec_name, None)
try:
_forget_codec(self.codec_name)
except KeyError:
pass

def set_codec(self, encode, decode):
codec_info = codecs.CodecInfo(encode, decode,
Expand Down
7 changes: 3 additions & 4 deletions Lib/test/test_io.py
Original file line number Diff line number Diff line change
Expand Up @@ -2529,10 +2529,6 @@ def lookupTestDecoder(cls, name):
streamreader=None, streamwriter=None,
incrementaldecoder=cls)

# Register the previous decoder for testing.
# Disabled by default, tests will enable it.
codecs.register(StatefulIncrementalDecoder.lookupTestDecoder)


class StatefulIncrementalDecoderTest(unittest.TestCase):
"""
Expand Down Expand Up @@ -2583,6 +2579,9 @@ def setUp(self):
self.testdata = b"AAA\r\nBBB\rCCC\r\nDDD\nEEE\r\n"
self.normalized = b"AAA\nBBB\nCCC\nDDD\nEEE\n".decode("ascii")
os_helper.unlink(os_helper.TESTFN)
codecs.register(StatefulIncrementalDecoder.lookupTestDecoder)
self.addCleanup(codecs.unregister,
StatefulIncrementalDecoder.lookupTestDecoder)

def tearDown(self):
os_helper.unlink(os_helper.TESTFN)
Expand Down
5 changes: 4 additions & 1 deletion Lib/test/test_unicode.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@ def decode2(input, errors="strict"):
return (encode2, decode2, None, None)
else:
return None
codecs.register(search_function)

def duplicate_string(text):
"""
Expand All @@ -58,6 +57,10 @@ class UnicodeTest(string_tests.CommonTest,

type2test = str

def setUp(self):
codecs.register(search_function)
self.addCleanup(codecs.unregister, search_function)

def checkequalnofix(self, result, object, methodname, *args):
method = getattr(object, methodname)
realresult = method(*args)
Expand Down
20 changes: 0 additions & 20 deletions Modules/_codecsmodule.c
Original file line number Diff line number Diff line change
Expand Up @@ -160,25 +160,6 @@ _codecs_decode_impl(PyObject *module, PyObject *obj, const char *encoding,

/* --- Helpers ------------------------------------------------------------ */

/*[clinic input]
_codecs._forget_codec

encoding: str
/

Purge the named codec from the internal codec lookup cache
[clinic start generated code]*/

static PyObject *
_codecs__forget_codec_impl(PyObject *module, const char *encoding)
/*[clinic end generated code: output=0bde9f0a5b084aa2 input=18d5d92d0e386c38]*/
{
if (_PyCodec_Forget(encoding) < 0) {
return NULL;
};
Py_RETURN_NONE;
}

static
PyObject *codec_tuple(PyObject *decoded,
Py_ssize_t len)
Expand Down Expand Up @@ -1057,7 +1038,6 @@ static PyMethodDef _codecs_functions[] = {
_CODECS_CODE_PAGE_DECODE_METHODDEF
_CODECS_REGISTER_ERROR_METHODDEF
_CODECS_LOOKUP_ERROR_METHODDEF
_CODECS__FORGET_CODEC_METHODDEF
{NULL, NULL} /* sentinel */
};

Expand Down
39 changes: 1 addition & 38 deletions Modules/clinic/_codecsmodule.c.h

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

25 changes: 0 additions & 25 deletions Python/codecs.c
Original file line number Diff line number Diff line change
Expand Up @@ -208,31 +208,6 @@ PyObject *_PyCodec_Lookup(const char *encoding)
return NULL;
}

int _PyCodec_Forget(const char *encoding)
{
PyObject *v;
int result;

PyInterpreterState *interp = _PyInterpreterState_GET();
if (interp->codec_search_path == NULL) {
return -1;
}

/* Convert the encoding to a normalized Python string: all
characters are converted to lower case, spaces and hyphens are
replaced with underscores. */
v = normalizestring(encoding);
if (v == NULL) {
return -1;
}

/* Drop the named codec from the internal cache */
result = PyDict_DelItem(interp->codec_search_cache, v);
Py_DECREF(v);

return result;
}

/* Codec registry encoding check API. */

int PyCodec_KnownEncoding(const char *encoding)
Expand Down