Consider the following code example
import abc
class ABCtest(abc.ABC):
@abc.abstractmethod
def foo(self):
raise RuntimeError("Abstract method was called, this should be impossible")
class ABCtest_B(ABCtest):
pass
test = ABCtest_B()
This correctly raises the error:
Traceback (most recent call last):
File "/.../test.py", line 10, in <module>
test = ABCtest_B()
TypeError: Can't instantiate abstract class ABCtest_B with abstract methods foo
However when the subclass of ABCtest
also inherits from a built in type like str
or list
there is no error and test.foo()
calls the abstract method:
class ABCtest_C(ABCtest, str):
pass
>>> test = ABCtest_C()
>>> test.foo()
Traceback (most recent call last):
File "<pyshell#0>", line 1, in <module>
test.foo()
File "/.../test.py", line 5, in foo
raise RuntimeError("Abstract method was called, this should be impossible")
RuntimeError: Abstract method was called, this should be impossible
This seems to happen when inheriting from any class defined in C including itertools.chain
and numpy.ndarray
but still correctly raises errors with classes defined in python. Why would implementing one of a built in types break the functionality of abstract classes?
foo
should be enforced to be overridden in a subclass, normally (and without also inheritting fromstr
) instantiating it raises an error, however when also inherriting fromstr
no error happens and the abstract methodtest.foo
is a valid callable method. – Aspectualstr
isn't a variable name. – Fuquaabc.py
since there is no entry in the traceback I think that the error originates fromtype.__call__
so I think a look into the C source code will be required to answer why this is happening... – Aspectual