The main two use cases I know of for this and PEP 549 are lazy imports of submodules, and deprecating attributes. If we assume that you only want lazy imports to show up in dir() and don't want deprecated attributes to show up in dir() (and I'm not sure this is what you want 100% of the time, but it seems like the most reasonable default to me), then currently you need one of the PEPs for one of the cases and the other PEP for the other case.
Would it make more sense to add direct support for lazy imports and attribute deprecation to ModuleType? This might look something like metamodule's FancyModule type: https://github.com/njsmith/metamodule/blob/ ee54d49100a9a06ffff341bb10a4d3549642139f/metamodule.py#L20 -n On Sep 10, 2017 11:49, "Ivan Levkivskyi" <levkivs...@gmail.com> wrote: > I have written a short PEP as a complement/alternative to PEP 549. > I will be grateful for comments and suggestions. The PEP should > appear online soon. > > -- > Ivan > > *********************************************************** > > PEP: 562 > Title: Module __getattr__ > Author: Ivan Levkivskyi <levkivs...@gmail.com> > Status: Draft > Type: Standards Track > Content-Type: text/x-rst > Created: 09-Sep-2017 > Python-Version: 3.7 > Post-History: 09-Sep-2017 > > > Abstract > ======== > > It is proposed to support ``__getattr__`` function defined on modules to > provide basic customization of module attribute access. > > > Rationale > ========= > > 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 ``types.ModuleType`` or substituting > ``sys.modules`` > item with a custom wrapper instance. It would be convenient to simplify > this > procedure 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*. For example:: > > # lib.py > > from warnings import warn > > deprecated_names = ["old_function", ...] > > def _deprecated_old_function(arg, other): > ... > > def __getattr__(name): > if name in deprecated_names: > warn(f"{name} is deprecated", DeprecationWarning) > return globals()[f"_deprecated_{name}"] > raise AttributeError(f"module {__name__} has no attribute {name}") > > # main.py > > from lib import old_function # Works, but emits the warning > > There is a related proposal PEP 549 that proposes to support instance > properties for a similar functionality. The difference is this PEP proposes > a faster and simpler mechanism, but provides more basic customization. > An additional motivation for this proposal is that PEP 484 already defines > the use of module ``__getattr__`` for this purpose in Python stub files, > see [1]_. > > > Specification > ============= > > The ``__getattr__`` function at the module level should accept one argument > which is a name of an attribute and return the computed value or raise > an ``AttributeError``:: > > def __getattr__(name: str) -> Any: ... > > This function will be called only if ``name`` is not found in the module > through the normal attribute lookup. > > The reference implementation for this PEP can be found in [2]_. > > > Backwards compatibility and impact on performance > ================================================= > > This PEP may break code that uses module level (global) name > ``__getattr__``. > The performance implications of this PEP are minimal, since ``__getattr__`` > is called only for missing attributes. > > > References > ========== > > .. [1] PEP 484 section about ``__getattr__`` in stub files > (https://www.python.org/dev/peps/pep-0484/#stub-files) > > .. [2] The reference implementation > (https://github.com/ilevkivskyi/cpython/pull/3/files) > > > Copyright > ========= > > This document has been placed in the public domain. > > _______________________________________________ > Python-ideas mailing list > Python-ideas@python.org > https://mail.python.org/mailman/listinfo/python-ideas > Code of Conduct: http://python.org/psf/codeofconduct/ > >
_______________________________________________ Python-ideas mailing list Python-ideas@python.org https://mail.python.org/mailman/listinfo/python-ideas Code of Conduct: http://python.org/psf/codeofconduct/