[pypy-svn] r57071 - in pypy/branch/isinstance-refactor/pypy: interpreter interpreter/test objspace/flow

arigo at codespeak.net arigo at codespeak.net
Thu Aug 7 19:01:06 CEST 2008


Author: arigo
Date: Thu Aug  7 19:01:01 2008
New Revision: 57071

Modified:
   pypy/branch/isinstance-refactor/pypy/interpreter/baseobjspace.py
   pypy/branch/isinstance-refactor/pypy/interpreter/error.py
   pypy/branch/isinstance-refactor/pypy/interpreter/function.py
   pypy/branch/isinstance-refactor/pypy/interpreter/test/test_function.py
   pypy/branch/isinstance-refactor/pypy/objspace/flow/objspace.py
Log:
Tests and refactoring.  Some tests fail on the trunk.


Modified: pypy/branch/isinstance-refactor/pypy/interpreter/baseobjspace.py
==============================================================================
--- pypy/branch/isinstance-refactor/pypy/interpreter/baseobjspace.py	(original)
+++ pypy/branch/isinstance-refactor/pypy/interpreter/baseobjspace.py	Thu Aug  7 19:01:01 2008
@@ -655,15 +655,7 @@
         """Checks if the given exception type matches 'w_check_class'."""
         if self.is_w(w_exc_type, w_check_class):
             return True
-        if self.is_true(self.abstract_issubclass(w_exc_type, w_check_class)):
-            return True
-
-        if self.is_true(self.isinstance(w_check_class, self.w_tuple)):
-            exclst_w = self.unpacktuple(w_check_class)
-            for w_e in exclst_w:
-                if self.exception_match(w_exc_type, w_e):
-                    return True
-        return False
+        return self.abstract_issubclass_w(w_exc_type, w_check_class)
 
     def call(self, w_callable, w_args, w_kwds=None):
         args = Arguments.frompacked(self, w_args, w_kwds)
@@ -679,8 +671,8 @@
                     func = w_func.w_function
                     if isinstance(func, Function):
                         return func.funccall(w_inst, *args_w)
-                elif args_w and self.is_true(
-                        self.abstract_isinstance(args_w[0], w_func.w_class)):
+                elif args_w and (
+                        self.abstract_isinstance_w(args_w[0], w_func.w_class)):
                     w_func = w_func.w_function
 
             if isinstance(w_func, Function):
@@ -701,9 +693,9 @@
                     func = w_func.w_function
                     if isinstance(func, Function):
                         return func.funccall_obj_valuestack(w_inst, nargs, frame)
-                elif nargs > 0 and self.is_true(
-                    self.abstract_isinstance(frame.peekvalue(nargs-1),   #    :-(
-                                             w_func.w_class)):
+                elif nargs > 0 and (
+                    self.abstract_isinstance_w(frame.peekvalue(nargs-1),   #    :-(
+                                               w_func.w_class)):
                     w_func = w_func.w_function
 
             if isinstance(w_func, Function):
@@ -755,61 +747,34 @@
         w_objtype = self.type(w_obj)
         return self.issubtype(w_objtype, w_type)
 
