new-style classes multiplication error message isn't very informative
ziga.seilnacht at gmail.com
ziga.seilnacht at gmail.com
Fri Dec 30 09:01:35 EST 2005
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), but it beats the behavior with new-style
> classes:
>
> >>> class my(object):
> ... def __mul__(self, other):
> ... return NotImplemented
> ...
> >>> my() * my()
> Traceback (most recent call last):
> File "<stdin>", line 1, in ?
> TypeError: can't multiply sequence to non-int
>
> After a lot of googling and a lot of pouring over abstract.c, I now
> understand that object() is defined with a tp_as_sequence, and so the error
> message is the result of the last-ditch effort to do sequence concatentation.
>
> What if I don't want to permit sequence concatenation?
> Is there a way to unset tp_as_sequence?
> Should I be inheriting from a different class? We started inheriting from
> object because we want a __new__ method.
>
> The "'instance' and 'instance'" message would be OK, but even better is the
> result of this completely degenerate class:
>
> >>> class my(object):
> ... pass
> ...
> >>> class your(my):
> ... pass
> ...
> >>> my() * your()
> Traceback (most recent call last):
> File "<stdin>", line 1, in ?
> TypeError: unsupported operand type(s) for *: 'my' and 'your'
>
> That's an error message I can actually do something with. Is there any way
> to get this behavior when I do have a __mul__ method and sometimes return
> NotImplemented?
>
> We're doing most of our development in Python 2.3, if it matters.
This is a bug in Python. See this thread:
http://mail.python.org/pipermail/python-dev/2005-December/059046.html
and this patch:
http://sourceforge.net/tracker/?group_id=5470&atid=305470&func=detail&aid=1390657
for more details.
More information about the Python-list
mailing list