From e8fc640349dee549e4804df643cf6653a954e125 Mon Sep 17 00:00:00 2001
From: Guido van Rossum <guido@python.org>
Date: Tue, 16 Apr 2002 16:44:51 +0000
Subject: SF bug 544647.

PyNumber_InPlaceMultiply insisted on calling sq_inplace_repeat if it
existed, even if nb_inplace_multiply also existed and the arguments
weren't right for sq_inplace_repeat.  Change this to only use
sq_inplace_repeat if nb_inplace_multiply isn't defined.

Bugfix candidate.
---
 Lib/test/test_descr.py | 27 +++++++++++++++++++++++++++
 Objects/abstract.c     |  8 ++++++--
 2 files changed, 33 insertions(+), 2 deletions(-)

diff --git a/Lib/test/test_descr.py b/Lib/test/test_descr.py
index 3e3424a..fc5f2ea 100644
--- a/Lib/test/test_descr.py
+++ b/Lib/test/test_descr.py
@@ -2929,6 +2929,32 @@ def funnynew():
     vereq(isinstance(d, D), True)
     vereq(d.foo, 1)
 
+def imulbug():
+    # SF bug 544647
+    if verbose: print "Testing for __imul__ problems..."
+    class C(object):
+        def __imul__(self, other):
+            return (self, other)
+    x = C()
+    y = x
+    y *= 1.0
+    vereq(y, (x, 1.0))
+    y = x
+    y *= 2
+    vereq(y, (x, 2))
+    y = x
+    y *= 3L
+    vereq(y, (x, 3L))
+    y = x
+    y *= 1L<<100
+    vereq(y, (x, 1L<<100))
+    y = x
+    y *= None
+    vereq(y, (x, None))
+    y = x
+    y *= "foo"
+    vereq(y, (x, "foo"))
+
 def test_main():
     class_docstrings()
     lists()
@@ -2992,6 +3018,7 @@ def test_main():
     dictproxyiteritems()
     pickleslots()
     funnynew()
+    imulbug()
     if verbose: print "All OK"
 
 if __name__ == "__main__":
diff --git a/Objects/abstract.c b/Objects/abstract.c
index cb2807d..622e819 100644
--- a/Objects/abstract.c
+++ b/Objects/abstract.c
@@ -742,8 +742,12 @@ PyObject *
 PyNumber_InPlaceMultiply(PyObject *v, PyObject *w)
 {
 	PyObject * (*g)(PyObject *, int) = NULL;
-	if (HASINPLACE(v) && v->ob_type->tp_as_sequence &&
-		(g = v->ob_type->tp_as_sequence->sq_inplace_repeat)) {
+	if (HASINPLACE(v) &&
+	    v->ob_type->tp_as_sequence &&
+	    (g = v->ob_type->tp_as_sequence->sq_inplace_repeat) &&
+	    !(v->ob_type->tp_as_number &&
+	      v->ob_type->tp_as_number->nb_inplace_multiply))
+	{
 		long n;
 		if (PyInt_Check(w)) {
 			n  = PyInt_AsLong(w);
-- 
cgit v0.12

