Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python 3.6: abc.abstracmethod on classmethod no check on class level call

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
like image 511
Michael Hooreman Avatar asked Jun 29 '26 18:06

Michael Hooreman


1 Answers

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.

like image 102
Nik Avatar answered Jul 02 '26 08:07

Nik



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!