-    def abstract_issubclass(self, w_obj, w_cls, failhard=False):
-        try:
-            return self.issubtype(w_obj, w_cls)
-        except OperationError, e:
-            if not e.match(self, self.w_TypeError):
-                raise
-            try:
-                self.getattr(w_cls, self.wrap('__bases__')) # type sanity check
-                return self.recursive_issubclass(w_obj, w_cls)
-            except OperationError, e:
-                if failhard or not (e.match(self, self.w_TypeError) or
-                                    e.match(self, self.w_AttributeError)):
-                    raise
-                else:
-                    return self.w_False
-
-    def recursive_issubclass(self, w_obj, w_cls):
-        if self.is_w(w_obj, w_cls):
-            return self.w_True
-        for w_base in self.unpackiterable(self.getattr(w_obj,
-                                                       self.wrap('__bases__'))):
-            if self.is_true(self.recursive_issubclass(w_base, w_cls)):
-                return self.w_True
-        return self.w_False
-
-    def abstract_isinstance(self, w_obj, w_cls):
-        try:
-            return self.isinstance(w_obj, w_cls)
-        except OperationError, e:
-            if not e.match(self, self.w_TypeError):
-                raise
-            try:
-                w_objcls = self.getattr(w_obj, self.wrap('__class__'))
-                return self.abstract_issubclass(w_objcls, w_cls)
-            except OperationError, e:
-                if not (e.match(self, self.w_TypeError) or
-                        e.match(self, self.w_AttributeError)):
-                    raise
-                return self.w_False
-
-    def abstract_isclass(self, w_obj):
-        if self.is_true(self.isinstance(w_obj, self.w_type)):
-            return self.w_True
-        if self.findattr(w_obj, self.wrap('__bases__')) is not None:
-            return self.w_True
-        else:
-            return self.w_False
+    def abstract_issubclass_w(self, w_cls1, w_cls2):
+        # Equivalent to 'issubclass(cls1, cls2)'.  The code below only works
+        # for the simple case (new-style class, new-style class).
+        # This method is patched with the full logic by the __builtin__
+        # module when it is loaded.
+        return self.unwrap(self.issubtype(w_cls1, w_cls2))
+
+    def abstract_isinstance_w(self, w_obj, w_cls):
+        # Equivalent to 'isinstance(obj, cls)'.  The code below only works
+        # for the simple case (new-style instance, new-style class).
+        # This method is patched with the full logic by the __builtin__
+        # module when it is loaded.
+        return self.unwrap(self.isinstance(w_obj, w_cls))
+
+    def abstract_isclass_w(self, w_obj):
+        # Equivalent to 'isinstance(obj, type)'.  The code below only works
+        # for the simple case (new-style instance without special stuff).
+        # This method is patched with the full logic by the __builtin__
+        # module when it is loaded.
+        return self.unwrap(self.isinstance(w_obj, self.w_type))
 
     def abstract_getclass(self, w_obj):
-        try:
-            return self.getattr(w_obj, self.wrap('__class__'))
-        except OperationError, e:
-            if e.match(self, self.w_TypeError) or e.match(self, self.w_AttributeError):
-                return self.type(w_obj)
-            raise
+        # Equivalent to 'obj.__class__'.  The code below only works
+        # for the simple case (new-style instance without special stuff).
+        # This method is patched with the full logic by the __builtin__
+        # module when it is loaded.
+        return self.type(w_obj)
+
 
     def eval(self, expression, w_globals, w_locals):
         "NOT_RPYTHON: For internal debugging."

Modified: pypy/branch/isinstance-refactor/pypy/interpreter/error.py
==============================================================================
--- pypy/branch/isinstance-refactor/pypy/interpreter/error.py	(original)
+++ pypy/branch/isinstance-refactor/pypy/interpreter/error.py	Thu Aug  7 19:01:01 2008
@@ -151,15 +151,14 @@
             while space.is_true(space.isinstance(w_type, space.w_tuple)):
                 w_type = space.getitem(w_type, space.wrap(0))
 
-        if space.is_true(space.abstract_isclass(w_type)):
+        if space.abstract_isclass_w(w_type):
             if space.is_w(w_value, space.w_None):
                 # raise Type: we assume we have to instantiate Type
                 w_value = space.call_function(w_type)
                 w_type = space.abstract_getclass(w_value)
             else:
                 w_valuetype = space.abstract_getclass(w_value)
-                if space.is_true(space.abstract_issubclass(w_valuetype,
-                                                           w_type)):
+                if space.abstract_issubclass_w(w_valuetype, w_type):
                     # raise Type, Instance: let etype be the exact type of value
                     w_type = w_valuetype
                 else:

