Issue #17358: imp.load_source() and load_compiled() should now return

modules which will typically work when reloaded.

A hack is used to support these functions as their API allowed them to
pass in a file object but then operate as if import had loaded them.
Unfortunately the hack kept a reference around for the file object
passed in which would be unusable on reload since it had been closed.
The solution is to simply use the hack for the initial load but then a
proper loader on the module so that imp.reload() at least has a chance
to work.
This commit is contained in:
Brett Cannon 2013-04-28 11:53:26 -04:00
parent 9330a94467
commit 5a4c233a9e
2 changed files with 15 additions and 2 deletions

View File

@ -111,7 +111,12 @@ def load_source(name, pathname, file=None):
'importlib.machinery.SourceFileLoader(name, pathname).load_module()' 'importlib.machinery.SourceFileLoader(name, pathname).load_module()'
' instead') ' instead')
warnings.warn(msg, DeprecationWarning, 2) warnings.warn(msg, DeprecationWarning, 2)
return _LoadSourceCompatibility(name, pathname, file).load_module(name) _LoadSourceCompatibility(name, pathname, file).load_module(name)
module = sys.modules[name]
# To allow reloading to potentially work, use a non-hacked loader which
# won't rely on a now-closed file object.
module.__loader__ = _bootstrap.SourceFileLoader(name, pathname)
return module
class _LoadCompiledCompatibility(_HackedGetData, class _LoadCompiledCompatibility(_HackedGetData,
@ -125,7 +130,12 @@ def load_compiled(name, pathname, file=None):
'importlib.machinery.SourcelessFileLoader(name, pathname).' 'importlib.machinery.SourcelessFileLoader(name, pathname).'
'load_module() instead ') 'load_module() instead ')
warnings.warn(msg, DeprecationWarning, 2) warnings.warn(msg, DeprecationWarning, 2)
return _LoadCompiledCompatibility(name, pathname, file).load_module(name) _LoadCompiledCompatibility(name, pathname, file).load_module(name)
module = sys.modules[name]
# To allow reloading to potentially work, use a non-hacked loader which
# won't rely on a now-closed file object.
module.__loader__ = _bootstrap.SourcelessFileLoader(name, pathname)
return module
def load_package(name, path): def load_package(name, path):

View File

@ -39,6 +39,9 @@ Core and Builtins
Library Library
------- -------
- Issue #17358: Modules loaded by imp.load_source() and load_compiled() (and by
extention load_module()) now have a better chance of working when reloaded.
- Issue #17353: Plistlib emitted empty data tags with deeply nested datastructures - Issue #17353: Plistlib emitted empty data tags with deeply nested datastructures
- Issue #11714: Use 'with' statements to assure a Semaphore releases a - Issue #11714: Use 'with' statements to assure a Semaphore releases a