7

I have an abstract base class, Animal:

class Animal(metaclass=abc.ABCMeta):
 @abc.abstractmethod
 def move(self):
 raise NotImplementedError()
 @abc.abstractmethod
 def eat(self):
 raise NotImplementedError()

Now I have another abc that only implements one of these methods:

class Bird(Animal):
 def move(self):
 print("fly")

An another class that implements the missing method:

class Eagle(Bird):
 def eat(self):
 print("eagle eats")

But PyCharm is complaining about Bird that it "must implement all abstract methods", when I intentionally want it to stay abstract still.

Am I missing something, or is this a bug? If it's just a bug, can I ignore the warning somehow (similar to #noqa)?

asked May 20, 2019 at 11:04
2
  • It's not a bug. The entire concept of abstract classes is to force subclasses to implement all methods. Commented May 20, 2019 at 11:15
  • @DeepSpace How about my example then? I should be allowed to have a chain of multiple abc's. Commented May 20, 2019 at 11:25

1 Answer 1

5

Just mark Bird as abstract too:

from abc import ABC
class Bird(Animal, ABC):
 def move(self):
 print("fly")

After thinking about it a little, actually, I think that for this purpose it would make more sense to specify metaclass=ABCMeta, as you did originally, since conceptually we do not want to modify the inheritance hierarchy of Bird, but rather mark it as also an abstract class (for PyCharm's benefit), and perhaps that is a cleaner way of doing so.

answered May 20, 2019 at 11:25
Sign up to request clarification or add additional context in comments.

5 Comments

Right, this doesn't make sense if you think about the inheritance tree imo. Besides, ABC only seems to add metaclass=abc.ABCMeta, and metaclasses inherit to all subclasses, so this doesn't do anything in Python. It did cheat PyCharm though, so thank you! :)
@MarkusMeskanen About inheriting from ABC; yup, that's all it does, but I personally find it more convenient than specifying the metaclass explicitly. About the actual effect, you're right that it doesn't actually do anything. However, PyCharm, by default, assumes that all classes that inherit from abstract classes should be concrete, so this tells PyCharm that this class is specifically still meant to be abstract. As for the inheritance hierarchy, since, as you noted, all this does is change the metaclass, so perhaps using the metaclass method is better, from a principled perspective ;)
You're correct, and maybe it's good to "re-declare" it as an ABC, not just for PyCharm but for our clarity too. I 100% agree about the use of metaclass over subclassing ABC, but unfortunately it didn't cheat PyCharm, it was the first thing I tried before posting the question. I'm not sure why subclassing ABC works but re-defining the metaclass doesn't, but I'm glad you came up with it.
There seems to be a bug report already, maybe it'll be fixed: youtrack.jetbrains.com/issue/PY-33830 For now I'm good with your proposed solution
@MarkusMeskanen I see, so it is a bug. Given what you've tried, it certainly sounds like one. I actually also stumbled upon this solution purely by chance earlier, since I had this exact same problem. Lucky, I guess!

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.