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

arigo at codespeak.net arigo at codespeak.net
Sun Mar 11 09:13:09 CET 2007


Author: arigo
Date: Sun Mar 11 09:13:06 2007
New Revision: 40193

Modified:
   pypy/dist/pypy/interpreter/baseobjspace.py
   pypy/dist/pypy/interpreter/gateway.py
   pypy/dist/pypy/interpreter/test/test_gateway.py
   pypy/dist/pypy/interpreter/test/test_objspace.py
   pypy/dist/pypy/objspace/cpy/function.py
   pypy/dist/pypy/objspace/std/listtype.py
   pypy/dist/pypy/objspace/std/objspace.py
   pypy/dist/pypy/objspace/std/rangeobject.py
   pypy/dist/pypy/objspace/std/ropeobject.py
   pypy/dist/pypy/objspace/std/slicetype.py
   pypy/dist/pypy/objspace/std/stringobject.py
   pypy/dist/pypy/objspace/std/strsliceobject.py
   pypy/dist/pypy/objspace/std/tupleobject.py
   pypy/dist/pypy/objspace/std/unicodeobject.py
Log:
Details about __index__:

* gateways should not clamp by default, but raise
  OverflowError

* make w_exception=None be no longer a default argument,
  to avoid clamping-by-surprize if we forget it

* better hack (maybe) for the bootstrap issue in
  getitem__Tuple_ANY()

* unified the way error messages are built

* (unrelated) 'int * unicode' should not use space.mul()


Modified: pypy/dist/pypy/interpreter/baseobjspace.py
==============================================================================
--- pypy/dist/pypy/interpreter/baseobjspace.py	(original)
+++ pypy/dist/pypy/interpreter/baseobjspace.py	Sun Mar 11 09:13:06 2007
@@ -795,12 +795,23 @@
             step  = 0
         return start, stop, step
 
-    def getindex_w(self, w_obj, w_exception=None):
+    def getindex_w(self, w_obj, w_exception, objdescr=None):
+        """Return w_obj.__index__() as an RPython int.
+        If w_exception is None, silently clamp in case of overflow;
+        else raise w_exception.
+        """
         # shortcut for int objects
         if self.is_w(self.type(w_obj), self.w_int):
             return self.int_w(w_obj)
 
-        w_index = self.index(w_obj)
+        try:
+            w_index = self.index(w_obj)
+        except OperationError, err:
+            if objdescr is None or not err.match(self, self.w_TypeError):
+                raise
+            msg = "%s must be an integer, not %s" % (
+                objdescr, self.type(w_obj).getname(self, '?'))
+            raise OperationError(self.w_TypeError, self.wrap(msg))
         try:
             index = self.int_w(w_index)
         except OperationError, err:

Modified: pypy/dist/pypy/interpreter/gateway.py
==============================================================================
--- pypy/dist/pypy/interpreter/gateway.py	(original)
+++ pypy/dist/pypy/interpreter/gateway.py	Sun Mar 11 09:13:06 2007
@@ -107,11 +107,11 @@
     def visit_self(self, cls, app_sig):
         self.visit__Wrappable(cls, app_sig)
 
-    def checked_space_method(self, typ, app_sig):
+    def checked_space_method(self, typname, app_sig):
         argname = self.orig_arg()
         assert not argname.startswith('w_'), (
             "unwrapped %s argument %s of built-in function %r should "
-            "not start with 'w_'" % (typ.__name__, argname, self.func))
+            "not start with 'w_'" % (typname, argname, self.func))
         app_sig.append(argname)
 
     def visit_index(self, index, app_sig):
@@ -164,7 +164,7 @@
     def visit__object(self, typ, app_sig):
         if typ not in (int, str, float):
             assert False, "unsupported basic type in unwrap_spec"
-        self.checked_space_method(typ, app_sig)
+        self.checked_space_method(typ.__name__, app_sig)
 
 
 class UnwrapSpec_EmitRun(UnwrapSpecEmit):
@@ -214,7 +214,8 @@
                              (typ.__name__, self.scopenext()))
 
     def visit_index(self, typ):
-        self.run_args.append("space.getindex_w(%s)" % (self.scopenext(), ))
+        self.run_args.append("space.getindex_w(%s, space.w_OverflowError)"
+                             % (self.scopenext(), ))
 
     def _make_unwrap_activation_class(self, unwrap_spec, cache={}):
         try:
