[Python-Dev] PEP 451 update

Nick Coghlan ncoghlan at gmail.com
Sat Oct 26 19:27:57 CEST 2013


On 26 October 2013 08:51, PJ Eby <pje at telecommunity.com> wrote:
> Mostly, this just seems like an ugly wart -- Python should be dynamic
> by default, and that includes reloading.  While the import machinery
> has lots of ugly caching under the hood, a user-level function like
> reload() should not require you to do the equivalent of saying, "no,
> really...  I want you to *really* reload, not just pull in whatever
> exists where you found it last time, while ignoring whether I switched
> from module to package or vice versa, or just fixed my sys.path so I
> can load the right version of the module."
>
> It is a really tiny thing in the overall scheme of things, because
> reload() is not used all that often, but it's still a thing.  If this
> isn't treated as a bug, then the docs for reload() at least need to
> include a forward-supported workaround so you can say "no, really...
> *really* reload" in an approved fashion.
>
> (ISTM that any production code out there that currently uses reload()
> would want to perform the "really reload" incantation in order to
> avoid the edge cases, even if they haven't actually run into any of
> them yet.)

Having imp.reload() kick off the full reload cycle makes sense to me.
The only reason it doesn't currently do that in importlib is because
there was no test for it in the regression test suite, and PEP 302 and
the library reference are entirely vague on how module reloading works
(aside from the requirement that it reuse the same module namespace).

>> And in a PEP 451 world it should be dead-simple to make this work the way
>> you want in your own code even if this doesn't go the way you want::
>>
>>   spec = importlib.find_spec(name)
>>   module.__spec__ = spec
>>   importlib.reload(module)  # Which in itself is essentially
>> init_module_attrs(spec, module); spec.loader.exec_module(module)
>>
>> Heck, you can do this in Python 3.3 right now::
>>
>>   loader = importlib.find_loader(name)
>>   module = sys.modules[name]
>>   module.__loader__ = loader
>>   importlib.reload(module)
>
> And will that later version still work correctly in a PEP 451 world,
> or will you have to detect which world you live in before waving this
> particular dead chicken?  ;-)

Yep, we already tweaked PEP 451 to say that it has to respect
post-import modifications made to the module attributes.

>> Ah, okay. That is not explicit in the PEP beyond coming off a total nuisance
>> in order to support reloading by the loader, not an explicit finder + loader
>> use-case.
>
> Yeah, it actually was to ensure that you could reload a module using a
> different loader than the one that originally loaded it, e.g. due to a
> change in path hooks, etc.

Yeah, the rationale makes sense, we only missed it due to the lack of
a regression test for the behaviour.

Cheers,
Nick.

-- 
Nick Coghlan   |   ncoghlan at gmail.com   |   Brisbane, Australia


More information about the Python-Dev mailing list