[Python-checkins] cpython (merge 3.4 -> default): Merge fix for issue #22166 from 3.4

nick.coghlan python-checkins at python.org
Mon Sep 15 13:56:04 CEST 2014


http://hg.python.org/cpython/rev/322ee2f2e922
changeset: 92436:322ee2f2e922
parent: 92434:5eb95d41ee43
parent: 92435:fcf45ec7863e
user: Nick Coghlan <ncoghlan at gmail.com>
date: Mon Sep 15 23:55:16 2014 +1200
summary:
 Merge fix for issue #22166 from 3.4
files:
 Include/codecs.h | 4 ++
 Lib/test/test_codecs.py | 14 +++++++
 Misc/NEWS | 4 ++
 Modules/_codecsmodule.c | 54 +++++++++++++++++++++++++++++
 Python/codecs.c | 26 +++++++++++++
 5 files changed, 102 insertions(+), 0 deletions(-)
diff --git a/Include/codecs.h b/Include/codecs.h
--- a/Include/codecs.h
+++ b/Include/codecs.h
@@ -49,6 +49,10 @@
 PyAPI_FUNC(PyObject *) _PyCodec_Lookup(
 const char *encoding
 );
+
+PyAPI_FUNC(int) _PyCodec_Forget(
+ const char *encoding
+ );
 #endif
 
 /* Codec registry encoding check API.
diff --git a/Lib/test/test_codecs.py b/Lib/test/test_codecs.py
--- a/Lib/test/test_codecs.py
+++ b/Lib/test/test_codecs.py
@@ -2586,6 +2586,14 @@
 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):
@@ -2611,6 +2619,12 @@
 
 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,
diff --git a/Misc/NEWS b/Misc/NEWS
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -525,6 +525,10 @@
 
 - Issue #21525: Most Tkinter methods which accepted tuples now accept lists too.
 
+- Issue #22166: with the assistance of a new internal _codecs._forget_codec
+ helping function, test_codecs now clears the encoding caches to avoid the
+ appearance of a reference leak
+
 - Issue #22236: Tkinter tests now don't reuse default root window. New root
 window is created for every test class.
 
diff --git a/Modules/_codecsmodule.c b/Modules/_codecsmodule.c
--- a/Modules/_codecsmodule.c
+++ b/Modules/_codecsmodule.c
@@ -42,6 +42,12 @@
 #include <windows.h>
 #endif
 
+/*[clinic input]
+module _codecs
+[clinic start generated code]*/
+/*[clinic end generated code: output=da39a3ee5e6b4b0d input=e1390e3da3cb9deb]*/
+
+
 /* --- Registry ----------------------------------------------------------- */
 
 PyDoc_STRVAR(register__doc__,
@@ -138,6 +144,53 @@
 
 /* --- Helpers ------------------------------------------------------------ */
 
+/*[clinic input]
+_codecs._forget_codec
+
+ encoding: str
+ /
+
+Purge the named codec from the internal codec lookup cache
+[clinic start generated code]*/
+
+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_VARARGS, _codecs__forget_codec__doc__},
+
+static PyObject *
+_codecs__forget_codec_impl(PyModuleDef *module, const char *encoding);
+
+static PyObject *
+_codecs__forget_codec(PyModuleDef *module, PyObject *args)
+{
+ PyObject *return_value = NULL;
+ const char *encoding;
+
+ if (!PyArg_ParseTuple(args,
+ "s:_forget_codec",
+ &encoding))
+ goto exit;
+ return_value = _codecs__forget_codec_impl(module, encoding);
+
+exit:
+ return return_value;
+}
+
+static PyObject *
+_codecs__forget_codec_impl(PyModuleDef *module, const char *encoding)
+/*[clinic end generated code: output=a75e631591702a5c input=18d5d92d0e386c38]*/
+{
+ if (_PyCodec_Forget(encoding) < 0) {
+ return NULL;
+ };
+ Py_RETURN_NONE;
+}
+
 static
 PyObject *codec_tuple(PyObject *unicode,
 Py_ssize_t len)
@@ -1172,6 +1225,7 @@
 register_error__doc__},
 {"lookup_error", lookup_error, METH_VARARGS,
 lookup_error__doc__},
+ _CODECS__FORGET_CODEC_METHODDEF
 {NULL, NULL} /* sentinel */
 };
 
diff --git a/Python/codecs.c b/Python/codecs.c
--- a/Python/codecs.c
+++ b/Python/codecs.c
@@ -185,6 +185,32 @@
 return NULL;
 }
 
+int _PyCodec_Forget(const char *encoding)
+{
+ PyInterpreterState *interp;
+ PyObject *v;
+ int result;
+
+ interp = PyThreadState_GET()->interp;
+ 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)
-- 
Repository URL: http://hg.python.org/cpython


More information about the Python-checkins mailing list

AltStyle によって変換されたページ (->オリジナル) /