Python
NotImplemented
NotImplementedError
error handling
programming practices

Why return NotImplemented instead of raising NotImplementedError

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

When designing Python classes, particularly those intended to interact with various objects in arithmetic or comparison operations, developers face a choice: how best to signal an operation that isn't implemented for certain object types. A common point of confusion arises between returning `NotImplemented` and raising `NotImplementedError`. Despite their similar names, these signify fundamentally different things and serve distinct uses. Through a discussion of technical explanations and examples, this article aims to clear up why you might opt to return `NotImplemented` instead of raising `NotImplementedError`.

Difference Between `NotImplemented` and `NotImplementedError`

Understanding the difference between `NotImplemented` and `NotImplementedError` is crucial before diving into situations where one is preferred over the other.

  • `NotImplemented`: A special return value intended primarily for binary special methods such as `eq`, `add`, etc. This is a singleton used to indicate that an operation on a given pair of operands isn't defined, giving the interpreter a cue to try alternative strategies.
  • `NotImplementedError`: An exception raised to indicate that a method or operation hasn't been implemented at all. It's essentially a placeholder, often used during development when an interface or superclass defines a method that should be implemented by any subclass.

Key Characteristics and Use Cases

Returning `NotImplemented`

In binary special methods, the return value `NotImplemented` serves as a mechanism to indicate that the given operation is not supported between the two subjects in question. Here's how it works:

  • Delegation Mechanism: When Python tries to evaluate an operation involving two objects (e.g., `a + b`), it checks whether the left-hand operand (`a`) knows how to perform the operation with the right-hand operand (`b`). If the left-hand operand's method (e.g., `a.add(b)`) returns `NotImplemented`, Python will then call the reverse method on the right-hand operand (e.g., `b.radd(a)`), giving it the opportunity to handle the operation.
  • Interoperability: Returning `NotImplemented` fosters interoperability and extensibility, encouraging Python to handle operations outside the immediately apparent pairing of operands. This promotes the data model principle that encourages operands to be neighboring types rather than the same (or directly compatible) object.

Here's a rudimentary example outlining this behavior:


Course illustration
Course illustration

All Rights Reserved.