Randolf Scholz <randolf.sch...@gmail.com> added the comment:

@Terry I think the problem boils down to the fact that `@classmethod @property` 
decorated methods end up not being real properties.

Calling `MyBaseClass.__dict__` reveals:

```python
mappingproxy({'__module__': '__main__',
              'expensive_class_property': <classmethod at 0x7f893e95dd60>,
              'expensive_instance_property': <property at 0x7f893e8a5860>,
              '__dict__': <attribute '__dict__' of 'MyBaseClass' objects>,
              '__weakref__': <attribute '__weakref__' of 'MyBaseClass' objects>,
              '__doc__': None,
              '__abstractmethods__': frozenset(),
              '_abc_impl': <_abc._abc_data at 0x7f893fb98740>})
```

Two main issues:

1. Any analytics or documentation tool that has special treatment for 
properties may not identify 'expensive_class_property' as a property if they 
simply check via `isinstance(func, property)`. Of course, this could be fixed 
by the tool-makers by doing a conditional check:

```python
isinstance(func, property) or (`isinstance(func, classmethod)` and 
`isinstance(func.__func__, property)`
```

2. `expensive_class_property` does not implement `getter`, `setter`, `deleter`. 
This seems to be the real dealbreaker, for example, if we do

```python
MyBaseClass.expensive_class_property = 2
MyBaseClass().expensive_instance_property = 2
```

Then the first line erroneously executes, such that 
MyBaseClass.__dict__['expensive_class_property'] is now `int` instead of 
`classmethod`, while the second line correctly raises `AttributeError: can't 
set attribute` since the setter method is not implemented.

----------

_______________________________________
Python tracker <rep...@bugs.python.org>
<https://bugs.python.org/issue45356>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com

Reply via email to