2

Consider this code

from abc import ABCMeta, abstractmethod class C(): @abstractmethod def my_abstract_method(self): print('foo') class D(C): pass x = C() y = D() 

Neither x nor y is allowed by mypy yielding me a

test.py:13: error: Cannot instantiate abstract class 'C' with abstract attribute 'my_abstract_method' test.py:15: error: Cannot instantiate abstract class 'D' with abstract attribute 'my_abstract_method' 

I'm testing this with mypy 0.570 and python 3.6.3

However, the documentation says that I'd need to set metaclass=ABCMeta for that to work. What am I missing?

4
  • Which Python version ? I can't reproduce this behaviour on 2.7.x nor on 3.4.3 Commented Mar 15, 2018 at 11:12
  • Updated question. I'm getting the error with mypy version 0.570. Btw, I'm getting no python errors directly no matter if I apply the metaclass=ABCMeta or not. So mypy is the only tool that actually helps me to catch this error anyway. Commented Mar 15, 2018 at 11:21
  • mypy and python do two very different things. mypy is a static analyzer, and is free to make the assumption that you forgot to use ABCMeta if @abstractmethod is present in the source of your code. python just interprets the code, and without ABCMeta, it has no reason to do anything with the list of methods populated by @abstractmethod. (Indeed, at runtime there is no evidence in the method itself that it was decorated.) Commented Mar 15, 2018 at 16:33
  • @chepner yes, that's true. It just happened that I noticed mypy catches the error without the metaclass being set and I didn't further check what python actually does. I just stopped there left wondering why mypy catches the error when I thought it shouldn't. Thanks for the background info! Commented Mar 16, 2018 at 14:49

1 Answer 1

4

Ok, turns out without metaclass=ABCMeta only mypy will catch the error whereas with the metaclass=ABCMeta both mypy and python will catch the error.

See:

from abc import abstractmethod class C(): @abstractmethod def my_abstract_method(self): print('foo') class D(C): pass x = C() y = D() $ mypy test.py test.py:13: error: Cannot instantiate abstract class 'C' with abstract attribute 'my_abstract_method' test.py:15: error: Cannot instantiate abstract class 'D' with abstract attribute 'my_abstract_method' 

but

$ python3 test.py $ 

Whereas with that, python will catch the error as well.

from abc import ABCMeta, abstractmethod class C(metaclass=ABCMeta): @abstractmethod def my_abstract_method(self): print('foo') class D(C): pass x = C() y = D() $ python3 test.py Traceback (most recent call last): File "test.py", line 11, in <module> x = C() TypeError: Can't instantiate abstract class C with abstract methods my_abstract_method 
Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.