Search code examples
python-3.xabstract-class

Why does this abstract static method return None?


The concrete class doesn't implement foo()

import abc

class Base(abc.ABC):

    @staticmethod
    @abc.abstractmethod
    def foo():
        ...

class Concrete(Base):
    pass

print(Concrete.foo())  # prints "None"

I'd expect this to fail with an error


Solution

  • It turns out that classes defined like:

    def foo():
        ...
    

    Will return None when called. If I want to communicate "hey you forgot to implement this" on a static method in a context where the caller never creates an object, I need to explicitly raise that error in the base class:

    import abc
    class Base:
    
        @staticmethod
        @abc.abstractmethod
        def foo():
            raise NotImplementedError("subclasses must implement this")
    
    class Concrete(Base):
        pass
    

    The expected error will show up if the caller attempts to create an object like below.

    obj = Concrete()  # TypeError: Can't instantiate abstract class Concrete with abstract methods foo
    

    However, if Concrete does define foo() it will be called instead.