[Python-Dev] PEP 549: Instance Properties (aka: module properties)

Larry Hastings larry at hastings.org
Sun Sep 10 23:42:11 EDT 2017



On 09/06/2017 08:26 AM, Guido van Rossum wrote:
> 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).

I guess it's a matter of perspective.  I solved this problem using 
@property, and I don't think it's particularly hacky.  (See my 
implementation at the bottom of this email).  The worst thing it does is 
look up the current module via sys.modules[__name__]... which 
Nathaniel's code also must do.

My example is a lot simpler than Nathaniel's code but it's just a 
proof-of-concept.  Nathaniel's code does much more.  In particular, I 
didn't override __dir__ to hide the deprecated attributes; doing that 
would mean assigning to __class__ just as Nathaniel does.  (If you're 
actually curious to see it I could add that to the proof-of-concept.)

IMO my PEP strikes the right balance.  @property is far more popular 
than __getattr__ or __getattribute__; 19 times out of 20, people use 
@property.  Meanwhile, people for whom @property is insufficient (like 
Nathaniel) can already assign to module.__class__ and override 
__getattr__, __getattribute__, __del__, or any other existing magic 
method.  In other words: the commonplace is easy, and the unusual is 
possible.  Perfect!


//arry

-----

/test_deprecated.py:

    import depmod

    print(depmod.depr1) # throws an exception


depmod.py:

    # module with deprecated properties
    import sys

    _deprecated_properies = (
         ("depr1", 33),
         ("depr2", 44),
         )

    __module__ = sys.modules[__name__]
    def set_deprecated_property(name, value):
         @property
         def prop(self):
             raise RuntimeError(f"property '{name}' is deprecated")
             return value
         setattr(__module__, name, prop)

    for name, value in _deprecated_properies:
         set_deprecated_property(name, value)


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-dev/attachments/20170910/0bd0b413/attachment.html>


More information about the Python-Dev mailing list