Skip to content

Commit

Permalink
bpo-41919, test_codecs: Move codecs.register calls to setUp() (GH-22513)
Browse files Browse the repository at this point in the history
* Move the codecs' (un)register operation to testcases.
* Remove _codecs._forget_codec() and _PyCodec_Forget()
  • Loading branch information
shihai1991 authored Oct 16, 2020
1 parent cf693e5 commit c9f696c
Show file tree
Hide file tree
Showing 7 changed files with 16 additions and 112 deletions.
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

0 comments on commit c9f696c

Please sign in to comment.