diff options
author | Ivan Levkivskyi <levkivskyi@gmail.com> | 2017-12-14 11:59:44 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-12-14 11:59:44 +0100 |
commit | 5364b5cd7571f2dfa75acd37b388c14ac33fef73 (patch) | |
tree | 43b89bf162a571e979946d2d9dcfda82b4e0f4c8 /Doc | |
parent | bpo-32302: Fix distutils bdist_wininst for CRT v142 (#4851) (diff) | |
download | cpython-5364b5cd7571f2dfa75acd37b388c14ac33fef73.tar.gz cpython-5364b5cd7571f2dfa75acd37b388c14ac33fef73.tar.bz2 cpython-5364b5cd7571f2dfa75acd37b388c14ac33fef73.zip |
bpo-32225: Implementation of PEP 562 (#4731)
Implement PEP 562: module __getattr__ and __dir__.
The implementation simply updates module_getattro and
module_dir.
Diffstat (limited to 'Doc')
-rw-r--r-- | Doc/reference/datamodel.rst | 45 | ||||
-rw-r--r-- | Doc/whatsnew/3.7.rst | 18 |
2 files changed, 63 insertions, 0 deletions
diff --git a/Doc/reference/datamodel.rst b/Doc/reference/datamodel.rst index 153b58b4fbf..790339cd47b 100644 --- a/Doc/reference/datamodel.rst +++ b/Doc/reference/datamodel.rst @@ -1512,6 +1512,51 @@ access (use of, assignment to, or deletion of ``x.name``) for class instances. returned. :func:`dir` converts the returned sequence to a list and sorts it. +Customizing module attribute access +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. index:: + single: __getattr__ (module attribute) + single: __dir__ (module attribute) + single: __class__ (module attribute) + +Special names ``__getattr__`` and ``__dir__`` can be also used to customize +access to module attributes. The ``__getattr__`` function at the module level +should accept one argument which is the name of an attribute and return the +computed value or raise an :exc:`AttributeError`. If an attribute is +not found on a module object through the normal lookup, i.e. +:meth:`object.__getattribute__`, then ``__getattr__`` is searched in +the module ``__dict__`` before raising an :exc:`AttributeError`. If found, +it is called with the attribute name and the result is returned. + +The ``__dir__`` function should accept no arguments, and return a list of +strings that represents the names accessible on module. If present, this +function overrides the standard :func:`dir` search on a module. + +For a more fine grained customization of the module behavior (setting +attributes, properties, etc.), one can set the ``__class__`` attribute of +a module object to a subclass of :class:`types.ModuleType`. For example:: + + import sys + from types import ModuleType + + class VerboseModule(ModuleType): + def __repr__(self): + return f'Verbose {self.__name__}' + + def __setattr__(self, attr, value): + print(f'Setting {attr}...') + setattr(self, attr, value) + + sys.modules[__name__].__class__ = VerboseModule + +.. note:: + Defining module ``__getattr__`` and setting module ``__class__`` only + affect lookups made using the attribute access syntax -- directly accessing + the module globals (whether by code within the module, or via a reference + to the module's globals dictionary) is unaffected. + + .. _descriptors: Implementing Descriptors diff --git a/Doc/whatsnew/3.7.rst b/Doc/whatsnew/3.7.rst index d6d0861d5d5..3574b53ad18 100644 --- a/Doc/whatsnew/3.7.rst +++ b/Doc/whatsnew/3.7.rst @@ -159,6 +159,24 @@ effort will be made to add such support. PEP written by Erik M. Bray; implementation by Masayuki Yamamoto. +PEP 562: Customization of access to module attributes +----------------------------------------------------- + +It is sometimes convenient to customize or otherwise have control over access +to module attributes. A typical example is managing deprecation warnings. +Typical workarounds are assigning ``__class__`` of a module object to +a custom subclass of :class:`types.ModuleType` or replacing the ``sys.modules`` +item with a custom wrapper instance. This procedure is now simplified by +recognizing ``__getattr__`` defined directly in a module that would act like +a normal ``__getattr__`` method, except that it will be defined on module +*instances*. + +.. seealso:: + + :pep:`562` -- Module ``__getattr__`` and ``__dir__`` + PEP written and implemented by Ivan Levkivskyi + + PEP 564: Add new time functions with nanosecond resolution ---------------------------------------------------------- |