summaryrefslogtreecommitdiffstats
path: root/Doc
diff options
context:
space:
mode:
Diffstat (limited to 'Doc')
-rw-r--r--Doc/reference/datamodel.rst45
-rw-r--r--Doc/whatsnew/3.7.rst18
2 files changed, 63 insertions, 0 deletions
diff --git a/Doc/reference/datamodel.rst b/Doc/reference/datamodel.rst
index 153b58b..790339c 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 d6d0861..3574b53 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
----------------------------------------------------------