Unlike most errors, this one is raised on purpose and often by design. Base classes and abstract interfaces raise it in placeholder methods to say “subclasses must implement this”; libraries raise it for operations that do not exist on the current platform or plan. It is a signpost, not a malfunction: it tells you the code path you reached is a deliberate dead end, and the work is finding the intended path.
class Storage:
def save(self, data):
raise NotImplementedError
class FileStorage(Storage):
pass # forgot to implement save()
FileStorage().save("hello")
Traceback (most recent call last):
File "main.py", line 9, in <module>
NotImplementedError
abc module (@abstractmethod), which moves this failure earlier, to object creation, with a message naming every missing method at once.If third-party code raises NotImplementedError on a mainstream platform and version, you have usually installed a build or backend that lacks the feature (a minimal wheel, a missing optional dependency). The project's installation docs name the extra that provides it.
What is the difference between NotImplementedError and NotImplemented? They are unrelated despite the names. NotImplementedError is an exception class you raise. NotImplemented is a special value that binary special methods (like __eq__) return to tell Python to try the other operand's method. Raising the value, or returning the exception class, are both bugs.
Should my own code raise NotImplementedError or use abstract base classes? Abstract base classes (abc) are the modern enforcement: instantiation fails immediately, listing all unimplemented methods. NotImplementedError remains right for methods that are optional, platform-dependent, or part of interfaces where only some implementations make sense.