Modified: pypy/branch/isinstance-refactor/pypy/interpreter/function.py
==============================================================================
--- pypy/branch/isinstance-refactor/pypy/interpreter/function.py	(original)
+++ pypy/branch/isinstance-refactor/pypy/interpreter/function.py	Thu Aug  7 19:01:01 2008
@@ -343,8 +343,8 @@
         else:
             # unbound method
             w_firstarg = args.firstarg()
-            if w_firstarg is not None and space.is_true(
-                    space.abstract_isinstance(w_firstarg, self.w_class)):
+            if w_firstarg is not None and (
+                    space.abstract_isinstance_w(w_firstarg, self.w_class)):
                 pass  # ok
             else:
                 myname = self.getname(space,"")
@@ -372,7 +372,7 @@
             # only allow binding to a more specific class than before
             if (w_cls is not None and
                 not space.is_w(w_cls, space.w_None) and
-                not space.is_true(space.abstract_issubclass(w_cls, self.w_class))):
+                not space.abstract_issubclass_w(w_cls, self.w_class)):
                 return space.wrap(self)    # subclass test failed
             else:
                 return descr_function_get(space, self.w_function, w_obj, w_cls)

Modified: pypy/branch/isinstance-refactor/pypy/interpreter/test/test_function.py
==============================================================================
--- pypy/branch/isinstance-refactor/pypy/interpreter/test/test_function.py	(original)
+++ pypy/branch/isinstance-refactor/pypy/interpreter/test/test_function.py	Thu Aug  7 19:01:01 2008
@@ -280,6 +280,46 @@
             __metaclass__ = A().foo
         assert Fun[:2] == ('Fun', ())
 
+    def test_unbound_abstract_typecheck(self):
+        import new
+        def f(*args):
+            return args
+        m = new.instancemethod(f, None, "foobar")
+        raises(TypeError, m)
+        raises(TypeError, m, None)
+        raises(TypeError, m, "egg")
+
+        m = new.instancemethod(f, None, (str, int))     # really obscure...
+        assert m(4) == (4,)
+        assert m("uh") == ("uh",)
+        raises(TypeError, m, [])
+
+        class MyBaseInst(object):
+            pass
+        class MyInst(MyBaseInst):
+            def __init__(self, myclass):
+                self.myclass = myclass
+            def __class__(self):
+                if self.myclass is None:
+                    raise AttributeError
+                return self.myclass
+            __class__ = property(__class__)
+        class MyClass(object):
+            pass
+        BBase = MyClass()
+        BSub1 = MyClass()
+        BSub2 = MyClass()
+        BBase.__bases__ = ()
+        BSub1.__bases__ = (BBase,)
+        BSub2.__bases__ = (BBase,)
+        x = MyInst(BSub1)
+        m = new.instancemethod(f, None, BSub1)
+        assert m(x) == (x,)
+        raises(TypeError, m, MyInst(BBase))
+        raises(TypeError, m, MyInst(BSub2))
+        raises(TypeError, m, MyInst(None))
+        raises(TypeError, m, MyInst(42))
+
 
 class TestMethod: 
     def setup_method(self, method):

Modified: pypy/branch/isinstance-refactor/pypy/objspace/flow/objspace.py
==============================================================================
--- pypy/branch/isinstance-refactor/pypy/objspace/flow/objspace.py	(original)
+++ pypy/branch/isinstance-refactor/pypy/objspace/flow/objspace.py	Thu Aug  7 19:01:01 2008
@@ -218,18 +218,6 @@
                 return ecls
         return None
 
-    def abstract_issubclass(self, w_obj, w_cls, failhard=False):
-        return self.issubtype(w_obj, w_cls)
-
-    def abstract_isinstance(self, w_obj, w_cls):
-        return self.isinstance(w_obj, w_cls)
-
-    def abstract_isclass(self, w_obj):
-        return self.isinstance(w_obj, self.w_type)
-
-    def abstract_getclass(self, w_obj):
-        return self.type(w_obj)
-
 
     def build_flow(self, func, constargs={}):
         """



More information about the Pypy-commit mailing list