New submission from Antony Lee <[email protected]>:
When checking whether a class implements all abstractmethods (to know whether
the class can be instantiated), one should only consider methods that come
*before* the abstractmethod in the MRO -- methods that come after cannot be
said to override the abstractmethod. Indeed, this is currently the case:
from abc import ABC, abstractmethod
class NeedsFoo(ABC):
foo = abstractmethod(lambda self: None)
class HasFoo(ABC):
foo = lambda self: None
class FooImplFirst(HasFoo, NeedsFoo): pass
class FooImplSecond(NeedsFoo, HasFoo): pass
FooImplFirst()
try: FooImplSecond()
except TypeError: pass
else: raise Exception("Expected error")
Here FooImplFirst correctly overrides the foo method (using the HasFoo mixin
first), so can be instantiated; FooImplSecond doesn't (by the MRO,
FooImplSecond().foo would resolve to the abstract implementation), and we get a
TypeError on instantiation.
However, this is not the case when considering builtins:
from abc import ABC, abstractmethod
class NeedsKeys(ABC):
keys = abstractmethod(lambda self: None)
HasKeys = dict # dict has a keys method.
class KeysImplFirst(HasKeys, NeedsKeys): pass
class KeysImplSecond(NeedsKeys, HasKeys): pass
KeysImplFirst()
try: KeysImplSecond()
except TypeError: pass
else: raise Exception("Expected error")
This example differs from the first only by having dict be the mixin that
provides the keys method. However, running this example shows that
KeysImplSecond() will incorrectly succeed: the ABC machinery does not realize
that the keys method has not been overridden.
(Alternatively, one could say that "providing the method later in the MRO" is
also sufficient; I think that goes against the expectations about ABCs but at
least consistency between the non-builtin and builtin cases would be better.)
----------
components: Library (Lib)
messages: 328419
nosy: Antony.Lee
priority: normal
severity: normal
status: open
title: Checking for abstractmethod implementation fails to consider MRO for
builtins
versions: Python 3.7
_______________________________________
Python tracker <[email protected]>
<https://bugs.python.org/issue35063>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe:
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com