PEP 499: add some examples and other updates (#939)
* add some examples * specify that packages are not affected by this change * specify that use of module.__name__ should be replaced by module.__spec__.name where the canonical monudle name is required * other small changes [Unlike the original PR, this does *not* change Cameron's email. A separate PR is needed.]
This commit is contained in:
parent
e6fb1bcc32
commit
ccdbb66ee4
77
pep-0499.txt
77
pep-0499.txt
|
@ -2,12 +2,12 @@ PEP: 499
|
|||
Title: ``python -m foo`` should bind ``sys.modules['foo']`` in addition to ``sys.modules['__main__']``
|
||||
Version: $Revision$
|
||||
Last-Modified: $Date$
|
||||
Author: Cameron Simpson <cs@zip.com.au>
|
||||
Author: Cameron Simpson <cs@zip.com.au>, Chris Angelico <rosuav@gmail.com>, Joseph Jevnik <joejev@gmail.com>
|
||||
Status: Draft
|
||||
Type: Standards Track
|
||||
Content-Type: text/x-rst
|
||||
Created: 07-Aug-2015
|
||||
Python-Version: 3.6
|
||||
Python-Version: 3.8
|
||||
|
||||
Abstract
|
||||
========
|
||||
|
@ -38,8 +38,46 @@ then it will obtain the same module instance.
|
|||
|
||||
That actuality is that the module was imported only as ``'__main__'``.
|
||||
Another import will obtain a distinct module instance, which can
|
||||
lead to confusing bugs.
|
||||
lead to confusing bugs,
|
||||
all stemming from having two instances of module global objects:
|
||||
one in each module.
|
||||
|
||||
Examples include:
|
||||
|
||||
module level data structures
|
||||
Some modules provide features such as caches or registries
|
||||
as module level global variables,
|
||||
typically private.
|
||||
A second instance of a module creates a second data structure.
|
||||
If that structure is a cache
|
||||
such as in the ``re`` module
|
||||
then two caches exist leading to wasteful memory use.
|
||||
If that structure is a shared registry
|
||||
such as a mapping of values to handlers
|
||||
then it is possible to register a handler to one registry
|
||||
and to try to use it via the other registry, where it is unknown.
|
||||
|
||||
sentinels
|
||||
The standard test for a sentinel value provided by a module
|
||||
is the identity comparison using ``is``,
|
||||
as this avoids unreliable "looks like" comparisons
|
||||
such as equality which can both mismatch two values as "equal"
|
||||
(for example being zeroish)
|
||||
or raise a ``TypeError`` when the objects are incompatible.
|
||||
When there are two instances of a module
|
||||
there are two sentinel instances
|
||||
and only one will be recognised via ``is``.
|
||||
|
||||
classes
|
||||
With two modules
|
||||
there are duplicate class definitions of any classes provided.
|
||||
All operations which depend on recognising these classes
|
||||
and subclasses of these are prone to failure
|
||||
depending where the reference class
|
||||
(from one of the modules) is obtained
|
||||
and where the comparison class or instance is obtained.
|
||||
This impacts ``isinstance``, ``issubclass``
|
||||
and also ``try``/``except`` constructs.
|
||||
|
||||
Proposal
|
||||
========
|
||||
|
@ -60,6 +98,13 @@ to instead be::
|
|||
sys.modules[mod_spec.name] = main_module
|
||||
main_globals = main_module.__dict__
|
||||
|
||||
Joseph Jevnik has pointed out that modules which are packages already
|
||||
do something very similar to this proposal:
|
||||
the __init__.py file is bound to the module's canonical name
|
||||
and the __main__.py file is bound to "__main__".
|
||||
As such, the double import issue does not occur.
|
||||
Therefore this PEP proposes to affect only simple non-package modules.
|
||||
|
||||
|
||||
Considerations and Prerequisites
|
||||
================================
|
||||
|
@ -81,6 +126,32 @@ Nick has mentioned `issue 19702`_ which proposes (quoted from the issue):
|
|||
The first point above covers this PEP's specific proposal.
|
||||
|
||||
|
||||
A Normal Module's ``__name__`` Is No Longer Canonical
|
||||
-----------------------------------------------------
|
||||
|
||||
Chris Angelico points out that it becomes possible to import a
|
||||
module whose ``__name__`` is not what you gave to "import", since
|
||||
"__main__" is now present at "module.name", so a subsequent
|
||||
``import module.name`` finds it already present.
|
||||
Therefore ``__name__`` is no longer the canonical name for some normal imports.
|
||||
|
||||
Some counter arguments follow:
|
||||
|
||||
- As of PEP 451 a module's canonical name is stored at ``__spec__.name``.
|
||||
- Very little code should actually care about ``__name__`` being the canonical name
|
||||
and any that does should arguably be updated to consult ``__spec__.name``
|
||||
with fallback to ``__name__`` for older Pythons, should that be relevant.
|
||||
This is true even if this PEP is not approved.
|
||||
- Should this PEP be approved,
|
||||
it becomes possible to introspect a module by its canonical name
|
||||
and ask "was this the main program?" by inferring from ``__name__``.
|
||||
This was not previously possible.
|
||||
|
||||
The glaring counter example is the standard "am I the main program?" boilerplate,
|
||||
where ``__name__`` is expected to be "__main__".
|
||||
This PEP explicitly preserves that semantic.
|
||||
|
||||
|
||||
Background
|
||||
==========
|
||||
|
||||
|
|
Loading…
Reference in New Issue