I don't really see the point of having this read
method defined with pass as single instruction. If you don't need it, let it raise NotImplementedError
.
class IReader(object):
@abstractmethod
def read(self):
raise NotImplementedError
As specified in the docs, an abstract method can have an implementation used by children with super()
. But in your case, it does nothing. Therefore, unless you have a good reason, you might as well let it raise NotImplementedError
.
(Arguably, a good reason could be a pattern where all your children call super().my_method()
for some reason, so you need an implementation for all methods in the abstract class.)
How to exclude the abstract method from coverage report
Regardless, the test coverage is just an indicator you build: the part of the code you want to test that you actually test. Defining the "code you want to test" is up to you.
You could add a test to check that the abstract method returns NotImplementedError
or just pass
es, if you see an interest in this.
Or you may think (which seems reasonable) that testing this is pointless, in which case excluding the method from coverage report #pragma: no cover
seems like the way to go:
class IReader(object): #pragma: no cover
@abstractmethod
def read(self):
pass
The doc page linked above shows how you can also exclude all NotImplementedError
methods adding this to your configuration file:
[report]
exclude_lines =
pragma: no cover
raise NotImplementedError
so that you don't have to add a pragma
to each abstract method.
2020 edit
I just noticed the @abstractmethod decorator. Since it prevents the class from being instantiated, I wouldn't raise NotImplementedError
. See this other answer.
I'd just leave the method empty. Syntaxically, a docstring is enough
class IReader(object):
@abstractmethod
def read(self):
"""Read data"""