5.4.3.
Module spec
The import machinery uses a variety of information about each module during import, especially
before loading. Most of the information is common to all modules. The purpose of a module’s spec
is to encapsulate this import-related information on a per-module basis.
Using a spec during import allows state to be transferred between import system components, e.g.
between the finder that creates the module spec and the loader that executes it. Most importantly,
it allows the import machinery to perform the boilerplate operations of loading, whereas without a
module spec the loader had that responsibility.
The module’s spec is exposed as the __spec__ attribute on a module object. See ModuleSpec for
details on the contents of the module spec.
New in version 3.4.
5.4.4. Import-related module attributes
The import machinery fills in these attributes on each module object during loading, based on the
module’s spec, before the loader executes the module.
__name__
The __name__ attribute must be set to the fully-qualified name of the module. This name
is used to uniquely identify the module in the import system.
__loader__
The __loader__ attribute must be set to the loader object that the import machinery used
when loading the module. This is mostly for introspection, but can be used for additional
loader-specific functionality, for example getting data associated with a loader.
__package__
The module’s __package__ attribute must be set. Its value must be a string, but it can be
the same value as its __name__. When the module is a package, its __package__ value
should be set to its __name__. When the module is not a package, __package__ should be
set to the empty string for top-level modules, or for submodules, to the parent package’s
name. See PEP 366 for further details.
This attribute is used instead of __name__ to calculate explicit relative imports for main
modules, as defined in PEP 366. It is expected to have the same value
as __spec__.parent.
Changed in version 3.6: The value of __package__ is expected to be the same
as __spec__.parent.
__spec__
The __spec__ attribute must be set to the module spec that was used when importing the
module. Setting __spec__ appropriately applies equally to modules initialized during
interpreter startup. The one exception is __main__, where __spec__ is set to None in some
cases.
When __package__ is not defined, __spec__.parent is used as a fallback.
New in version 3.4.
Changed in version 3.6: __spec__.parent is used as a fallback when __package__ is not
defined.
__path__
If the module is a package (either regular or namespace), the module
object’s __path__ attribute must be set. The value must be iterable, but may be empty
if __path__ has no further significance. If __path__ is not empty, it must produce strings
when iterated over. More details on the semantics of __path__ are given below.
Non-package modules should not have a __path__ attribute.
__file__
__cached__
__file__ is optional. If set, this attribute’s value must be a string. The import system may
opt to leave __file__ unset if it has no semantic meaning (e.g. a module loaded from a
database).
If __file__ is set, it may also be appropriate to set the __cached__ attribute which is the
path to any compiled version of the code (e.g. byte-compiled file). The file does not need
to exist to set this attribute; the path can simply point to where the compiled file would
exist (see PEP 3147).
It is also appropriate to set __cached__ when __file__ is not set. However, that scenario
is quite atypical. Ultimately, the loader is what makes use of __file__ and/or __cached__.
So if a loader can load from a cached module but otherwise does not load from a file, that
atypical scenario may be appropriate.
5.4.5. module.__path__
By definition, if a module has a __path__ attribute, it is a package.
A package’s __path__ attribute is used during imports of its subpackages. Within the import
machinery, it functions much the same as sys.path, i.e. providing a list of locations to search for
modules during import. However, __path__ is typically much more constrained than sys.path.
__path__ must be an iterable of strings, but it may be empty. The same rules used
for sys.path also apply to a package’s __path__, and sys.path_hooks (described below) are
consulted when traversing a package’s __path__.
A package’s __init__.py file may set or alter the package’s __path__ attribute, and this was
typically the way namespace packages were implemented prior to PEP 420. With the adoption
of PEP 420, namespace packages no longer need to supply __init__.py files containing
only __path__ manipulation code; the import machinery automatically sets __path__ correctly for
the namespace package.
5.4.6. Module reprs
By default, all modules have a usable repr, however depending on the attributes set above, and in
the module’s spec, you can more explicitly control the repr of module objects.
If the module has a spec ( __spec__), the import machinery will try to generate a repr from it. If that
fails or there is no spec, the import system will craft a default repr using whatever information is
available on the module. It will try to use the module.__name__, module.__file__,
and module.__loader__ as input into the repr, with defaults for whatever information is missing.
Here are the exact rules used:
• If the module has a __spec__ attribute, the information in the spec is used to
generate the repr. The “name”, “loader”, “origin”, and “has_location” attributes
are consulted.
• If the module has a __file__ attribute, this is used as part of the module’s repr.
• If the module has no __file__ but does have a __loader__ that is not None, then
the loader’s repr is used as part of the module’s repr.
• Otherwise, just use the module’s __name__ in the repr.
Changed in version 3.4: Use of loader.module_repr() has been deprecated and the module spec is
now used by the import machinery to generate a module repr.
For backward compatibility with Python 3.3, the module repr will be generated by calling the
loader’s module_repr() method, if defined, before trying either approach described above.
However, the method is deprecated.
5.4.7. Cached bytecode invalidation