Author: Armin Rigo <[email protected]>
Branch: 
Changeset: r50663:16d3f098e8ec
Date: 2011-12-18 18:50 +0100
http://bitbucket.org/pypy/pypy/changeset/16d3f098e8ec/

Log:    (reported by amaury)

        Test and fix: proxies used to force too many arguments. They should
        really force the "minimum" number of them, which means "usually 1
        and sometimes 2" based on some half-random rule. Tested against
        CPython.

diff --git a/pypy/module/_weakref/interp__weakref.py 
b/pypy/module/_weakref/interp__weakref.py
--- a/pypy/module/_weakref/interp__weakref.py
+++ b/pypy/module/_weakref/interp__weakref.py
@@ -329,11 +329,16 @@
 special_ops = {'repr': True, 'userdel': True, 'hash': True}
 
 for opname, _, arity, special_methods in ObjSpace.MethodTable:
-    if opname in special_ops:
+    if opname in special_ops or not special_methods:
         continue
     nonspaceargs =  ", ".join(["w_obj%s" % i for i in range(arity)])
     code = "def func(space, %s):\n    '''%s'''\n" % (nonspaceargs, opname)
-    for i in range(arity):
+    assert arity >= len(special_methods)
+    forcing_count = len(special_methods)
+    if opname.startswith('inplace_'):
+        assert arity == 2
+        forcing_count = arity
+    for i in range(forcing_count):
         code += "    w_obj%s = force(space, w_obj%s)\n" % (i, i)
     code += "    return space.%s(%s)" % (opname, nonspaceargs)
     exec py.code.Source(code).compile()
diff --git a/pypy/module/_weakref/test/test_weakref.py 
b/pypy/module/_weakref/test/test_weakref.py
--- a/pypy/module/_weakref/test/test_weakref.py
+++ b/pypy/module/_weakref/test/test_weakref.py
@@ -466,3 +466,44 @@
         # No exception should be raised here
         gc.collect()
 
+    def test_add(self):
+        import _weakref
+        class A(object):
+            def __add__(self, other):
+                return other
+        a1 = A()
+        a2 = A()
+        p1 = _weakref.proxy(a1)
+        p2 = _weakref.proxy(a2)
+        a3 = p1 + p2
+        assert a3 is a2
+
+    def test_inplace_add(self):
+        import _weakref
+        class A(object):
+            def __add__(self, other):
+                return other
+        a1 = A()
+        a2 = A()
+        p1 = _weakref.proxy(a1)
+        p2 = _weakref.proxy(a2)
+        p1 += p2
+        assert p1 is a2
+
+    def test_setattr(self):
+        import _weakref
+        class A(object):
+            def __setitem__(self, key, value):
+                self.setkey = key
+                self.setvalue = value
+        a1 = A()
+        a2 = A()
+        p1 = _weakref.proxy(a1)
+        p2 = _weakref.proxy(a2)
+        p1[p2] = 42
+        assert a1.setkey is p2
+        assert a1.setvalue == 42
+        #
+        p1[42] = p2
+        assert a1.setkey == 42
+        assert a1.setvalue is p2
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to