This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

classification
Title: Abstract instance and class attributes for abstract base classes
Type: enhancement Stage:
Components: Versions: Python 3.9
process
Status: open Resolution:
Dependencies: Superseder:
Assigned To: Nosy List: AlexWaygood, ajoino, rzepecki.t
Priority: normal Keywords:

Created on 2021-08-12 23:48 by rzepecki.t, last changed 2022-04-11 14:59 by admin.

Files
File name Uploaded Description Edit
example.py rzepecki.t, 2021-08-12 23:48
Messages (5)
msg399486 - (view) Author: Tomasz Rzepecki (rzepecki.t) Date: 2021-08-12 23:48
There seems to be no way to transparently make an abstract base class enforce instance attributes for subclasses (without creating a custom metaclass, see e.g. https://newbedev.com/python-abstract-class-shall-force-derived-classes-to-initialize-variable-in-init).

The analogous problem for enforcing *class* attributes in subclasses can be solved by creating an abstract class property (which can then be overridden by a class attribute), but this feels like a hack and possibly a bug (see https://bugs.python.org/issue44904 for a related bug).

The corresponding "solution" for instance attributes does not work (see attached file), and probably rightly so.

This seems like an oversight to me.
msg399534 - (view) Author: Alex Waygood (AlexWaygood) * (Python triager) Date: 2021-08-13 13:05
+1 to this suggestion. I had a use case for this the other day. It currently feels like something of a discrepancy between ABCs and `typing.Property`, which can be seen as analogous in some ways to "an ABC for the static type-checker". `typing.Property` allows you to specify that an object must have certain attributes, as well as certain methods, while for ABCs it is only the latter.
msg399649 - (view) Author: Alex Waygood (AlexWaygood) * (Python triager) Date: 2021-08-16 11:07
Tomasz -- as discussed in the original BPO issue for `abstractmethod` implementations (https://bugs.python.org/issue1706989), this works as a workaround:

```
>>> from abc import ABCMeta
>>> class AbstractAttribute:
... 	__isabstractmethod__ = True
... 	
>>> class Foo(metaclass=ABCMeta):
... 	abstract_attribute_to_be_overriden = AbstractAttribute()
... 	
>>> class Bar(Foo): pass
... 
>>> b = Bar()
Traceback (most recent call last):
  File "<input>", line 1, in <module>
TypeError: Can't instantiate abstract class Bar with abstract method abstract_attribute_to_be_overriden
```

It would be nice to have something like this in the `abc` module, though.
msg399650 - (view) Author: Alex Waygood (AlexWaygood) * (Python triager) Date: 2021-08-16 11:10
^And, that only works for class attributes, not instance attributes.
msg399653 - (view) Author: Jacob Nilsson (ajoino) Date: 2021-08-16 11:39
Could one possible downside of this suggestion be, if implemented like in https://newbedev.com/python-abstract-class-shall-force-derived-classes-to-initialize-variable-in-init, a slowdown in code creating a lot of instances of a class with metaclass ABCMeta?

I have personally never experienced that the current behavior is an issue, I've only occasionally got confused by the error messages until I read the traceback.
History
Date User Action Args
2022-04-11 14:59:48adminsetgithub: 89068
2021-08-16 11:39:37ajoinosetmessages: + msg399653
2021-08-16 11:10:34AlexWaygoodsetmessages: + msg399650
2021-08-16 11:07:55AlexWaygoodsetmessages: + msg399649
2021-08-13 13:05:49AlexWaygoodsetnosy: + AlexWaygood
messages: + msg399534
2021-08-13 07:28:40ajoinosetnosy: + ajoino
2021-08-12 23:48:29rzepecki.tcreate