So we've seen a real use case for __class__ assignment: deprecating things on access. That use case could also be solved if modules natively supported defining __getattr__ (with the same "only used if attribute not found otherwise" semantics as it has on classes), but it couldn't be solved using @property (or at least it would be quite hacky).
Is there a real use case for @property? Otherwise, if we're going to mess with module's getattro, it makes more sense to add __getattr__, which would have made Nathaniel's use case somewhat simpler. (Except for the __dir__ thing -- what else might we need?) On Tue, Sep 5, 2017 at 3:52 PM, Nathaniel Smith <n...@pobox.com> wrote: > On Tue, Sep 5, 2017 at 3:03 PM, Larry Hastings <la...@hastings.org> wrote: > > > > I've written a PEP proposing a language change: > > > > https://www.python.org/dev/peps/pep-0549/ > > > > The TL;DR summary: add support for property objects to modules. I've > > already posted a prototype. > > Interesting idea! It's definitely less arcane than the __class__ > assignment support that was added in 3.5. I guess the question is > whether to add another language feature here, or to provide better > documentation/helpers for the existing feature. > > If anyone's curious what the __class__ trick looks like in practice, > here's some simple deprecation machinery: > https://github.com/njsmith/trio/blob/ee8d909e34a2b28d55b5c6137707e8 > 861eee3234/trio/_deprecate.py#L102-L138 > > And here's what it looks like in use: > https://github.com/njsmith/trio/blob/ee8d909e34a2b28d55b5c6137707e8 > 861eee3234/trio/__init__.py#L91-L115 > > Advantages of PEP 549: > - easier to explain and use > > Advantages of the __class__ trick: > - faster (no need to add an extra step to the normal attribute lookup > fast path); only those who need the feature pay for it > > - exposes the full power of Python's class model. Notice that the > above code overrides __getattr__ but not __dir__, so the attributes > are accessible via direct lookup but not listed in dir(mod). This is > on purpose, for two reasons: (a) tab completion shouldn't be > suggesting deprecated attributes, (b) when I did expose them in > __dir__, I had trouble with test runners that iterated through > dir(mod) looking for tests, and ended up spewing tons of spurious > deprecation warnings. (This is especially bad when you have a policy > of running your tests with DeprecationWarnings converted to errors.) I > don't think there's any way to do this with PEP 549. > > - already supported in CPython 3.5+ and PyPy3, and with a bit of care > can be faked on all older CPython releases (including, crucially, > CPython 2). PEP 549 OTOH AFAICT will only be usable for packages that > have 3.7 as their minimum supported version. > > I don't imagine that I would actually use PEP 549 any time in the > foreseeable future, due to the inability to override __dir__ and the > minimum version requirement. If you only need to support CPython 3.5+ > and PyPy3 5.9+, then you can effectively get PEP 549's functionality > at the cost of 3 lines of code and a block indent: > > import sys, types > class _MyModuleType(types.ModuleType): > @property > def ... > > @property > def ... > sys.modules[__name__].__class__ = _MyModuleType > > It's definitely true though that they're not the most obvious lines of > code :-) > > -n > > -- > Nathaniel J. Smith -- https://vorpus.org > _______________________________________________ > Python-Dev mailing list > Python-Dev@python.org > https://mail.python.org/mailman/listinfo/python-dev > Unsubscribe: https://mail.python.org/mailman/options/python-dev/ > guido%40python.org > -- --Guido van Rossum (python.org/~guido)
_______________________________________________ Python-Dev mailing list Python-Dev@python.org https://mail.python.org/mailman/listinfo/python-dev Unsubscribe: https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com