@@ -326,7 +327,8 @@
                                                self.nextarg()))
 
     def visit_index(self, typ):
-        self.unwrap.append("space.getindex_w(%s)" % (self.nextarg()), )
+        self.unwrap.append("space.getindex_w(%s, space.w_OverflowError)"
+                           % (self.nextarg()), )
 
     def make_fastfunc(unwrap_spec, func):
         unwrap_info = UnwrapSpec_FastFunc_Unwrap()

Modified: pypy/dist/pypy/interpreter/test/test_gateway.py
==============================================================================
--- pypy/dist/pypy/interpreter/test/test_gateway.py	(original)
+++ pypy/dist/pypy/interpreter/test/test_gateway.py	Sun Mar 11 09:13:06 2007
@@ -209,6 +209,27 @@
             space.call_function(w_app_g3_if, w(1), w(1.0)),
             w(2.0))
 
+    def test_interp2app_unwrap_spec_index(self):
+        space = self.space
+        w = space.wrap
+        def g3_idx(space, idx0):
+            return space.wrap(idx0 + 1)
+        app_g3_idx = gateway.interp2app_temp(g3_idx,
+                                         unwrap_spec=[gateway.ObjSpace,
+                                                      'index'])
+        w_app_g3_idx = space.wrap(app_g3_idx) 
+        assert space.eq_w(
+            space.call_function(w_app_g3_idx, w(123)),
+            w(124))
+        space.raises_w(space.w_OverflowError,
+                       space.call_function,
+                       w_app_g3_idx,
+                       space.mul(space.wrap(sys.maxint), space.wrap(7)))
+        space.raises_w(space.w_OverflowError,
+                       space.call_function,
+                       w_app_g3_idx,
+                       space.mul(space.wrap(sys.maxint), space.wrap(-7)))
+
     def test_interp2app_unwrap_spec_typechecks(self):
         space = self.space
         w = space.wrap

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	Sun Mar 11 09:13:06 2007
@@ -1,4 +1,5 @@
 from py.test import raises
+from pypy.interpreter.error import OperationError
 from pypy.interpreter.function import Function
 from pypy.interpreter.pycode import PyCode
 import sys
