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

nik at codespeak.net nik at codespeak.net
Fri Feb 17 16:47:24 CET 2006


Author: nik
Date: Fri Feb 17 16:47:22 2006
New Revision: 23454

Modified:
   pypy/dist/pypy/interpreter/baseobjspace.py
   pypy/dist/pypy/interpreter/test/test_objspace.py
Log:
added callable helper method to baseobjspace. maybe this could also live
somewhere else, some place for general interp level helpers.


Modified: pypy/dist/pypy/interpreter/baseobjspace.py
==============================================================================
--- pypy/dist/pypy/interpreter/baseobjspace.py	(original)
+++ pypy/dist/pypy/interpreter/baseobjspace.py	Fri Feb 17 16:47:22 2006
@@ -520,6 +520,26 @@
         w_meth = self.getattr(w_obj, self.wrap(methname))
         return self.call_function(w_meth, *arg_w)
 
+    def callable(self, w_obj):
+        w_type = self.type(w_obj)
+        w_mro = self.getattr(w_type, self.wrap("__mro__"))
+        for w_supertype in self.unpackiterable(w_mro):
+            w_dict = self.getattr(w_supertype, self.wrap("__dict__"))
+            if self.is_true(
+                    self.call_method(w_dict, "has_key", self.wrap("__call__"))):
+                w_is_oldstyle = self.isinstance(w_obj, self.w_instance)
+                if self.is_true(w_is_oldstyle):
+                    # ugly old style class special treatment, but well ...
+                    try:
+                        self.getattr(w_obj, self.wrap("__call__"))
+                        return self.w_True
+                    except OperationError, e:
+                        if not e.match(self, self.w_AttributeError):
+                            raise
+                        return self.w_False
+                return self.w_True
+        return self.w_False
+
     def isinstance(self, w_obj, w_type):
         w_objtype = self.type(w_obj)
         return self.issubtype(w_objtype, w_type)

Modified: pypy/dist/pypy/interpreter/test/test_objspace.py
==============================================================================
--- pypy/dist/pypy/interpreter/test/test_objspace.py	(original)
+++ pypy/dist/pypy/interpreter/test/test_objspace.py	Fri Feb 17 16:47:22 2006
@@ -89,6 +89,37 @@
         assert not self.space.exception_match(self.space.w_ValueError,
                                                self.space.w_LookupError)
 
+    def test_callable(self):
+        def is_callable(w_obj):
+            return self.space.is_true(self.space.callable(w_obj))
+
+        assert is_callable(self.space.w_int)
+        assert not is_callable(self.space.wrap(1))
+        w_func = self.space.appexec([], "():\n def f(): pass\n return f")
+        assert is_callable(w_func)
+        w_lambda_func = self.space.appexec([], "(): return lambda: True")
+        assert is_callable(w_lambda_func)
+        
+        w_instance = self.space.appexec([], """():
+            class Call(object):
+                def __call__(self): pass
+            return Call()""")
+        assert is_callable(w_instance)
+
+        w_instance = self.space.appexec([],
+                "():\n class NoCall(object): pass\n return NoCall()")
+        assert not is_callable(w_instance)
+        self.space.setattr(w_instance, self.space.wrap("__call__"), w_func)
+        assert not is_callable(w_instance)
+
+        w_oldstyle = self.space.appexec([], """():
+            class NoCall:
+                __metaclass__ = _classobj
+            return NoCall()""")
+        assert not is_callable(w_oldstyle)
+        self.space.setattr(w_oldstyle, self.space.wrap("__call__"), w_func)
+        assert is_callable(w_oldstyle)
+
     def test_interp_w(self):
         w = self.space.wrap
 	w_bltinfunction = self.space.builtin.get('len')



More information about the Pypy-commit mailing list