[Python-Dev] Decimal & returning NotImplemented (or not)

Guido van Rossum gvanrossum at gmail.com
Thu Mar 3 04:58:00 CET 2005

> Nick Craig-Wood wrote:
> > Why is it like that?

Nick Coghlan replied:
> Speed, I assume - if it was exception based, then *every* operation effectively
> gets wrapped in a try/except block. Yikes!

No, the reason is that if we did this with exceptions, it would be
liable to mask errors; an exception does not necessarily originate
immediately with the code you invoked, it could have been raised by
something else that was invoked by that code. The special value
NotImplemented must pretty much originate directly in the invoked
code, since the implementation guarantees that e.g. a+b can never
*return* NotImplemented: if a.__add__(b) and b.__radd__(a) both return
NotImplemented, TypeError is raised.

(Then why is StopIteration an exception instead of a special value,
you may ask? That's because we didn't want to have a value that you
could stick in a list to stop iteration over the list prematurely,
which would cause problems similar to null bytes in C strings. For
binary operators this isn't a problem, since binary operators (at
least by convention) always return an object that itself supports the
same binary operator that produced it, and NotImplemented itself
doesn't implement any binary operators.)

> Also, for C implementations, the error return is fairly natural. It's only when
> implementing operations in Python that it bites.

You went on to great lengths later about how it's less natural in
Python to return an error value, but I disagree. I've written a lot of
code like this and it's quite natural to write things like this:

    def __add__(self, other):
        if not isinstance(other, ThisClass):
            return NotImplemented
        return ...implementation of self + other...

If you want to factor out the type check, it makes just as much sense
to define a Boolean function:

    def __add__(self, other):
        if not self.acceptableArgument(other):
            return NotImplemented

I'm guessing this wasn't caught before 2.4 was released because most
people reviewing the code were more interested in correct computations
than into correct integration in the Python framework.

--Guido van Rossum (home page: http://www.python.org/~guido/)

More information about the Python-Dev mailing list