This might not be the right place to put this, but is there any interest in adding a decorator for abstract class methods? (And potentially supporting it in MyPy?)
Currently, annotating a method with both @abstractmethod and @classmethod results in a runtime error. I see some suggestions on how to make this work on StackOverflow, but of course those custom decorators would not be supported in MyPy.
I would be interested in either making using both decorators work, or adding a new decorator.
Since @abstractclassmethod was deprecated, we should fix the combination.
This seems to work fine already:
class A(metaclass=ABCMeta):
@classmethod
@abstractmethod
def f(cls):
pass
So I don't think anything else is needed here.
Good to know that it works, thanks! It looks like my error was happening because I put @abstractmethod and @classmethod in the wrong order:
from abc import ABCMeta, abstractmethod
class B:
__metaclass__ = ABCMeta
@abstractmethod
@classmethod
def f(cls):
pass
Running this with python2 gives the error:
Traceback (most recent call last):
File "test_abstractclassmethod.py", line 3, in <module>
class B:
File "test_abstractclassmethod.py", line 7, in B
@classmethod
File "/Users/sidharthkapur/.pyenv/versions/2.7.14/lib/python2.7/abc.py", line 32, in abstractmethod
funcobj.__isabstractmethod__ = True
AttributeError: 'classmethod' object has no attribute '__isabstractmethod__'
Do we want to fix this? Or is this behavior fine?
If that fails with Python 2 there is nothing we can do about it -- @abstractmethod and @classmethod are both defined by the stdlib, and Python 2 isn't going to fix things like this (Python 2 end of life is 1/1/2020).
Hmm, looks like a similar (not identical) error happens in python3 as well:
Traceback (most recent call last):
File "test_abstractclassmethod.py", line 3, in <module>
class B:
File "test_abstractclassmethod.py", line 7, in B
@classmethod
File "/Users/sidharthkapur/.pyenv/versions/3.6.4/lib/python3.6/abc.py", line 25, in abstractmethod
funcobj.__isabstractmethod__ = True
AttributeError: attribute '__isabstractmethod__' of 'classmethod' objects is not writable
You can file a bug in the Python issue tracker -- possibly this is all we
can do and it should just be documented. Or possibly it is already
documented?
Note that that error happens only with one ordering of the two decorators; it works if you swap them. Ideally that should indeed be documented though, and perhaps @abstractmethod should have a better error message tailored for this case.
Most helpful comment
This seems to work fine already:
So I don't think anything else is needed here.