[pypy-svn] r38515 - in pypy/dist/pypy/interpreter: . test

arigo at codespeak.net arigo at codespeak.net
Sun Feb 11 20:37:17 CET 2007


Author: arigo
Date: Sun Feb 11 20:37:15 2007
New Revision: 38515

Modified:
   pypy/dist/pypy/interpreter/baseobjspace.py
   pypy/dist/pypy/interpreter/test/test_function.py
Log:
(pedronis, arigo)

Fix the shortcut paths: for unbound methods, it was bypassing the
check that the 1st argument is of the correct class.


Modified: pypy/dist/pypy/interpreter/baseobjspace.py
==============================================================================
--- pypy/dist/pypy/interpreter/baseobjspace.py	(original)
+++ pypy/dist/pypy/interpreter/baseobjspace.py	Sun Feb 11 20:37:15 2007
@@ -578,7 +578,8 @@
                 func = w_func.w_function
                 if isinstance(func, Function):
                     return func.funccall(w_inst, *args_w)
-            else:
+            elif args_w and self.is_true(
+                    self.abstract_isinstance(args_w[0], w_func.w_class)):
                 w_func = w_func.w_function
 
         if isinstance(w_func, Function):
@@ -597,7 +598,9 @@
                 func = w_func.w_function
                 if isinstance(func, Function):
                     return func.funccall_obj_valuestack(w_inst, nargs, frame)
-            else:
+            elif nargs > 0 and self.is_true(
+                self.abstract_isinstance(frame.peekvalue(nargs-1),   #    :-(
+                                         w_func.w_class)):
                 w_func = w_func.w_function
 
         if isinstance(w_func, Function):

Modified: pypy/dist/pypy/interpreter/test/test_function.py
==============================================================================
--- pypy/dist/pypy/interpreter/test/test_function.py	(original)
+++ pypy/dist/pypy/interpreter/test/test_function.py	Sun Feb 11 20:37:15 2007
@@ -254,6 +254,29 @@
         im = new.instancemethod(A(), 3)
         assert map(im, [4]) == [7]
 
+    def test_unbound_typecheck(self):
+        class A(object):
+            def foo(self, *args):
+                return args
+        class B(A):
+            pass
+        class C(A):
+            pass
+
+        assert A.foo(A(), 42) == (42,)
+        assert A.foo(B(), 42) == (42,)
+        raises(TypeError, A.foo, 5)
+        raises(TypeError, B.foo, C())
+        try:
+            class Fun:
+                __metaclass__ = A.foo
+            assert 0  # should have raised
+        except TypeError:
+            pass
+        class Fun:
+            __metaclass__ = A().foo
+        assert Fun[:2] == ('Fun', ())
+
 
 class TestMethod: 
     def setup_method(self, method):



More information about the Pypy-commit mailing list