returning NotImplemented

Eric Snow ericsnowcurrently at gmail.com
Tue May 31 17:46:49 EDT 2011


Looking at the ABC code [1], I noticed that Mapping's __eq__ method can
return NotImplemented.  This got me curious as to why you would return
NotImplemented and not raise a TypeError or a NotImplementedError.

There was an issue regarding this last year [2] that indicated the reason
for Mapping's behavior.  Also, I found a thread from python-dev [3] which
talks about the use of NotImplemented (the thread relates to numeric
coercion).  I found some older documentation on informal coercion guidelines
that helped [4].  My understanding is that NotImplemented is used for binary
operators: the right hand side of the operator should be tried if the left
hand side returns NotImplemented.  So it's more like
DoNotKnowHowToHandleArgumentOfThatType.  I think the name may have added to
my confusion.   (BTW, I learned that NotImplemented is a singleton, like
None).

Is binary operators the only place that NotImplemented is used under the
hood?  Is it all binary operators, and if not, where does it say which
operators use NotImplemented?  This would have bearing on when I would need
to return it.

In the python-dev thread [3], MRAB indicates NotImplemented is used instead
of exceptions for performance reasons.  Is raising NotImplementedError or
TypeError that big a difference?  I expect if you are using the operator on
a large loop it could matter, but how much?

Guido indicates earlier in the thread that NotImplemented is used so that
you know that it came from the function that you directly called, and not
from another call inside that function.  Why does it matter if it came
directly from the function or not?  And couldn't the NotImplemented still
have come from a call inside the operator, rather than directly?

As an aside, don't we have that same situation all over the place.  For
instance, using __getattribute__, how do you know if an AttributeError means
that the attribute was not found on the object?  It could mean that
__getattribute__ called something that raised the exception (and perhaps it
should have handled it).  Does it matter?  Is there a good way to tell the
difference, or would it be good practice to always handle explicitly in a
function any exception type that you may be raising there?

Thanks,

-eric

[1]
http://hg.python.org/cpython/file/29e08a98281d/Lib/collections/abc.py#l398
[2] http://bugs.python.org/issue8729
[3] http://mail.python.org/pipermail/python-dev/2005-March/051835.html
[4] http://docs.python.org/release/2.5.2/ref/coercion-rules.html
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-list/attachments/20110531/9507c40a/attachment.html>


More information about the Python-list mailing list