From f58f1c33c115a4f9dfb8ff2b753241d08f46aace Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Sat, 21 May 2011 02:13:22 +0200 Subject: [PATCH] Issue #12124: zipimport doesn't keep a reference to zlib.decompress() anymore to be able to unload the module. --- Lib/test/test_zipimport.py | 17 -------------- Misc/NEWS | 5 +++- Modules/zipimport.c | 47 +++++++++++++++++++------------------- 3 files changed, 27 insertions(+), 42 deletions(-) diff --git a/Lib/test/test_zipimport.py b/Lib/test/test_zipimport.py index 5974c8bfb6..a66738a778 100644 --- a/Lib/test/test_zipimport.py +++ b/Lib/test/test_zipimport.py @@ -25,11 +25,6 @@ import StringIO from traceback import extract_tb, extract_stack, print_tb raise_src = 'def do_raise(): raise TypeError\n' -# so we only run testAFakeZlib once if this test is run repeatedly -# which happens when we look for ref leaks -test_imported = False - - def make_pyc(co, mtime): data = marshal.dumps(co) if type(mtime) is type(0.0): @@ -463,19 +458,7 @@ class BadFileZipImportTestCase(unittest.TestCase): zipimport._zip_directory_cache.clear() -def cleanup(): - # this is necessary if test is run repeated (like when finding leaks) - global test_imported - if test_imported: - zipimport._zip_directory_cache.clear() - if hasattr(UncompressedZipImportTestCase, 'testAFakeZlib'): - delattr(UncompressedZipImportTestCase, 'testAFakeZlib') - if hasattr(CompressedZipImportTestCase, 'testAFakeZlib'): - delattr(CompressedZipImportTestCase, 'testAFakeZlib') - test_imported = True - def test_main(): - cleanup() try: test_support.run_unittest( UncompressedZipImportTestCase, diff --git a/Misc/NEWS b/Misc/NEWS index 93af718400..296d2c1646 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -80,13 +80,16 @@ Core and Builtins Library ------- +- Issue #12124: zipimport doesn't keep a reference to zlib.decompress() anymore + to be able to unload the module. + - Issue #11088: don't crash when using F5 to run a script in IDLE on MacOSX with Tk 8.5. - Issue #10154, #10090: change the normalization of UTF-8 to "UTF-8" instead of "UTF8" in the locale module as the latter is not supported MacOSX and OpenBSD. -- Issue #9516: avoid errors in sysconfig when MACOSX_DEPLOYMENT_TARGET is +- Issue #9516: avoid errors in sysconfig when MACOSX_DEPLOYMENT_TARGET is set in shell. - Issue #12050: zlib.decompressobj().decompress() now clears the unconsumed_tail diff --git a/Modules/zipimport.c b/Modules/zipimport.c index 9224a6880c..b7a1b8da9f 100644 --- a/Modules/zipimport.c +++ b/Modules/zipimport.c @@ -798,35 +798,33 @@ error: /* Return the zlib.decompress function object, or NULL if zlib couldn't be imported. The function is cached when found, so subsequent calls - don't import zlib again. Returns a *borrowed* reference. - XXX This makes zlib.decompress immortal. */ + don't import zlib again. */ static PyObject * get_decompress_func(void) { - static PyObject *decompress = NULL; + static int importing_zlib = 0; + PyObject *zlib; + PyObject *decompress; - if (decompress == NULL) { - PyObject *zlib; - static int importing_zlib = 0; - - if (importing_zlib != 0) - /* Someone has a zlib.py[co] in their Zip file; - let's avoid a stack overflow. */ - return NULL; - importing_zlib = 1; - zlib = PyImport_ImportModuleNoBlock("zlib"); - importing_zlib = 0; - if (zlib != NULL) { - decompress = PyObject_GetAttrString(zlib, - "decompress"); - Py_DECREF(zlib); - } - else - PyErr_Clear(); - if (Py_VerboseFlag) - PySys_WriteStderr("# zipimport: zlib %s\n", - zlib != NULL ? "available": "UNAVAILABLE"); + if (importing_zlib != 0) + /* Someone has a zlib.py[co] in their Zip file; + let's avoid a stack overflow. */ + return NULL; + importing_zlib = 1; + zlib = PyImport_ImportModuleNoBlock("zlib"); + importing_zlib = 0; + if (zlib != NULL) { + decompress = PyObject_GetAttrString(zlib, + "decompress"); + Py_DECREF(zlib); + } + else { + PyErr_Clear(); + decompress = NULL; } + if (Py_VerboseFlag) + PySys_WriteStderr("# zipimport: zlib %s\n", + zlib != NULL ? "available": "UNAVAILABLE"); return decompress; } @@ -911,6 +909,7 @@ get_data(char *archive, PyObject *toc_entry) goto error; } data = PyObject_CallFunction(decompress, "Oi", raw_data, -15); + Py_DECREF(decompress); error: Py_DECREF(raw_data); return data; -- 2.40.0