bpo-41919, test_codecs: Move codecs.register calls to setUp() (GH-22513)

* Move the codecs' (un)register operation to testcases.
* Remove _codecs._forget_codec() and _PyCodec_Forget()
This commit is contained in:
Hai Shi 2020-10-16 16:34:15 +08:00 committed by GitHub
parent cf693e537d
commit c9f696cb96
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 16 additions and 112 deletions

View File

@ -20,12 +20,15 @@ def codec_search_function(encoding):
return tuple(testcodec.getregentry()) return tuple(testcodec.getregentry())
return None return None
codecs.register(codec_search_function)
# test codec's name (see test/testcodec.py) # test codec's name (see test/testcodec.py)
codecname = 'testcodec' codecname = 'testcodec'
class CharmapCodecTest(unittest.TestCase): class CharmapCodecTest(unittest.TestCase):
def setUp(self):
codecs.register(codec_search_function)
self.addCleanup(codecs.unregister, codec_search_function)
def test_constructorx(self): def test_constructorx(self):
self.assertEqual(str(b'abc', codecname), 'abc') self.assertEqual(str(b'abc', codecname), 'abc')
self.assertEqual(str(b'xdef', codecname), 'abcdef') self.assertEqual(str(b'xdef', codecname), 'abcdef')

View File

@ -2754,29 +2754,14 @@ _TEST_CODECS = {}
def _get_test_codec(codec_name): def _get_test_codec(codec_name):
return _TEST_CODECS.get(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): class ExceptionChainingTest(unittest.TestCase):
def setUp(self): def setUp(self):
# There's no way to unregister a codec search function, so we just self.codec_name = 'exception_chaining_test'
# ensure we render this one fairly harmless after the test codecs.register(_get_test_codec)
# case finishes by using the test case repr as the codec name self.addCleanup(codecs.unregister, _get_test_codec)
# 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()
# We store the object to raise on the instance because of a bad # We store the object to raise on the instance because of a bad
# interaction between the codec caching (which means we can't # interaction between the codec caching (which means we can't
@ -2791,10 +2776,6 @@ class ExceptionChainingTest(unittest.TestCase):
_TEST_CODECS.pop(self.codec_name, None) _TEST_CODECS.pop(self.codec_name, None)
# Issue #22166: Also pop from caches to avoid appearance of ref leaks # Issue #22166: Also pop from caches to avoid appearance of ref leaks
encodings._cache.pop(self.codec_name, None) encodings._cache.pop(self.codec_name, None)
try:
_forget_codec(self.codec_name)
except KeyError:
pass
def set_codec(self, encode, decode): def set_codec(self, encode, decode):
codec_info = codecs.CodecInfo(encode, decode, codec_info = codecs.CodecInfo(encode, decode,

View File

@ -2529,10 +2529,6 @@ class StatefulIncrementalDecoder(codecs.IncrementalDecoder):
streamreader=None, streamwriter=None, streamreader=None, streamwriter=None,
incrementaldecoder=cls) incrementaldecoder=cls)
# Register the previous decoder for testing.
# Disabled by default, tests will enable it.
codecs.register(StatefulIncrementalDecoder.lookupTestDecoder)
class StatefulIncrementalDecoderTest(unittest.TestCase): class StatefulIncrementalDecoderTest(unittest.TestCase):
""" """
@ -2583,6 +2579,9 @@ class TextIOWrapperTest(unittest.TestCase):
self.testdata = b"AAA\r\nBBB\rCCC\r\nDDD\nEEE\r\n" self.testdata = b"AAA\r\nBBB\rCCC\r\nDDD\nEEE\r\n"
self.normalized = b"AAA\nBBB\nCCC\nDDD\nEEE\n".decode("ascii") self.normalized = b"AAA\nBBB\nCCC\nDDD\nEEE\n".decode("ascii")
os_helper.unlink(os_helper.TESTFN) os_helper.unlink(os_helper.TESTFN)
codecs.register(StatefulIncrementalDecoder.lookupTestDecoder)
self.addCleanup(codecs.unregister,
StatefulIncrementalDecoder.lookupTestDecoder)
def tearDown(self): def tearDown(self):
os_helper.unlink(os_helper.TESTFN) os_helper.unlink(os_helper.TESTFN)

View File

