Previous discussion: https://discuss.python.org/t/abc-add-abstract-attributes-via-abstract-type-hint/26164
Feature or enhancement
Sometimes, we want to indicate that all subclasses of an abstract base class must have some attribute. Currently, this can only be done by combining @property and @abstractmethod:
from abc import ABC, abstractmethod
class Foo(ABC):
@property
@abstractmethod
def myattr(self) -> int: ...
However, this is verbose. Even more so if we want to assert that the attribute must be settable.
from abc import ABC, abstractmethod
class Foo(ABC):
@property
@abstractmethod
def myattr(self) -> int: ...
@myattr.setter
@abstractmethod
def myattr(self, x: int, /) -> None: ...
class Bar(Foo):
myattr: int = 1
Bar()
Secondly, since @classmethod and @property cannot be combined anymore, we cannot use this to assert the existence of abstract class-attributes.
Finally, a user might wish to indicate that an attribute has to be implemented by a property. (For instance, because the attribute is expensive to compute, so the lazy evaluation of properties might be important). If the new method of hinting abstract attributes is accepted, then at some point in the future the way ABCs work can be changed to require that @abstractmethod-properties must be implement as properties by the subclass.
Pitch
Add two new typing constructs: Abstract and Mutable OR AbstractAttribute and AbstractMutableAttribute, analogous to e.g. Sequence and MutableSequence. (Not sure which one is preferable)
AbstractAttribute/Abstract guarantees read-access. Subclasses can implement it via a @property or a regular attribute.
AbstractMutableAttribute/Abstract[Mutable] guarantees read and write access. Subclasses can implement via a @property with getter and setter or as a regular attribute.
- Either can be combined with
ClassVar to indicate abstract class-attributes. (⇝ composability with other 'modifiers' like e.g. dataclasses.InitVar ?!)
For example:
class Foo(ABC):
x: Abstract[int] # ALT: AbstractAttribute[int]
y: Abstract[Mutable[float]] # ALT: AbstractMutableAttribute[float]
z: Abstract[ClassVar[int]] # ALT: AbstractAttribute[ClassVar[int]]
class Bar(Foo):
z: ClassVar[int] = 42
@property
def x(self) -> int:
return 0
@property
def y(self) -> int:
return 1
Would fail since Bar is missing the setter for y.
Previous discussion: https://discuss.python.org/t/abc-add-abstract-attributes-via-abstract-type-hint/26164
Feature or enhancement
Sometimes, we want to indicate that all subclasses of an abstract base class must have some attribute. Currently, this can only be done by combining
@propertyand@abstractmethod:However, this is verbose. Even more so if we want to assert that the attribute must be settable.
Secondly, since
@classmethodand@propertycannot be combined anymore, we cannot use this to assert the existence of abstract class-attributes.Finally, a user might wish to indicate that an attribute has to be implemented by a property. (For instance, because the attribute is expensive to compute, so the lazy evaluation of properties might be important). If the new method of hinting abstract attributes is accepted, then at some point in the future the way
ABCs work can be changed to require that@abstractmethod-properties must be implement as properties by the subclass.Pitch
Add two new typing constructs:
AbstractandMutableORAbstractAttributeandAbstractMutableAttribute, analogous to e.g.SequenceandMutableSequence. (Not sure which one is preferable)AbstractAttribute/Abstractguarantees read-access. Subclasses can implement it via a@propertyor a regular attribute.AbstractMutableAttribute/Abstract[Mutable]guarantees read and write access. Subclasses can implement via a@propertywith getter and setter or as a regular attribute.ClassVarto indicate abstract class-attributes. (⇝ composability with other 'modifiers' like e.g.dataclasses.InitVar?!)For example:
Would fail since
Baris missing the setter fory.