[Python-bugs-list] [ python-Bugs-461546 ] bug in long_mul

noreply@sourceforge.net noreply@sourceforge.net
Sat, 15 Sep 2001 08:36:44 -0700


Bugs item #461546, was opened at 2001-09-14 07:18
You can respond by visiting: 
http://sourceforge.net/tracker/?func=detail&atid=105470&aid=461546&group_id=5470

Category: Type/class unification
Group: Python 2.2
>Status: Closed
>Resolution: Fixed
Priority: 5
Submitted By: Guido van Rossum (gvanrossum)
Assigned to: Guido van Rossum (gvanrossum)
Summary: bug in long_mul

Initial Comment:
Here's a strange exception:

>>> class C(long):
    __dynamic__ = 1

>>> c = C(1)
>>> c*1
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
SystemError: ../Objects/longobject.c:186: bad argument
to internal function
>>> 1*c
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
SystemError: ../Objects/longobject.c:186: bad argument
to internal function
>>> 

If I change __dynamic__ to 0, all's well:

>>> class C(long):
    __dynamic__ = 0

>>> c = C(1)
>>> c*1
1L
>>> 1*c
1L
>>> 


----------------------------------------------------------------------

>Comment By: Guido van Rossum (gvanrossum)
Date: 2001-09-15 08:36

Message:
Logged In: YES 
user_id=6380

Fixed now (also for ints).

----------------------------------------------------------------------

Comment By: Tim Peters (tim_one)
Date: 2001-09-14 12:56

Message:
Logged In: YES 
user_id=31435

I don't really understand __dynamic__ yet, but I bet this 
will be clear(er) to you:

The cause is that long_mul is trying to figure out whether 
this is multiplication or sequence repetition.  Simplify 
this by considering c*2L (which also blows up).  The LHS 
has a non-NULL v->ob_type->tp_as_sequence->sq_repeat slot, 
so long_mul incorrectly decides this *is* sequence 
repetition.

One call to PyLong_AsLong completes, in long_repeat, 
getting the value 2 (the RHS).  Then the LHS v->ob_type-
>tp_as_sequence->sq_repeat is called.  Then we end up in 
some macro, go thru some code it looks like you just 
checked in (lookup_maybe and PyObject_Call), and end up 
passing the Python int (not long) form of 2 to 
PyLong_AsLong.  That's why it complains -- it was passed an 
int rather than a long.

But we were really hosed at the start of this, when 
deciding this is sequence repetition rather than 
multiplication.  When __dynamic__ is 0, the v->ob_type-
>tp_as_sequence slot is NULL, so long_mul never tries to 
treat this as sequence repetition.

----------------------------------------------------------------------

You can respond by visiting: 
http://sourceforge.net/tracker/?func=detail&atid=105470&aid=461546&group_id=5470