Re: [Python-Dev] PEP 562

2017年11月15日 04:58:46 -0800

On Tue, Nov 14, 2017 at 10:34 PM, Ivan Levkivskyi <[email protected]>
wrote:
​[..]​
> 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 replacing the
> ``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
>
>
​Deprecating functions is already possible, so I assume the reason for this
would be performance? If so, are you sure this would help for performance?
​
​Deprecating module attributes / globals is indeed difficult to do at
present. This PEP would allow deprecation warnings for accessing
attributes, which is nice! However, as thread-unsafe as it is, many
modules use module attributes to configure the state of the module. In that
case, the user is more likely to *set* the attribute that to *get* it. Is
this outside the scope of the PEP?
​[..]​
> 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.
>
​I'm not surprised that the comparison is in favor of this PEP ;-).​
​[..]​
> Specification
> =============
>
> 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 ``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 Rationale (quoted in the beginning of this email) easily leaves a
different impression of this.​
​[..]
​
>
> Discussion
> ==========
>
> Note that the use of module ``__getattr__`` requires care to keep the
> referred
> objects pickleable. For example, the ``__name__`` attribute of a function
> should correspond to the name with which it is accessible via
> ``__getattr__``::
>
> def keep_pickleable(func):
> func.__name__ = func.__name__.replace('_deprecated_', '')
> func.__qualname__ = func.__qualname__.replace('_deprecated_', '')
> return func
>
> @keep_pickleable
> def _deprecated_old_function(arg, other):
> ...
>
> One should be also careful to avoid recursion as one would do with
> a class level ``__getattr__``.
>
>
Off-topic: In some sense, I'm happy to hear something about pickleability.
But in some sense not.
I think there are three kinds of people regarding pickleability:
1. Those who don't care about anything being pickleable
2. Those ​who care about some things being picklable
​3. ​Those who care about all things being picklable
Personally, I'd like to belong to group 3, but because group 3 cannot even
attempt to coexist with groups 1 and 2, I actually belong to group 1 most
of the time.
​––Koos
​
> 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.
>
>
>
> ..
> Local Variables:
> mode: indented-text
> indent-tabs-mode: nil
> sentence-end-double-space: t
> fill-column: 70
> coding: utf-8
> End:
>
> _______________________________________________
> Python-Dev mailing list
> [email protected]
> https://mail.python.org/mailman/listinfo/python-dev
> Unsubscribe: https://mail.python.org/mailman/options/python-dev/
> k7hoven%40gmail.com
>
>
-- 
+ Koos Zevenhoven + http://twitter.com/k7hoven +
_______________________________________________
Python-Dev mailing list
[email protected]
https://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com

Reply via email to