Typing: Abstract class methods?

Created on 1 Aug 2018  路  7Comments  路  Source: python/typing

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.

Most helpful comment

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.

All 7 comments

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.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

saulshanabrook picture saulshanabrook  路  6Comments

shoyer picture shoyer  路  8Comments

max-sixty picture max-sixty  路  7Comments

LiraNuna picture LiraNuna  路  7Comments

scherrey picture scherrey  路  3Comments