(Merge 3.2) Issue #12124: zipimport doesn't keep a reference to

zlib.decompress() anymore to be able to unload the module.
This commit is contained in:
Victor Stinner 2011-05-20 00:22:39 +02:00
commit 21809a6938
3 changed files with 26 additions and 41 deletions

View file

@ -19,11 +19,6 @@ import io
from traceback import extract_tb, extract_stack, print_tb from traceback import extract_tb, extract_stack, print_tb
raise_src = 'def do_raise(): raise TypeError\n' 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): def make_pyc(co, mtime):
data = marshal.dumps(co) data = marshal.dumps(co)
if type(mtime) is type(0.0): if type(mtime) is type(0.0):
@ -467,19 +462,7 @@ class BadFileZipImportTestCase(unittest.TestCase):
zipimport._zip_directory_cache.clear() 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(): def test_main():
cleanup()
try: try:
support.run_unittest( support.run_unittest(
UncompressedZipImportTestCase, UncompressedZipImportTestCase,

View file

@ -153,6 +153,9 @@ Core and Builtins
Library Library
------- -------
- Issue #12124: zipimport doesn't keep a reference to zlib.decompress() anymore
to be able to unload the module.
- Issue #12120, #12119: skip a test in packaging and distutils - Issue #12120, #12119: skip a test in packaging and distutils
if sys.dont_write_bytecode is set to True. if sys.dont_write_bytecode is set to True.

View file

@ -867,35 +867,33 @@ error:
/* Return the zlib.decompress function object, or NULL if zlib couldn't /* Return the zlib.decompress function object, or NULL if zlib couldn't
be imported. The function is cached when found, so subsequent calls be imported. The function is cached when found, so subsequent calls
don't import zlib again. Returns a *borrowed* reference. don't import zlib again. */
XXX This makes zlib.decompress immortal. */
static PyObject * static PyObject *
get_decompress_func(void) get_decompress_func(void)
{ {
static PyObject *decompress = NULL; static int importing_zlib = 0;
PyObject *zlib;
PyObject *decompress;
if (decompress == NULL) { if (importing_zlib != 0)
PyObject *zlib; /* Someone has a zlib.py[co] in their Zip file;
static int importing_zlib = 0; let's avoid a stack overflow. */
return NULL;
if (importing_zlib != 0) importing_zlib = 1;
/* Someone has a zlib.py[co] in their Zip file; zlib = PyImport_ImportModuleNoBlock("zlib");
let's avoid a stack overflow. */ importing_zlib = 0;
return NULL; if (zlib != NULL) {
importing_zlib = 1; decompress = PyObject_GetAttrString(zlib,
zlib = PyImport_ImportModuleNoBlock("zlib"); "decompress");
importing_zlib = 0; Py_DECREF(zlib);
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");
} }
else {
PyErr_Clear();
decompress = NULL;
}
if (Py_VerboseFlag)
PySys_WriteStderr("# zipimport: zlib %s\n",
zlib != NULL ? "available": "UNAVAILABLE");
return decompress; return decompress;
} }
@ -986,6 +984,7 @@ get_data(PyObject *archive, PyObject *toc_entry)
goto error; goto error;
} }
data = PyObject_CallFunction(decompress, "Oi", raw_data, -15); data = PyObject_CallFunction(decompress, "Oi", raw_data, -15);
Py_DECREF(decompress);
error: error:
Py_DECREF(raw_data); Py_DECREF(raw_data);
return data; return data;