NotImplementedError
The base class says "a subclass must provide this" — you get the error only when the missing method is actually called, not when the object is created.
Demo
class Exporter: def export(self, data): raise NotImplementedError('subclasses must implement export()') class CsvExporter(Exporter): def export(self, data): return ','.join(data) class JsonExporter(Exporter): pass exporters = {'csv': CsvExporter(), 'json': JsonExporter()} exporters['csv'].export(['a', 'b'])
Creating JsonExporter() worked fine — the error only appears when export() is called, because the base method runs and raises. Compare the unknown format: that is a KeyError from the dict, a different problem entirely. abc.abstractmethod (see the pitfalls) moves the failure earlier, to object creation.
Constructor
| Name | Type | Required | Description |
|---|---|---|---|
| *args | object | no | Optional message, e.g. which method must be overridden. With no args the traceback line is the bare class name. |
Attributes
| Attribute | Type | Meaning |
|---|---|---|
| args | tuple | The message you passed, or () for a bare raise NotImplementedError. |
Common patterns
class Shape: def area(self): raise NotImplementedError(f'{type(self).__name__} must implement area()')
from abc import ABC, abstractmethod class Shape(ABC): @abstractmethod def area(self): ...
class Money: def __init__(self, cents): self.cents = cents def __add__(self, other): if not isinstance(other, Money): return NotImplemented return Money(self.cents + other.cents)
Examples
Pitfalls
class Shape: def area(self): raise NotImplemented Shape().area()
class Shape: def area(self): raise NotImplementedError('area') Shape().area()
class Money: def __init__(self, cents): self.cents = cents def __eq__(self, other): if not isinstance(other, Money): raise NotImplementedError return self.cents == other.cents Money(5) == 5
class Money: def __init__(self, cents): self.cents = cents def __eq__(self, other): if not isinstance(other, Money): return NotImplemented return self.cents == other.cents Money(5) == 5
class Plugin: def run(self): raise NotImplementedError class Broken(Plugin): pass p = Broken() 'created'
from abc import ABC, abstractmethod class Plugin(ABC): @abstractmethod def run(self): ... class Broken(Plugin): pass p = Broken() 'created'
When to use
- A base-class method every subclass must override
- A stub for a feature still being written (with a message saying so)
- A method that is legitimately unsupported for one specific subclass, e.g. write() on a read-only backend
- Binary operators and rich comparisons → return NotImplemented
- An operation that should never exist on the class → leave it undefined (or set it to None in a subclass)
- Enforcing overrides at creation time → abc.ABC + @abstractmethod
Notes
FAQ
NotImplementedError is an exception you raise from a method a subclass must override. NotImplemented is a constant you RETURN from binary operator methods (__eq__, __add__, __lt__, …) to say 'I do not know how to handle this type' — Python then tries the other operand's reflected method and, if that also returns NotImplemented, raises TypeError (or, for ==, falls back to identity). They are not interchangeable: raise NotImplemented is a TypeError, and raising NotImplementedError from __eq__ breaks comparisons.