@ -36,7 +36,6 @@ def search_function(encoding):
return (encode2, decode2, None, None) return (encode2, decode2, None, None)
else: else:
return None return None
codecs.register(search_function)
def duplicate_string(text): def duplicate_string(text):
""" """
@ -58,6 +57,10 @@ class UnicodeTest(string_tests.CommonTest,
type2test = str type2test = str
def setUp(self):
codecs.register(search_function)
self.addCleanup(codecs.unregister, search_function)
def checkequalnofix(self, result, object, methodname, *args): def checkequalnofix(self, result, object, methodname, *args):
method = getattr(object, methodname) method = getattr(object, methodname)
realresult = method(*args) realresult = method(*args)

View File

@ -160,25 +160,6 @@ _codecs_decode_impl(PyObject *module, PyObject *obj, const char *encoding,
/* --- Helpers ------------------------------------------------------------ */ /* --- 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 static
PyObject *codec_tuple(PyObject *decoded, PyObject *codec_tuple(PyObject *decoded,
Py_ssize_t len) Py_ssize_t len)
@ -1057,7 +1038,6 @@ static PyMethodDef _codecs_functions[] = {
_CODECS_CODE_PAGE_DECODE_METHODDEF _CODECS_CODE_PAGE_DECODE_METHODDEF
_CODECS_REGISTER_ERROR_METHODDEF _CODECS_REGISTER_ERROR_METHODDEF
_CODECS_LOOKUP_ERROR_METHODDEF _CODECS_LOOKUP_ERROR_METHODDEF
_CODECS__FORGET_CODEC_METHODDEF
{NULL, NULL} /* sentinel */ {NULL, NULL} /* sentinel */
}; };

View File

@ -217,43 +217,6 @@ exit:
return return_value; return return_value;
} }
PyDoc_STRVAR(_codecs__forget_codec__doc__,
"_forget_codec($module, encoding, /)\n"
"--\n"
"\n"
"Purge the named codec from the internal codec lookup cache");
#define _CODECS__FORGET_CODEC_METHODDEF \
{"_forget_codec", (PyCFunction)_codecs__forget_codec, METH_O, _codecs__forget_codec__doc__},
static PyObject *
_codecs__forget_codec_impl(PyObject *module, const char *encoding);
static PyObject *
_codecs__forget_codec(PyObject *module, PyObject *arg)
{
PyObject *return_value = NULL;
const char *encoding;
if (!PyUnicode_Check(arg)) {
_PyArg_BadArgument("_forget_codec", "argument", "str", arg);
goto exit;
}
Py_ssize_t encoding_length;
encoding = PyUnicode_AsUTF8AndSize(arg, &encoding_length);
if (encoding == NULL) {
goto exit;
}
if (strlen(encoding) != (size_t)encoding_length) {
PyErr_SetString(PyExc_ValueError, "embedded null character");
goto exit;
}
return_value = _codecs__forget_codec_impl(module, encoding);
exit:
return return_value;
}
PyDoc_STRVAR(_codecs_escape_decode__doc__, PyDoc_STRVAR(_codecs_escape_decode__doc__,
"escape_decode($module, data, errors=None, /)\n" "escape_decode($module, data, errors=None, /)\n"
"--\n" "--\n"
@ -2838,4 +2801,4 @@ exit:
#ifndef _CODECS_CODE_PAGE_ENCODE_METHODDEF #ifndef _CODECS_CODE_PAGE_ENCODE_METHODDEF
#define _CODECS_CODE_PAGE_ENCODE_METHODDEF #define _CODECS_CODE_PAGE_ENCODE_METHODDEF
#endif /* !defined(_CODECS_CODE_PAGE_ENCODE_METHODDEF) */ #endif /* !defined(_CODECS_CODE_PAGE_ENCODE_METHODDEF) */
/*[clinic end generated code: output=9a97e2ddf3e69072 input=a9049054013a1b77]*/ /*[clinic end generated code: output=557c3b37e4c492ac input=a9049054013a1b77]*/

View File

@ -208,31 +208,6 @@ PyObject *_PyCodec_Lookup(const char *encoding)
return NULL; 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. */ /* Codec registry encoding check API. */
int PyCodec_KnownEncoding(const char *encoding) int PyCodec_KnownEncoding(const char *encoding)