new-style classes multiplication error message isn't very informative

Steven D'Aprano steve at REMOVETHIScyber.com.au
Fri Dec 30 00:11:48 EST 2005


On Fri, 30 Dec 2005 03:47:30 +0000, Jon Guyer wrote:

>>>> This is a fake line to confuse the stupid top-posting filter at gmane
> 
> We have a rather complicated class that, under certain circumstances, knows
> that it cannot perform various arithmetic operations, and so returns
> NotImplemented.  As a trivial example:
> 
>     >>> class my:
>     ...     def __mul__(self, other):
>     ...             return NotImplemented
>     ... 
>     >>> my() * my()
>     Traceback (most recent call last):
>       File "<stdin>", line 1, in ?
>     TypeError: unsupported operand type(s) for *: 'instance' and 'instance'
> 
> This error message isn't hugely meaningful to many of our users (and in
> complicated expressions, I'd certainly benefit from knowing exactly which
> subclasses of 'my' are involved)

Why don't you raise the exception yourself?

(Note the difference between NotImplemented and NotImplementedError.)


>>> class Parrot:
...     def __mul__(self, other):
...             raise NotImplementedError("Can't multiply %s yet!" %
...             self.__class__.__name__)
...
>>> x = Parrot()*2
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
  File "<stdin>", line 3, in __mul__
NotImplementedError: Can't multiply Parrot yet!


I've always considered NotImplementedError to be for situations that I
just haven't got around to implementing *yet*. For operations which should
not be implemented because they aren't meaningful, I define my own
exceptions.


I'd never noticed the behaviour of Python where it takes a return value of
NotImplemented and raises a ValueError. Unless somebody can tell me why
this is justified, I consider this at best a wart. If I return something,
that's my return value! I don't see why arithmetic operations are special
enough to justify this special behaviour.


-- 
Steven.




More information about the Python-list mailing list