diff -r 859ef54bdce2 Lib/test/test_imp.py --- a/Lib/test/test_imp.py Wed Nov 07 09:10:49 2012 +0100 +++ b/Lib/test/test_imp.py Wed Nov 07 10:41:34 2012 +0100 @@ -217,6 +217,20 @@ mod = imp.load_module(example, *x) self.assertEqual(mod.__name__, example) + def test_issue16421_multiple_modules_in_one_dll(self): + # Issue 16421: loading several modules from the same compiled file fails + m = '_testimportmultiple' + fileobj, pathname, description = imp.find_module(m) + fileobj.close() + mod0 = imp.load_dynamic(m, pathname) + mod1 = imp.load_dynamic('foo', pathname) + mod2 = imp.load_dynamic('bar', pathname) + self.assertEqual(mod0.__name__, m) + self.assertEqual(mod1.__name__, 'foo') + self.assertEqual(mod2.__name__, 'bar') + with self.assertRaises(ImportError): + imp.load_dynamic('nonexistent', pathname) + def test_load_dynamic_ImportError_path(self): # Issue #1559549 added `name` and `path` attributes to ImportError # in order to provide better detail. Issue #10854 implemented those diff -r 859ef54bdce2 Misc/ACKS --- a/Misc/ACKS Wed Nov 07 09:10:49 2012 +0100 +++ b/Misc/ACKS Wed Nov 07 10:41:34 2012 +0100 @@ -1099,6 +1099,7 @@ J. Sipprell Kragen Sitaker Michael Sloan +Václav Šmilauer Christopher Smith Eric V. Smith Gregory P. Smith diff -r 859ef54bdce2 Misc/NEWS --- a/Misc/NEWS Wed Nov 07 09:10:49 2012 +0100 +++ b/Misc/NEWS Wed Nov 07 10:41:34 2012 +0100 @@ -10,6 +10,10 @@ Core and Builtins ----------------- +- Issue #16421: loading multiple modules from one shared object is now + handled correctly (previously, the first module loaded from that file + was silently returned). Patch by Václav Šmilauer. + - Issue #15001: fix segfault on "del sys.module['__main__']". Patch by Victor Stinner. diff -r 859ef54bdce2 Modules/_testimportmultiple.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Modules/_testimportmultiple.c Wed Nov 07 10:41:34 2012 +0100 @@ -0,0 +1,57 @@ +/* + * C extensions module to test importing multiple modules from one compiled + * file (issue16421). This file defines 3 modules (_testimportmodule, + * foo, bar), only the first one is called the same as the compiled file. + */ +#include + +static struct PyModuleDef _testimportmultiple = { + PyModuleDef_HEAD_INIT, + "_testimportmultiple", + "_testimportmultiple doc", + -1, + NULL, + NULL, + NULL, + NULL, + NULL +}; + +PyMODINIT_FUNC PyInit__testimportmultiple() +{ + return PyModule_Create(&_testimportmultiple); +} + +static struct PyModuleDef _foomodule = { + PyModuleDef_HEAD_INIT, + "foo", + "foo doc", + -1, + NULL, + NULL, + NULL, + NULL, + NULL +}; + +PyMODINIT_FUNC PyInit_foo() +{ + return PyModule_Create(&_foomodule); +} + +static struct PyModuleDef _barmodule = { + PyModuleDef_HEAD_INIT, + "bar", + "bar doc", + -1, + NULL, + NULL, + NULL, + NULL, + NULL +}; + +PyMODINIT_FUNC PyInit_bar(){ + return PyModule_Create(&_barmodule); +} + diff -r 859ef54bdce2 PC/VS9.0/_testimportmultiple.vcproj --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/PC/VS9.0/_testimportmultiple.vcproj Wed Nov 07 10:41:34 2012 +0100 @@ -0,0 +1,521 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff -r 859ef54bdce2 PC/VS9.0/pcbuild.sln --- a/PC/VS9.0/pcbuild.sln Wed Nov 07 09:10:49 2012 +0100 +++ b/PC/VS9.0/pcbuild.sln Wed Nov 07 10:41:34 2012 +0100 @@ -87,6 +87,11 @@ {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26} = {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26} EndProjectSection EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_testimportmultiple", "_testimportmultiple.vcproj", "{36D0C52C-DF4E-45D0-8BC7-E294C3ABC781}" + ProjectSection(ProjectDependencies) = postProject + {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26} = {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26} + EndProjectSection +EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_tkinter", "_tkinter.vcproj", "{4946ECAC-2E69-4BF8-A90A-F5136F5094DF}" ProjectSection(ProjectDependencies) = postProject {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26} = {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26} @@ -422,6 +427,22 @@ {6901D91C-6E48-4BB7-9FEC-700C8131DF1D}.Release|Win32.Build.0 = Release|Win32 {6901D91C-6E48-4BB7-9FEC-700C8131DF1D}.Release|x64.ActiveCfg = Release|x64 {6901D91C-6E48-4BB7-9FEC-700C8131DF1D}.Release|x64.Build.0 = Release|x64 + {36D0C52C-DF4E-45D0-8BC7-E294C3ABC781}.Debug|Win32.ActiveCfg = Debug|Win32 + {36D0C52C-DF4E-45D0-8BC7-E294C3ABC781}.Debug|Win32.Build.0 = Debug|Win32 + {36D0C52C-DF4E-45D0-8BC7-E294C3ABC781}.Debug|x64.ActiveCfg = Debug|x64 + {36D0C52C-DF4E-45D0-8BC7-E294C3ABC781}.Debug|x64.Build.0 = Debug|x64 + {36D0C52C-DF4E-45D0-8BC7-E294C3ABC781}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32 + {36D0C52C-DF4E-45D0-8BC7-E294C3ABC781}.PGInstrument|Win32.Build.0 = PGInstrument|Win32 + {36D0C52C-DF4E-45D0-8BC7-E294C3ABC781}.PGInstrument|x64.ActiveCfg = PGInstrument|x64 + {36D0C52C-DF4E-45D0-8BC7-E294C3ABC781}.PGInstrument|x64.Build.0 = PGInstrument|x64 + {36D0C52C-DF4E-45D0-8BC7-E294C3ABC781}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32 + {36D0C52C-DF4E-45D0-8BC7-E294C3ABC781}.PGUpdate|Win32.Build.0 = PGUpdate|Win32 + {36D0C52C-DF4E-45D0-8BC7-E294C3ABC781}.PGUpdate|x64.ActiveCfg = PGUpdate|x64 + {36D0C52C-DF4E-45D0-8BC7-E294C3ABC781}.PGUpdate|x64.Build.0 = PGUpdate|x64 + {36D0C52C-DF4E-45D0-8BC7-E294C3ABC781}.Release|Win32.ActiveCfg = Release|Win32 + {36D0C52C-DF4E-45D0-8BC7-E294C3ABC781}.Release|Win32.Build.0 = Release|Win32 + {36D0C52C-DF4E-45D0-8BC7-E294C3ABC781}.Release|x64.ActiveCfg = Release|x64 + {36D0C52C-DF4E-45D0-8BC7-E294C3ABC781}.Release|x64.Build.0 = Release|x64 {4946ECAC-2E69-4BF8-A90A-F5136F5094DF}.Debug|Win32.ActiveCfg = Debug|Win32 {4946ECAC-2E69-4BF8-A90A-F5136F5094DF}.Debug|Win32.Build.0 = Debug|Win32 {4946ECAC-2E69-4BF8-A90A-F5136F5094DF}.Debug|x64.ActiveCfg = Debug|x64 diff -r 859ef54bdce2 PCbuild/_testimportmultiple.vcxproj --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/PCbuild/_testimportmultiple.vcxproj Wed Nov 07 10:41:34 2012 +0100 @@ -0,0 +1,218 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + PGInstrument + Win32 + + + PGInstrument + x64 + + + PGUpdate + Win32 + + + PGUpdate + x64 + + + Release + Win32 + + + Release + x64 + + + + {36D0C52C-DF4E-45D0-8BC7-E294C3ABC781} + _testimportmultiple + Win32Proj + + + + DynamicLibrary + NotSet + true + + + DynamicLibrary + NotSet + true + + + DynamicLibrary + NotSet + true + + + DynamicLibrary + NotSet + + + DynamicLibrary + NotSet + true + + + DynamicLibrary + NotSet + true + + + DynamicLibrary + NotSet + true + + + DynamicLibrary + NotSet + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.30319.1 + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + + + + 0x1e1F0000 + + + + + X64 + + + 0x1e1F0000 + + + + + 0x1e1F0000 + + + + + X64 + + + 0x1e1F0000 + + + + + 0x1e1F0000 + + + + + X64 + + + 0x1e1F0000 + MachineX64 + + + + + 0x1e1F0000 + + + + + X64 + + + 0x1e1F0000 + MachineX64 + + + + + + + + {cf7ac3d1-e2df-41d2-bea6-1e2556cdea26} + false + + + + + + diff -r 859ef54bdce2 PCbuild/_testimportmultiple.vcxproj.filters --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/PCbuild/_testimportmultiple.vcxproj.filters Wed Nov 07 10:41:34 2012 +0100 @@ -0,0 +1,13 @@ + + + + + {1ec38ad9-1abf-4b80-8628-ac43ccba324b} + + + + + Source Files + + + diff -r 859ef54bdce2 PCbuild/pcbuild.sln --- a/PCbuild/pcbuild.sln Wed Nov 07 09:10:49 2012 +0100 +++ b/PCbuild/pcbuild.sln Wed Nov 07 10:41:34 2012 +0100 @@ -38,6 +38,8 @@ EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_testcapi", "_testcapi.vcxproj", "{6901D91C-6E48-4BB7-9FEC-700C8131DF1D}" EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_testimportmultiple", "_testimportmultiple.vcxproj", "{36D0C52C-DF4E-45D0-8BC7-E294C3ABC781}" +EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_tkinter", "_tkinter.vcxproj", "{4946ECAC-2E69-4BF8-A90A-F5136F5094DF}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_bz2", "_bz2.vcxproj", "{73FCD2BD-F133-46B7-8EC1-144CD82A59D5}" @@ -344,6 +346,22 @@ {6901D91C-6E48-4BB7-9FEC-700C8131DF1D}.Release|Win32.Build.0 = Release|Win32 {6901D91C-6E48-4BB7-9FEC-700C8131DF1D}.Release|x64.ActiveCfg = Release|x64 {6901D91C-6E48-4BB7-9FEC-700C8131DF1D}.Release|x64.Build.0 = Release|x64 + {36D0C52C-DF4E-45D0-8BC7-E294C3ABC781}.Debug|Win32.ActiveCfg = Debug|Win32 + {36D0C52C-DF4E-45D0-8BC7-E294C3ABC781}.Debug|Win32.Build.0 = Debug|Win32 + {36D0C52C-DF4E-45D0-8BC7-E294C3ABC781}.Debug|x64.ActiveCfg = Debug|x64 + {36D0C52C-DF4E-45D0-8BC7-E294C3ABC781}.Debug|x64.Build.0 = Debug|x64 + {36D0C52C-DF4E-45D0-8BC7-E294C3ABC781}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32 + {36D0C52C-DF4E-45D0-8BC7-E294C3ABC781}.PGInstrument|Win32.Build.0 = PGInstrument|Win32 + {36D0C52C-DF4E-45D0-8BC7-E294C3ABC781}.PGInstrument|x64.ActiveCfg = PGInstrument|x64 + {36D0C52C-DF4E-45D0-8BC7-E294C3ABC781}.PGInstrument|x64.Build.0 = PGInstrument|x64 + {36D0C52C-DF4E-45D0-8BC7-E294C3ABC781}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32 + {36D0C52C-DF4E-45D0-8BC7-E294C3ABC781}.PGUpdate|Win32.Build.0 = PGUpdate|Win32 + {36D0C52C-DF4E-45D0-8BC7-E294C3ABC781}.PGUpdate|x64.ActiveCfg = PGUpdate|x64 + {36D0C52C-DF4E-45D0-8BC7-E294C3ABC781}.PGUpdate|x64.Build.0 = PGUpdate|x64 + {36D0C52C-DF4E-45D0-8BC7-E294C3ABC781}.Release|Win32.ActiveCfg = Release|Win32 + {36D0C52C-DF4E-45D0-8BC7-E294C3ABC781}.Release|Win32.Build.0 = Release|Win32 + {36D0C52C-DF4E-45D0-8BC7-E294C3ABC781}.Release|x64.ActiveCfg = Release|x64 + {36D0C52C-DF4E-45D0-8BC7-E294C3ABC781}.Release|x64.Build.0 = Release|x64 {4946ECAC-2E69-4BF8-A90A-F5136F5094DF}.Debug|Win32.ActiveCfg = Debug|Win32 {4946ECAC-2E69-4BF8-A90A-F5136F5094DF}.Debug|Win32.Build.0 = Debug|Win32 {4946ECAC-2E69-4BF8-A90A-F5136F5094DF}.Debug|x64.ActiveCfg = Debug|x64 diff -r 859ef54bdce2 Python/import.c --- a/Python/import.c Wed Nov 07 09:10:49 2012 +0100 +++ b/Python/import.c Wed Nov 07 10:41:34 2012 +0100 @@ -449,12 +449,12 @@ /* Magic for extension modules (built-in as well as dynamically loaded). To prevent initializing an extension module more than - once, we keep a static dictionary 'extensions' keyed by module name - (for built-in modules) or by filename (for dynamically loaded - modules), containing these modules. A copy of the module's - dictionary is stored by calling _PyImport_FixupExtensionObject() - immediately after the module initialization function succeeds. A - copy can be retrieved from there by calling + once, we keep a static dictionary 'extensions' keyed by the tuple + (module name, module name) (for built-in modules) or by + (filename, module name) (for dynamically loaded modules), containing these + modules. A copy of the module's dictionary is stored by calling + _PyImport_FixupExtensionObject() immediately after the module initialization + function succeeds. A copy can be retrieved from there by calling _PyImport_FindExtensionObject(). Modules which do support multiple initialization set their m_size @@ -467,7 +467,7 @@ _PyImport_FixupExtensionObject(PyObject *mod, PyObject *name, PyObject *filename) { - PyObject *modules, *dict; + PyObject *modules, *dict, *filename_name; struct PyModuleDef *def; if (extensions == NULL) { extensions = PyDict_New(); @@ -505,7 +505,11 @@ if (def->m_base.m_copy == NULL) return -1; } - PyDict_SetItem(extensions, filename, (PyObject*)def); + filename_name = PyTuple_Pack(2,filename, name); + if (filename_name == NULL) + return -1; + if (PyDict_SetItem(extensions, filename_name, (PyObject*)def) < 0) + return -1; return 0; } @@ -525,11 +529,14 @@ PyObject * _PyImport_FindExtensionObject(PyObject *name, PyObject *filename) { - PyObject *mod, *mdict; + PyObject *mod, *mdict, *filename_name; PyModuleDef* def; if (extensions == NULL) return NULL; - def = (PyModuleDef*)PyDict_GetItem(extensions, filename); + filename_name = PyTuple_Pack(2,filename, name); + if (filename_name == NULL) + return NULL; + def = (PyModuleDef*)PyDict_GetItem(extensions, filename_name); if (def == NULL) return NULL; if (def->m_size == -1) { diff -r 859ef54bdce2 Tools/msi/msi.py --- a/Tools/msi/msi.py Wed Nov 07 09:10:49 2012 +0100 +++ b/Tools/msi/msi.py Wed Nov 07 10:41:34 2012 +0100 @@ -101,6 +101,7 @@ '_decimal.pyd', '_testbuffer.pyd', '_sha3.pyd', + '_testimportmultiple.pyd', ] # Well-known component UUIDs diff -r 859ef54bdce2 setup.py --- a/setup.py Wed Nov 07 09:10:49 2012 +0100 +++ b/setup.py Wed Nov 07 10:41:34 2012 +0100 @@ -591,6 +591,8 @@ depends=['testcapi_long.h']) ) # Python PEP-3118 (buffer protocol) test module exts.append( Extension('_testbuffer', ['_testbuffer.c']) ) + # Test loading multiple modules from one compiled file (http://bugs.python.org/issue16421) + exts.append( Extension('_testimportmultiple', ['_testimportmultiple.c']) ) # profiler (_lsprof is for cProfile.py) exts.append( Extension('_lsprof', ['_lsprof.c', 'rotatingtree.c']) ) # static Unicode character database