@@ -149,12 +150,19 @@
             class Y(object):
                 def __index__(self): return 2**70
             return Y()""")
-        first = self.space.getindex_w(w_instance1)
+        first = self.space.getindex_w(w_instance1, None)
         assert first == 42
-        second = self.space.getindex_w(w_instance2)
+        second = self.space.getindex_w(w_instance2, None)
         assert second == sys.maxint
         self.space.raises_w(self.space.w_IndexError,
                             self.space.getindex_w, w_instance2, self.space.w_IndexError)
+        try:
+            self.space.getindex_w(self.space.w_tuple, None, "foobar")
+        except OperationError, e:
+            assert e.match(self.space, self.space.w_TypeError)
+            assert "foobar" in e.errorstr(self.space)
+        else:
+            assert 0, "should have raised"
 
 
 class TestModuleMinimal: 

Modified: pypy/dist/pypy/objspace/cpy/function.py
==============================================================================
--- pypy/dist/pypy/objspace/cpy/function.py	(original)
+++ pypy/dist/pypy/objspace/cpy/function.py	Sun Mar 11 09:13:06 2007
@@ -53,7 +53,6 @@
         convertermap = {int: 'int_w',
                         str: 'str_w',
                         float: 'float_w',
-                        "index": 'getindex_w'
                         }
         argname = self.orig_arg()
         assert not argname.startswith('w_')
@@ -65,7 +64,14 @@
         self.passedargs.append(argname)
 
     def visit_index(self, el):
-        self.visit__object("index")
+        argname = self.orig_arg()
+        assert not argname.startswith('w_')
+        self.inputargs.append(argname)
+        self.wrappings.append('%s = ___space.getindex_w(___W_Object(%s),'
+                              ' ___space.w_OverflowError)' %
+                               (argname,
+                                argname))
+        self.passedargs.append(argname)
 
     def visit_args_w(self, el):
         argname = self.orig_arg()

Modified: pypy/dist/pypy/objspace/std/listtype.py
==============================================================================
--- pypy/dist/pypy/objspace/std/listtype.py	(original)
+++ pypy/dist/pypy/objspace/std/listtype.py	Sun Mar 11 09:13:06 2007
@@ -66,9 +66,4 @@
 # ____________________________________________________________
 
 def get_list_index(space, w_index):
-    if not space.lookup(w_index, '__index__'):
-        raise OperationError(
-            space.w_TypeError,
-            space.wrap("list indices must be integers, not %s" %
-                       space.type(w_index).getname(space, '?')))
-    return space.getindex_w(w_index, space.w_IndexError)
+    return space.getindex_w(w_index, space.w_IndexError, "list index")

Modified: pypy/dist/pypy/objspace/std/objspace.py
==============================================================================
--- pypy/dist/pypy/objspace/std/objspace.py	(original)
+++ pypy/dist/pypy/objspace/std/objspace.py	Sun Mar 11 09:13:06 2007
@@ -627,7 +627,7 @@
     if space.is_w(w_start, space.w_None):
         w_start = space.wrap(0)
     else:
-        w_start = space.wrap(space.getindex_w(w_start))
+        w_start = space.wrap(space.getindex_w(w_start, None))
         if space.is_true(space.lt(w_start, space.wrap(0))):
             w_start = space.add(w_start, space.len(w_obj))
             # NB. the language ref is inconsistent with the new-style class
@@ -636,7 +636,7 @@
     if space.is_w(w_stop, space.w_None):
         w_stop = space.wrap(slice_max)
     else:
-        w_stop = space.wrap(space.getindex_w(w_stop))
+        w_stop = space.wrap(space.getindex_w(w_stop, None))
         if space.is_true(space.lt(w_stop, space.wrap(0))):
             w_stop = space.add(w_stop, space.len(w_obj))
     return w_start, w_stop

Modified: pypy/dist/pypy/objspace/std/rangeobject.py
==============================================================================
--- pypy/dist/pypy/objspace/std/rangeobject.py	(original)
+++ pypy/dist/pypy/objspace/std/rangeobject.py	Sun Mar 11 09:13:06 2007
@@ -78,7 +78,7 @@
 def getitem__RangeList_ANY(space, w_rangelist, w_index):
     if w_rangelist.w_list is not None:
         return space.getitem(w_rangelist.w_list, w_index)
-    idx = space.getindex_w(w_index, space.w_IndexError)
+    idx = space.getindex_w(w_index, space.w_IndexError, "list index")
     try:
         return wrapint(space, w_rangelist.getitem(idx))
     except IndexError:

Modified: pypy/dist/pypy/objspace/std/ropeobject.py
==============================================================================
--- pypy/dist/pypy/objspace/std/ropeobject.py	(original)
+++ pypy/dist/pypy/objspace/std/ropeobject.py	Sun Mar 11 09:13:06 2007
@@ -897,12 +897,7 @@
     return space.newbool(rope.compare(n1, n2) >= 0)
 
 def getitem__Rope_ANY(space, w_str, w_index):
-    if not space.lookup(w_index, '__index__'):
-        raise OperationError(
-            space.w_TypeError,
-            space.wrap("string indices must be integers, not %s" %
-                       space.type(w_index).getname(space, '?')))
-    ival = space.getindex_w(w_index, space.w_IndexError)
+    ival = space.getindex_w(w_index, space.w_IndexError, "string index")
     node = w_str._node
     slen = node.length()
     if ival < 0:

Modified: pypy/dist/pypy/objspace/std/slicetype.py
==============================================================================
--- pypy/dist/pypy/objspace/std/slicetype.py	(original)
+++ pypy/dist/pypy/objspace/std/slicetype.py	Sun Mar 11 09:13:06 2007
@@ -16,7 +16,7 @@
 # utility functions
 def _Eval_SliceIndex(space, w_int):
     try:
-        return space.getindex_w(w_int) # clamp if long integer is too large
+        return space.getindex_w(w_int, None) # clamp if long integer too large
     except OperationError, err:
         if not err.match(space, space.w_TypeError):
             raise

Modified: pypy/dist/pypy/objspace/std/stringobject.py
==============================================================================
--- pypy/dist/pypy/objspace/std/stringobject.py	(original)
+++ pypy/dist/pypy/objspace/std/stringobject.py	Sun Mar 11 09:13:06 2007
@@ -749,12 +749,7 @@
         return space.w_False
 
 def getitem__String_ANY(space, w_str, w_index):
-    if not space.lookup(w_index, '__index__'):
-        raise OperationError(
-            space.w_TypeError,
-            space.wrap("string indices must be integers, not %s" %
-                       space.type(w_index).getname(space, '?')))
-    ival = space.getindex_w(w_index, space.w_IndexError)
+    ival = space.getindex_w(w_index, space.w_IndexError, "string index")
     str = w_str._value
     slen = len(str)
     if ival < 0:

Modified: pypy/dist/pypy/objspace/std/strsliceobject.py
==============================================================================
--- pypy/dist/pypy/objspace/std/strsliceobject.py	(original)
+++ pypy/dist/pypy/objspace/std/strsliceobject.py	Sun Mar 11 09:13:06 2007
@@ -167,12 +167,7 @@
 
 
 def getitem__StringSlice_ANY(space, w_str, w_index):
-    if not space.lookup(w_index, '__index__'):
-        raise OperationError(
-            space.w_TypeError,
-            space.wrap("string indices must be integers, not %s" %
-                       space.type(w_index).getname(space, '?')))
-    ival = space.getindex_w(w_index, space.w_IndexError)
+    ival = space.getindex_w(w_index, space.w_IndexError, "string index")
     slen = w_str.stop - w_str.start
     if ival < 0:
         ival += slen

Modified: pypy/dist/pypy/objspace/std/tupleobject.py
==============================================================================
--- pypy/dist/pypy/objspace/std/tupleobject.py	(original)
+++ pypy/dist/pypy/objspace/std/tupleobject.py	Sun Mar 11 09:13:06 2007
@@ -28,15 +28,15 @@
     return wrapint(space, result)
 
 def getitem__Tuple_ANY(space, w_tuple, w_index):
-    if not space.lookup(w_index, '__index__'):
-        raise OperationError(
-            space.w_TypeError,
-            space.wrap("tuple indices must be integers, not %s" %
-                       space.type(w_index).getname(space, '?')))
+    # getindex_w should get a second argument space.w_IndexError,
+    # but that doesn't exist the first time this is called.
     try:
-        # XXX: getindex_w should get a second argument space.w_IndexError,
-        #      but that doesn't exist the first time this is called.
-        return w_tuple.wrappeditems[space.getindex_w(w_index)]
+        w_IndexError = space.w_IndexError
+    except AttributeError:
+        w_IndexError = None
+    index = space.getindex_w(w_index, w_IndexError, "tuple index")
+    try:
+        return w_tuple.wrappeditems[index]
     except IndexError:
         raise OperationError(space.w_IndexError,
                              space.wrap("tuple index out of range"))

Modified: pypy/dist/pypy/objspace/std/unicodeobject.py
==============================================================================
--- pypy/dist/pypy/objspace/std/unicodeobject.py	(original)
+++ pypy/dist/pypy/objspace/std/unicodeobject.py	Sun Mar 11 09:13:06 2007
@@ -221,12 +221,7 @@
     return space.wrap(len(w_uni._value))
 
 def getitem__Unicode_ANY(space, w_uni, w_index):
-    if not space.lookup(w_index, '__index__'):
-        raise OperationError(
-            space.w_TypeError,
-            space.wrap("string indices must be integers, not %s" %
-                       space.type(w_index).getname(space, '?')))
-    ival = space.getindex_w(w_index, space.w_IndexError)
+    ival = space.getindex_w(w_index, space.w_IndexError, "string index")
     uni = w_uni._value
     ulen = len(uni)
     if ival < 0:
@@ -251,9 +246,14 @@
     return W_UnicodeObject(r)
 
 def mul__Unicode_ANY(space, w_uni, w_times):
+    try:
+        times = space.getindex_w(w_times, space.w_OverflowError)
+    except OperationError, e:
+        if e.match(space, space.w_TypeError):
+            raise FailedToImplement
+        raise
     chars = w_uni._value
     charlen = len(chars)
-    times = space.getindex_w(w_times, space.w_OverflowError)
     if times <= 0 or charlen == 0:
         return W_UnicodeObject([])
     if times == 1:
@@ -273,7 +273,7 @@
     return W_UnicodeObject(result)
 
 def mul__ANY_Unicode(space, w_times, w_uni):
-    return space.mul(w_uni, w_times)
+    return mul__Unicode_ANY(space, w_uni, w_times)
 
 def _isspace(uchar):
     return unicodedb.isspace(ord(uchar))



More information about the Pypy-commit mailing list