[pypy-svn] r11731 - in pypy/dist/pypy: interpreter objspace/std objspace/std/test

pedronis at codespeak.net pedronis at codespeak.net
Sun May 1 22:22:12 CEST 2005


Author: pedronis
Date: Sun May  1 22:22:11 2005
New Revision: 11731

Modified:
   pypy/dist/pypy/interpreter/baseobjspace.py
   pypy/dist/pypy/interpreter/function.py
   pypy/dist/pypy/objspace/std/test/test_instmethobject.py
   pypy/dist/pypy/objspace/std/typeobject.py
Log:
- added W_Root.getname(space) to uniformely access the name(__name__) of objects

- unbound method error message more complete and better approximating CPython's one



Modified: pypy/dist/pypy/interpreter/baseobjspace.py
==============================================================================
--- pypy/dist/pypy/interpreter/baseobjspace.py	(original)
+++ pypy/dist/pypy/interpreter/baseobjspace.py	Sun May  1 22:22:11 2005
@@ -23,11 +23,19 @@
                 if not e.match(space, space.w_KeyError):
                     raise
         return None
-
     
     def getclass(self, space):
         return space.gettypeobject(self.typedef)
 
+    def getname(self, space, default):
+        try:
+            return space.str_w(space.getattr(self, space.wrap('__name__')))
+        except OperationError, e:
+            if e.match(space, space.w_TypeError) or e.match(space, space.w_AttributeError):
+                return default
+            raise
+                            
+
 class BaseWrappable(W_Root):
     """A subclass of BaseWrappable is an internal, interpreter-level class
     that can nevertheless be exposed at application-level by space.wrap()."""
@@ -286,7 +294,6 @@
     def abstract_getclass(self, w_obj):
         return self.getattr(w_obj, self.wrap('__class__'))
 
-
     def eval(self, expression, w_globals, w_locals):
         "NOT_RPYTHON: For internal debugging."
         import types

Modified: pypy/dist/pypy/interpreter/function.py
==============================================================================
--- pypy/dist/pypy/interpreter/function.py	(original)
+++ pypy/dist/pypy/interpreter/function.py	Sun May  1 22:22:11 2005
@@ -121,6 +121,13 @@
             w_res = space.w_None
         return w_res
 
+def _getclass(space, w_obj):
+    try:
+        return space.abstract_getclass(w_obj)
+    except OperationError, e:
+        if e.match(space, space.w_AttributeError):
+            return space.type(w_obj)
+        raise
 
 class Method(Wrappable): 
     """A method is a function bound to a specific instance or class."""
@@ -146,21 +153,33 @@
         return "%s method %s" % (pre, self.w_function.name)
 
     def call_args(self, args):
+        space = self.space
         if self.w_instance is not None:
             # bound method
             args = args.prepend(self.w_instance)
         else:
             # unbound method
             w_firstarg = args.firstarg()
-            if w_firstarg is not None and self.space.is_true(
-                    self.space.abstract_isinstance(w_firstarg, self.w_class)):
+            if w_firstarg is not None and space.is_true(
+                    space.abstract_isinstance(w_firstarg, self.w_class)):
                 pass  # ok
             else:
-                msg = ("unbound method must be called with "
-                       "instance as first argument")     # XXX fix error msg
-                raise OperationError(self.space.w_TypeError,
-                                     self.space.wrap(msg))
-        return self.space.call_args(self.w_function, args)
+                myname = self.getname(space,"")
+                clsdescr = self.w_class.getname(space,"")
+                if clsdescr:
+                    clsdescr+=" "
+                if w_firstarg is None:
+                    instdescr = "nothing"
+                else:
+                    instname = _getclass(space, w_firstarg).getname(space,"")
+                    if instname:
+                        instname += " "
+                    instdescr = "%sinstance" %instname
+                msg = ("unbound method %s() must be called with %s"
+                       "instance as first argument (got %s instead)")  % (myname, clsdescr, instdescr) 
+                raise OperationError(space.w_TypeError,
+                                     space.wrap(msg))
+        return space.call_args(self.w_function, args)
 
     def descr_method_get(self, w_obj, w_cls=None):
         space = self.space

Modified: pypy/dist/pypy/objspace/std/test/test_instmethobject.py
==============================================================================
--- pypy/dist/pypy/objspace/std/test/test_instmethobject.py	(original)
+++ pypy/dist/pypy/objspace/std/test/test_instmethobject.py	Sun May  1 22:22:11 2005
@@ -17,6 +17,14 @@
         raises(TypeError, unboundMethod, 333)
         raises(TypeError, unboundMethod, [1,2,3], 333)
 
+    def test_err_format(self):
+        class C(object):
+            def m(self): pass
+        try:
+            C.m(1)
+        except TypeError, e:
+            assert str(e) == 'unbound method m() must be called with C instance as first argument (got int instance instead)'
+
     def test_getBound(self):
         def f(l,x): return l[x+1]
         bound = f.__get__('abcdef')

Modified: pypy/dist/pypy/objspace/std/typeobject.py
==============================================================================
--- pypy/dist/pypy/objspace/std/typeobject.py	(original)
+++ pypy/dist/pypy/objspace/std/typeobject.py	Sun May  1 22:22:11 2005
@@ -358,7 +358,7 @@
     if candidate in orderlists[-1][1:]:
         # explicit error message for this specific case
         raise OperationError(space.w_TypeError,
-            space.wrap("duplicate base class " + _getname(space, candidate)))
+            space.wrap("duplicate base class " + candidate.getname(space,"?")))
     while candidate not in cycle:
         cycle.append(candidate)
         nextblockinglist = mro_blockinglist(candidate, orderlists)
@@ -366,7 +366,7 @@
     del cycle[:cycle.index(candidate)]
     cycle.append(candidate)
     cycle.reverse()
-    names = [_getname(space, cls) for cls in cycle]
+    names = [cls.getname(space, "?") for cls in cycle]
     raise OperationError(space.w_TypeError,
         space.wrap("cycle among base classes: " + ' < '.join(names)))
 



More information about the Pypy-commit mailing list