Hey all, I recently ran into some trouble and that I think deserves some attention. Consider the following case:
class A(ABC): @abstractmethod def __lt__(self, other): pass @dataclass(order=True) class B(A): x: int = 0 class C(B): pass Although B technically implements A's abstract methods, it is still considered an abstract class, and calling B() will fail. However, C is considered a non-abstract class and calling C() will succeed. This is because a class's "abstraction" is decided when a class is created. When B is created it does not implement __lt__, the implementation is added after creation by the dataclass decorator. Since C inherits from B after having its __lt__ set, C is considered non-abstract. This will also affect any "mixin-decorator" such as total_ordering, and also (a less-preferred use case) implementing abstract methods after class creation. There are many solutions for this, my proposed solution is for abc.ABCMeta to implement a __setattr__, that erases unimplemented metaclasses f they are implemented after class creation, Something along these lines: class ABCMeta2(ABCMeta): def __setattr__(self, key, value): super().__setattr__(key, value) if key != '__abstractmethods__' and value is not None: self.__abstractmethods__ -= {key} Obviously some additional logic is needed to handle sub-classes and such, but I think it's a good starting point. Any thoughts?
_______________________________________________ Python-ideas mailing list -- python-ideas@python.org To unsubscribe send an email to python-ideas-le...@python.org https://mail.python.org/mailman3/lists/python-ideas.python.org/ Message archived at https://mail.python.org/archives/list/python-ideas@python.org/message/6BNJ3YSEBPHEPGXSAZGBW3TJ64ZGZIHE/ Code of Conduct: http://python.org/psf/codeofconduct/