With python 3.6, When I decorate an abstractmehod
with abc.abstractmethod
withing a class having metaclass=abc.ABCMeta
, the abstract method can be called from a class (not instance) point of view.
It seems that the abc
decorators are performing the checks when the class is instanciated, so it is not done when calling from instance.
This behavior is highly disturbing and it looks like a bug in the abc
module.
What did I miss?
Thanks
Code example:
import abc
import sys
class P(metaclass=abc.ABCMeta):
@classmethod
@abc.abstractmethod
def acm(cls):
pass
class X(P):
pass
print("P.acm()", file=sys.stderr)
try:
P.acm()
print("OK")
except Exception as e:
print(f"KO: {e}")
print("P().acm()", file=sys.stderr)
try:
P().acm()
print("OK")
except Exception as e:
print(f"KO: {e}")
Results:
P.acm()
OK
P().acm()
KO: Can't instantiate abstract class P with abstract methods acm
This behavior is consistent with the behavior described in the documentation for @classmethod
.
https://docs.python.org/3.6/library/functions.html?highlight=classmethod#classmethod
"It can be called either on the class (such as C.f()) or on an instance (such as C().f())."
In this case, it can't be called on an instance because it is abstract, but since it's a classmethod, it is still okay to call it on the class directly.