1. Florian Hahn
  2. pypy

Commits

Armin Rigo  committed 464ddfa Merge

merge heads

  • Participants
  • Parent commits a57f077, 6349cca
  • Branches default

Comments (0)

Files changed (30)

File pypy/config/pypyoption.py

View file
     del working_modules["termios"]
     del working_modules["_minimal_curses"]
 
-    del working_modules["cppyy"]  # not tested on win32
+    if "cppyy" in working_modules:
+        del working_modules["cppyy"]  # not tested on win32
 
     # The _locale module is needed by site.py on Windows
     default_modules["_locale"] = None
     del working_modules["_minimal_curses"]
     del working_modules["termios"]
     del working_modules["_multiprocessing"]   # depends on rctime
-    del working_modules["cppyy"]  # depends on ctypes
+    if "cppyy" in working_modules:
+        del working_modules["cppyy"]  # depends on ctypes
 
 
 module_dependencies = {

File pypy/doc/whatsnew-head.rst

View file
 
 .. branch: remove-tuple-smm
 Remove multi-methods on tuple
+
+.. branch: remove-iter-smm
+Remove multi-methods on iterators

File pypy/module/micronumpy/arrayimpl/concrete.py

View file
 from rpython.rtyper.lltypesystem import rffi, lltype
 from rpython.rlib.rawstorage import free_raw_storage, raw_storage_getitem,\
      raw_storage_setitem, RAW_STORAGE
-from pypy.module.micronumpy.arrayimpl.sort import argsort_array
 from rpython.rlib.debug import make_sure_not_resized
 
 
             new_backstrides = [0] * ndims
             for nd in range(ndims):
                 new_backstrides[nd] = (new_shape[nd] - 1) * new_strides[nd]
+            assert isinstance(orig_array, W_NDimArray) or orig_array is None
             return SliceArray(self.start, new_strides, new_backstrides,
                               new_shape, self, orig_array)
         else:
                           orig_array)
 
     def argsort(self, space, w_axis):
+        from pypy.module.micronumpy.arrayimpl.sort import argsort_array
         return argsort_array(self, space, w_axis)
 
     def base(self):
         self.strides = strides
         self.backstrides = backstrides
         self.shape = shape
+        if dtype is None:
+            dtype = parent.dtype
         if isinstance(parent, SliceArray):
             parent = parent.parent # one level only
         self.parent = parent
         self.storage = parent.storage
         self.order = parent.order
-        if dtype is None:
-            dtype = parent.dtype
         self.dtype = dtype
         self.size = support.product(shape) * self.dtype.itemtype.get_element_size()
         self.start = start

File pypy/module/micronumpy/arrayimpl/scalar.py

View file
 from pypy.module.micronumpy.arrayimpl import base
 from pypy.module.micronumpy.base import W_NDimArray, convert_to_array
 from pypy.module.micronumpy import support
+from pypy.module.micronumpy.interp_boxes import W_GenericBox
 from pypy.interpreter.error import OperationError
 
 class ScalarIterator(base.BaseArrayIterator):
         return self.value
 
     def set_scalar_value(self, w_val):
+        assert isinstance(w_val, W_GenericBox)
         self.value = w_val.convert_to(self.dtype)
 
     def copy(self, space):
         dtype = self.dtype.float_type or self.dtype
         if len(w_arr.get_shape()) > 0:
             raise OperationError(space.w_ValueError, space.wrap(
-                "could not broadcast input array from shape " + 
+                "could not broadcast input array from shape " +
                 "(%s) into shape ()" % (
                     ','.join([str(x) for x in w_arr.get_shape()],))))
         if self.dtype.is_complex_type():
         dtype = self.dtype.float_type
         if len(w_arr.get_shape()) > 0:
             raise OperationError(space.w_ValueError, space.wrap(
-                "could not broadcast input array from shape " + 
+                "could not broadcast input array from shape " +
                 "(%s) into shape ()" % (
                     ','.join([str(x) for x in w_arr.get_shape()],))))
         self.value = self.dtype.itemtype.composite(

File pypy/module/micronumpy/base.py

View file
         from pypy.module.micronumpy.arrayimpl import concrete, scalar
 
         if not shape:
-            impl = scalar.Scalar(dtype)
+            impl = scalar.Scalar(dtype.base)
         else:
-            strides, backstrides = calc_strides(shape, dtype, order)
-            impl = concrete.ConcreteArray(shape, dtype, order, strides,
+            strides, backstrides = calc_strides(shape, dtype.base, order)
+            impl = concrete.ConcreteArray(shape, dtype.base, order, strides,
                                       backstrides)
         return W_NDimArray(impl)
 

File pypy/module/micronumpy/interp_boxes.py

View file
 
 
 class W_VoidBox(W_FlexibleBox):
-    @unwrap_spec(item=str)
-    def descr_getitem(self, space, item):
+    def descr_getitem(self, space, w_item):
+        from pypy.module.micronumpy.types import VoidType
+        if space.isinstance_w(w_item, space.w_str):
+            item = space.str_w(w_item)
+        elif space.isinstance_w(w_item, space.w_int):
+            #Called by iterator protocol
+            indx = space.int_w(w_item)
+            try:
+                item = self.dtype.fieldnames[indx]
+            except IndexError:
+                raise OperationError(space.w_IndexError,
+                     space.wrap("Iterated over too many fields %d" % indx))
+        else:
+            raise OperationError(space.w_IndexError, space.wrap(
+                    "Can only access fields of record with int or str"))
         try:
             ofs, dtype = self.dtype.fields[item]
         except KeyError:
             raise OperationError(space.w_IndexError,
                                  space.wrap("Field %s does not exist" % item))
-        read_val = dtype.itemtype.read(self.arr, self.ofs, ofs, dtype)
+        if isinstance(dtype.itemtype, VoidType):
+            read_val = dtype.itemtype.readarray(self.arr, self.ofs, ofs, dtype)
+        else:
+            read_val = dtype.itemtype.read(self.arr, self.ofs, ofs, dtype)
         if isinstance (read_val, W_StringBox):
             # StringType returns a str
             return space.wrap(dtype.itemtype.to_str(read_val))
     W_LongDoubleBox = W_Float64Box
     W_CLongDoubleBox = W_Complex64Box
 
-    
+
 W_GenericBox.typedef = TypeDef("generic",
     __module__ = "numpypy",
 

File pypy/module/micronumpy/interp_dtype.py

View file
 
 
 class W_Dtype(W_Root):
-    _immutable_fields_ = ["itemtype", "num", "kind"]
+    _immutable_fields_ = ["itemtype", "num", "kind", "shape"]
 
     def __init__(self, itemtype, num, kind, name, char, w_box_type,
                  alternate_constructors=[], aliases=[],
-                 fields=None, fieldnames=None, native=True):
+                 fields=None, fieldnames=None, native=True, shape=[], subdtype=None):
         self.itemtype = itemtype
         self.num = num
         self.kind = kind
         self.fieldnames = fieldnames
         self.native = native
         self.float_type = None
+        self.shape = list(shape)
+        self.subdtype = subdtype
+        if not subdtype:
+            self.base = self
+        else:
+            self.base = subdtype.base
 
     @specialize.argtype(1)
     def box(self, value):
         return self.itemtype.coerce(space, self, w_item)
 
     def getitem(self, arr, i):
-        return self.itemtype.read(arr, i, 0)
+        item = self.itemtype.read(arr, i, 0)
+        return item
 
     def getitem_bool(self, arr, i):
         return self.itemtype.read_bool(arr, i, 0)
     def descr_get_alignment(self, space):
         return space.wrap(self.itemtype.alignment)
 
+    def descr_get_base(self, space):
+        return space.wrap(self.base)
+
+    def descr_get_subdtype(self, space):
+        return space.newtuple([space.wrap(self.subdtype), self.descr_get_shape(space)])
+
     def descr_get_shape(self, space):
-        return space.newtuple([])
+        w_shape = [space.wrap(dim) for dim in self.shape]
+        return space.newtuple(w_shape)
 
     def eq(self, space, w_other):
         w_other = space.call_function(space.gettypefor(W_Dtype), w_other)
         if w_fields == space.w_None:
             self.fields = None
         else:
+            self.fields = {}
             ofs_and_items = []
             size = 0
             for key in space.listview(w_fields):
     ofs_and_items = []
     fieldnames = []
     for w_elem in lst_w:
-        w_fldname, w_flddesc = space.fixedview(w_elem, 2)
-        subdtype = descr__new__(space, space.gettypefor(W_Dtype), w_flddesc)
+        size = 1
+        w_shape = space.newtuple([])
+        if space.len_w(w_elem) == 3:
+            w_fldname, w_flddesc, w_shape = space.fixedview(w_elem)
+            if not base.issequence_w(space, w_shape):
+                w_shape = space.newtuple([w_shape,])
+        else:
+            w_fldname, w_flddesc = space.fixedview(w_elem)
+        subdtype = descr__new__(space, space.gettypefor(W_Dtype), w_flddesc, w_shape=w_shape)
         fldname = space.str_w(w_fldname)
         if fldname in fields:
             raise OperationError(space.w_ValueError, space.wrap("two fields with the same name"))
         assert isinstance(subdtype, W_Dtype)
         fields[fldname] = (offset, subdtype)
         ofs_and_items.append((offset, subdtype.itemtype))
-        offset += subdtype.itemtype.get_element_size()
+        offset += subdtype.itemtype.get_element_size() * size
         fieldnames.append(fldname)
     itemtype = types.RecordType(ofs_and_items, offset)
     return W_Dtype(itemtype, 20, VOIDLTR, "void" + str(8 * itemtype.get_element_size()),
     elif char == 'V':
         num = 20
         basename = 'void'
-        w_box_type = space.gettypefor(interp_boxes.W_VoidBox)
-        return dtype_from_list(space, space.newlist([]))
+        itemtype = types.VoidType(size)
+        return W_Dtype(itemtype, 20, VOIDLTR, "void" + str(size),
+                    "V", space.gettypefor(interp_boxes.W_VoidBox))
     else:
         assert char == 'U'
         basename = 'unicode'
         raise OperationError(space.w_NotImplementedError, space.wrap(
             "dtype from spec"))
 
-def descr__new__(space, w_subtype, w_dtype, w_align=None, w_copy=None):
+def descr__new__(space, w_subtype, w_dtype, w_align=None, w_copy=None, w_shape=None):
     # w_align and w_copy are necessary for pickling
     cache = get_dtype_cache(space)
 
+    if w_shape is not None and (space.isinstance_w(w_shape, space.w_int) or space.len_w(w_shape) > 0):
+        subdtype = descr__new__(space, w_subtype, w_dtype, w_align, w_copy)
+        assert isinstance(subdtype, W_Dtype)
+        size = 1
+        if space.isinstance_w(w_shape, space.w_int):
+            w_shape = space.newtuple([w_shape])
+        shape = []
+        for w_dim in space.fixedview(w_shape):
+            dim = space.int_w(w_dim)
+            shape.append(dim)
+            size *= dim
+        return W_Dtype(types.VoidType(subdtype.itemtype.get_element_size() * size), 20, VOIDLTR, "void" + str(8 * subdtype.itemtype.get_element_size() * size),
+                    "V", space.gettypefor(interp_boxes.W_VoidBox), shape=shape, subdtype=subdtype)
+
     if space.is_none(w_dtype):
         return cache.w_float64dtype
     elif space.isinstance_w(w_dtype, w_subtype):
                        "data type %s not understood" % name))
     elif space.isinstance_w(w_dtype, space.w_list):
         return dtype_from_list(space, w_dtype)
+    elif space.isinstance_w(w_dtype, space.w_tuple):
+        return descr__new__(space, w_subtype, space.getitem(w_dtype, space.wrap(0)), w_align, w_copy, w_shape=space.getitem(w_dtype, space.wrap(1)))
     elif space.isinstance_w(w_dtype, space.w_dict):
         return dtype_from_dict(space, w_dtype)
     for dtype in cache.builtin_dtypes:
     name = interp_attrproperty('name', cls=W_Dtype),
     fields = GetSetProperty(W_Dtype.descr_get_fields),
     names = GetSetProperty(W_Dtype.descr_get_names),
+    subdtype = GetSetProperty(W_Dtype.descr_get_subdtype),
+    base = GetSetProperty(W_Dtype.descr_get_base),
 )
 W_Dtype.typedef.acceptable_as_base_class = False
 

File pypy/module/micronumpy/interp_numarray.py

View file
 from rpython.rlib.rstring import StringBuilder
 from pypy.module.micronumpy.arrayimpl.base import BaseArrayImplementation
 
-def _find_shape(space, w_size):
+def _find_shape(space, w_size, dtype):
     if space.is_none(w_size):
         return []
     if space.isinstance_w(w_size, space.w_int):
     shape = []
     for w_item in space.fixedview(w_size):
         shape.append(space.int_w(w_item))
+    shape += dtype.shape
     return shape[:]
 
 class __extend__(W_NDimArray):
                              space.wrap("unsupported param"))
     dtype = space.interp_w(interp_dtype.W_Dtype,
           space.call_function(space.gettypefor(interp_dtype.W_Dtype), w_dtype))
-    shape = _find_shape(space, w_shape)
+    shape = _find_shape(space, w_shape, dtype)
     if not shape:
         return W_NDimArray.new_scalar(space, dtype)
     return W_NDimArray.from_shape(shape, dtype)
     """
     from rpython.rtyper.lltypesystem import rffi
     from rpython.rlib.rawstorage import RAW_STORAGE_PTR
-    shape = _find_shape(space, w_shape)
     storage = rffi.cast(RAW_STORAGE_PTR, addr)
     dtype = space.interp_w(interp_dtype.W_Dtype,
                            space.call_function(space.gettypefor(interp_dtype.W_Dtype), w_dtype))
+    shape = _find_shape(space, w_shape, dtype)
     return W_NDimArray.from_shape_and_storage(shape, storage, dtype)
 
 W_NDimArray.typedef = TypeDef(
     dtype = space.interp_w(interp_dtype.W_Dtype,
         space.call_function(space.gettypefor(interp_dtype.W_Dtype), w_dtype)
     )
-    shape = _find_shape(space, w_shape)
+    shape = _find_shape(space, w_shape, dtype)
     if not shape:
         return W_NDimArray.new_scalar(space, dtype, space.wrap(0))
     return space.wrap(W_NDimArray.from_shape(shape, dtype=dtype, order=order))
     dtype = space.interp_w(interp_dtype.W_Dtype,
         space.call_function(space.gettypefor(interp_dtype.W_Dtype), w_dtype)
     )
-    shape = _find_shape(space, w_shape)
+    shape = _find_shape(space, w_shape, dtype)
     if not shape:
         return W_NDimArray.new_scalar(space, dtype, space.wrap(0))
     arr = W_NDimArray.from_shape(shape, dtype=dtype, order=order)

File pypy/module/micronumpy/iter.py

View file
 shape dimension
   which is back 25 and forward 1,
   which is x.strides[1] * (x.shape[1] - 1) + x.strides[0]
-so if we precalculate the overflow backstride as 
+so if we precalculate the overflow backstride as
 [x.strides[i] * (x.shape[i] - 1) for i in range(len(x.shape))]
 we can go faster.
 All the calculations happen in next()
 
 next_skip_x() tries to do the iteration for a number of steps at once,
-but then we cannot gaurentee that we only overflow one single shape 
+but then we cannot gaurentee that we only overflow one single shape
 dimension, perhaps we could overflow times in one big step.
 """
 
         self.dtype.setitem(self.array, self.offset, elem)
 
     def getitem(self):
-        return self.dtype.getitem(self.array, self.offset)
+        item = self.dtype.getitem(self.array, self.offset)
+        return item
 
     def getitem_bool(self):
         return self.dtype.getitem_bool(self.array, self.offset)
         self.dim = dim
         self.array = array
         self.dtype = array.dtype
-        
+
     def setitem(self, elem):
         self.dtype.setitem(self.array, self.offset, elem)
 
     def getitem(self):
-        return self.dtype.getitem(self.array, self.offset)
+        item = self.dtype.getitem(self.array, self.offset)
+        return item
 
     @jit.unroll_safe
     def next(self):

File pypy/module/micronumpy/loop.py

File contents unchanged.

File pypy/module/micronumpy/test/test_dtypes.py

View file
         from numpypy import array, dtype
         from cPickle import loads, dumps
         a = array([1,2,3])
-        if self.ptr_size == 8:
+         if self.ptr_size == 8:
             assert a.dtype.__reduce__() == (dtype, ('i8', 0, 1), (3, '<', None, None, None, -1, -1, 0))
         else:
             assert a.dtype.__reduce__() == (dtype, ('i4', 0, 1), (3, '<', None, None, None, -1, -1, 0))
         assert loads(dumps(a.dtype)) == a.dtype
 
-    def test_pickle_record(self):
-        from numpypy import array, dtype
-        from cPickle import loads, dumps
-
-        d = dtype([("x", "int32"), ("y", "int32"), ("z", "int32"), ("value", float)])
-        assert d.__reduce__() == (dtype, ('V20', 0, 1), (3, '<', None, ('x', 'y', 'z', 'value'), {'y': (dtype('int32'), 4), 'x': (dtype('int32'), 0), 'z': (dtype('int32'), 8), 'value': (dtype('float64'), 12)}, 20, 1, 0))
-
-        new_d = loads(dumps(d))
-
-        assert new_d.__reduce__() == d.__reduce__()
-
 class AppTestTypes(BaseAppTestDtypes):
     def test_abstract_types(self):
         import numpypy as numpy
         x = int8(42).ravel()
         assert x.dtype == int8
         assert (x == array(42)).all()
-        
+
 
 
 class AppTestStrUnicodeDtypes(BaseNumpyAppTest):
         assert isinstance(unicode_(3), unicode)
 
 class AppTestRecordDtypes(BaseNumpyAppTest):
+    spaceconfig = dict(usemodules=["micronumpy", "struct", "binascii"])
     def test_create(self):
         from numpypy import dtype, void
 
         assert d.num == 20
         assert d.itemsize == 20
         assert d.kind == 'V'
+        assert d.base == d
         assert d.type is void
         assert d.char == 'V'
         assert d.names == ("x", "y", "z", "value")
         d = dtype({'names': ['a', 'b', 'c'],
                    })
 
+    def test_create_subarrays(self):
+        from numpypy import dtype
+        d = dtype([("x", "float", (2,)), ("y", "int", (2,))])
+        assert d.itemsize == 32
+        assert d.name == "void256"
+        keys = d.fields.keys()
+        assert "x" in keys
+        assert "y" in keys
+        assert d["x"].shape == (2,)
+        assert d["x"].itemsize == 16
+        e = dtype([("x", "float", 2), ("y", "int", 2)])
+        assert e.fields.keys() == keys
+        assert e['x'].shape == (2,)
+
+        dt = dtype((float, 10))
+        assert dt.shape == (10,)
+        assert dt.kind == 'V'
+        assert dt.fields == None
+        assert dt.subdtype == (dtype(float), (10,))
+        assert dt.base == dtype(float)
+
+    def test_pickle_record(self):
+        from numpypy import array, dtype
+        from cPickle import loads, dumps
+
+        d = dtype([("x", "int32"), ("y", "int32"), ("z", "int32"), ("value", float)])
+        assert d.__reduce__() == (dtype, ('V20', 0, 1), (3, '<', None, ('x', 'y', 'z', 'value'), {'y': (dtype('int32'), 4), 'x': (dtype('int32'), 0), 'z': (dtype('int32'), 8), 'value': (dtype('float64'), 12)}, 20, 1, 0))
+
+        new_d = loads(dumps(d))
+
+        assert new_d.__reduce__() == d.__reduce__()
+
+    def test_pickle_record_subarrays(self):
+        from numpypy import array, dtype
+        from cPickle import loads, dumps
+
+        d = dtype([("x", "int32", (3,)), ("y", "int32", (2,)), ("z", "int32", (4,)), ("value", float, (5,))])
+        new_d = loads(dumps(d))
+
+        keys = d.fields.keys()
+        keys.sort()
+        assert keys == ["value", "x", "y", "z"]
+
+        assert new_d.itemsize == d.itemsize == 76
+
 class AppTestNotDirect(BaseNumpyAppTest):
     def setup_class(cls):
         BaseNumpyAppTest.setup_class.im_func(cls)

File pypy/module/micronumpy/test/test_numarray.py

View file
         def get_element_size():
             return 1
 
+    def __init__(self):
+        self.base = self
+
     def get_size(self):
         return 1
 
-
 def create_slice(a, chunks):
     return Chunks(chunks).apply(W_NDimArray(a)).implementation
 
         assert a[0]['y'] == 2
         assert a[1]['y'] == 1
 
+    def test_subarrays(self):
+        from numpypy import dtype, array, zeros
+
+        d = dtype([("x", "int", 3), ("y", "float", 5)])
+        a = array([([1, 2, 3], [0.5, 1.5, 2.5, 3.5, 4.5]), ([4, 5, 6], [5.5, 6.5, 7.5, 8.5, 9.5])], dtype=d)
+
+        assert (a[0]["x"] == [1, 2, 3]).all()
+        assert (a[0]["y"] == [0.5, 1.5, 2.5, 3.5, 4.5]).all()
+        assert (a[1]["x"] == [4, 5, 6]).all()
+        assert (a[1]["y"] == [5.5, 6.5, 7.5, 8.5, 9.5]).all()
+
+        a[0]["x"][0] = 200
+        assert a[0]["x"][0] == 200
+
+        d = dtype([("x", "int", (2, 3))])
+        a = array([([[1, 2, 3], [4, 5, 6]],)], dtype=d)
+
+        assert a[0]["x"].dtype == dtype("int64")
+        assert a[0]["x"][0].dtype == dtype("int64")
+
+        assert (a[0]["x"][0] == [1, 2, 3]).all()
+        assert (a[0]["x"] == [[1, 2, 3], [4, 5, 6]]).all()
+
+        d = dtype((float, (10, 10)))
+        a = zeros((3,3), dtype=d)
+        assert a[0, 0].shape == (10, 10)
+        assert a.shape == (3, 3, 10, 10)
+        a[0, 0] = 500
+        assert (a[0, 0, 0] == 500).all()
+        assert a[0, 0, 0].shape == (10,)
+
+    def test_multidim_subarray(self):
+        from numpypy import dtype, array
+
+        d = dtype([("x", "int", (2, 3))])
+        a = array([([[1, 2, 3], [4, 5, 6]],)], dtype=d)
+
+        assert a[0]["x"].dtype == dtype("int64")
+        assert a[0]["x"][0].dtype == dtype("int64")
+
+        assert (a[0]["x"][0] == [1, 2, 3]).all()
+        assert (a[0]["x"] == [[1, 2, 3], [4, 5, 6]]).all()
+
+    def test_list_record(self):
+        from numpypy import dtype, array
+
+        d = dtype([("x", "int", 3), ("y", "float", 5)])
+        a = array([([1, 2, 3], [0.5, 1.5, 2.5, 3.5, 4.5]), ([4, 5, 6], [5.5, 6.5, 7.5, 8.5, 9.5])], dtype=d)
+
+        assert len(list(a[0])) == 2
 
 class AppTestPyPy(BaseNumpyAppTest):
     def setup_class(cls):

File pypy/module/micronumpy/types.py

View file
 
 from pypy.interpreter.error import OperationError
 from pypy.module.micronumpy import interp_boxes
+from pypy.module.micronumpy import support
 from pypy.module.micronumpy.arrayimpl.voidbox import VoidBoxStorage
+from pypy.module.micronumpy.arrayimpl.concrete import SliceArray
 from pypy.objspace.std.floatobject import float2string
 from pypy.objspace.std.complexobject import str_format
 from rpython.rlib import rfloat, clibffi, rcomplex
 
     def to_builtin_type(self, space, box):
         real,imag = self.for_computation(self.unbox(box))
-        return space.newcomplex(real, imag) 
+        return space.newcomplex(real, imag)
 
     def read_bool(self, arr, i, offset):
         v = self.for_computation(self._read(arr.storage, i, offset))
 
     @raw_binary_op
     def le(self, v1, v2):
-        return self._lt(v1, v2) or self._eq(v1, v2) 
+        return self._lt(v1, v2) or self._eq(v1, v2)
 
     @raw_binary_op
     def gt(self, v1, v2):
 
     @raw_binary_op
     def ge(self, v1, v2):
-        return self._lt(v2, v1) or self._eq(v2, v1) 
+        return self._lt(v2, v1) or self._eq(v2, v1)
 
     def _bool(self, v):
         return bool(v[0]) or bool(v[1])
             return rcomplex.c_div((v[0], -v[1]), (a2, 0.))
         except ZeroDivisionError:
             return rfloat.NAN, rfloat.NAN
- 
+
     # No floor, ceil, trunc in numpy for complex
     #@simple_unary_op
     #def floor(self, v):
         return space.wrap(self.to_str(box))
 
     def build_and_convert(self, space, mydtype, box):
+        assert isinstance(box, interp_boxes.W_GenericBox)
         if box.get_dtype(space).is_str_or_unicode():
             arg = box.get_dtype(space).itemtype.to_str(box)
         else:
         for j in range(i + 1, self.size):
             arr.storage[j] = '\x00'
         return interp_boxes.W_StringBox(arr,  0, arr.dtype)
-        
+
 class VoidType(BaseType, BaseStringType):
     T = lltype.Char
 
+    def _coerce(self, space, arr, ofs, dtype, w_items, shape):
+        items_w = space.fixedview(w_items)
+        for i in range(len(items_w)):
+            subdtype = dtype.subdtype
+            itemtype = subdtype.itemtype
+            if space.len_w(shape) <= 1:
+                w_box = itemtype.coerce(space, dtype.subdtype, items_w[i])
+                itemtype.store(arr, 0, ofs, w_box)
+                ofs += itemtype.get_element_size()
+            else:
+                size = 1
+                for dimension in shape[1:]:
+                    size *= dimension
+                size *= itemtype.get_element_size()
+                for w_item in items_w:
+                    self._coerce(space, arr, ofs, dtype, w_items, shape[1:])
+                    ofs += size
+        return arr
+
+    def _coerce(self, space, arr, ofs, dtype, w_items, shape):
+        # TODO: Make sure the shape and the array match
+        items_w = space.fixedview(w_items)
+        subdtype = dtype.subdtype
+        itemtype = subdtype.itemtype
+        if len(shape) <= 1:
+            for i in range(len(items_w)):
+                w_box = itemtype.coerce(space, dtype.subdtype, items_w[i])
+                itemtype.store(arr, 0, ofs, w_box)
+                ofs += itemtype.get_element_size()
+        else:
+            for w_item in items_w:
+                size = 1
+                for dimension in shape[1:]:
+                    size *= dimension
+                size *= itemtype.get_element_size()
+                self._coerce(space, arr, ofs, dtype, w_item, shape[1:])
+                ofs += size
+
+    def coerce(self, space, dtype, w_items):
+        arr = VoidBoxStorage(self.size, dtype)
+        self._coerce(space, arr, 0, dtype, w_items, dtype.shape)
+        return interp_boxes.W_VoidBox(arr, 0, dtype)
+
+    @jit.unroll_safe
+    def store(self, arr, i, ofs, box):
+        assert isinstance(box, interp_boxes.W_VoidBox)
+        for k in range(self.get_element_size()):
+            arr.storage[k + ofs] = box.arr.storage[k + box.ofs]
+
+    def readarray(self, arr, i, offset, dtype=None):
+        from pypy.module.micronumpy.base import W_NDimArray
+        if dtype is None:
+            dtype = arr.dtype
+        strides, backstrides = support.calc_strides(dtype.shape, dtype.subdtype, arr.order)
+        implementation = SliceArray(i + offset, strides, backstrides,
+                             dtype.shape, arr, W_NDimArray(arr), dtype.subdtype)
+        return W_NDimArray(implementation)
+
 NonNativeVoidType = VoidType
 NonNativeStringType = StringType
 
         if not space.issequence_w(w_item):
             raise OperationError(space.w_TypeError, space.wrap(
                 "expected sequence"))
-        if len(self.offsets_and_fields) != space.int_w(space.len(w_item)):
+        if len(self.offsets_and_fields) != space.len_w(w_item):
             raise OperationError(space.w_ValueError, space.wrap(
                 "wrong length"))
         items_w = space.fixedview(w_item)

File pypy/objspace/std/iterobject.py

View file
 """Generic iterator implementations"""
+
+from pypy.interpreter.baseobjspace import W_Root
+from pypy.interpreter.gateway import interp2app, interpindirect2app
 from pypy.interpreter.error import OperationError
-from pypy.objspace.std.model import registerimplementation, W_Object
-from pypy.objspace.std.register_all import register_all
+from pypy.objspace.std.stdtypedef import StdTypeDef
 
 
-class W_AbstractIterObject(W_Object):
-    __slots__ = ()
-
-class W_AbstractSeqIterObject(W_AbstractIterObject):
-    from pypy.objspace.std.itertype import iter_typedef as typedef
-
-    def __init__(w_self, w_seq, index=0):
+class W_AbstractSeqIterObject(W_Root):
+    def __init__(self, w_seq, index=0):
         if index < 0:
             index = 0
-        w_self.w_seq = w_seq
-        w_self.index = index
+        self.w_seq = w_seq
+        self.index = index
 
     def getlength(self, space):
         if self.w_seq is None:
             w_len = space.wrap(0)
         return w_len
 
+    def descr_iter(self, space):
+        return self
+
+    def descr_next(self, space):
+        raise NotImplementedError
+
+    def descr_reduce(self, space):
+        """
+        XXX to do: remove this __reduce__ method and do
+        a registration with copy_reg, instead.
+        """
+        from pypy.interpreter.mixedmodule import MixedModule
+        w_mod = space.getbuiltinmodule('_pickle_support')
+        mod = space.interp_w(MixedModule, w_mod)
+        new_inst = mod.get('seqiter_new')
+        tup = [self.w_seq, space.wrap(self.index)]
+        return space.newtuple([new_inst, space.newtuple(tup)])
+
+    def descr_length_hint(self, space):
+        return self.getlength(space)
+
+W_AbstractSeqIterObject.typedef = StdTypeDef(
+    "sequenceiterator",
+    __doc__ = '''iter(collection) -> iterator
+iter(callable, sentinel) -> iterator
+
+Get an iterator from an object.  In the first form, the argument must
+supply its own iterator, or be a sequence.
+In the second form, the callable is called until it returns the sentinel.''',
+    __iter__ = interp2app(W_AbstractSeqIterObject.descr_iter),
+    next = interpindirect2app(W_AbstractSeqIterObject.descr_next),
+    __reduce__ = interp2app(W_AbstractSeqIterObject.descr_reduce),
+    __length_hint__ = interp2app(W_AbstractSeqIterObject.descr_length_hint),
+)
+W_AbstractSeqIterObject.typedef.acceptable_as_base_class = False
+
+
 class W_SeqIterObject(W_AbstractSeqIterObject):
     """Sequence iterator implementation for general sequences."""
 
-class W_FastListIterObject(W_AbstractSeqIterObject): # XXX still needed
-    """Sequence iterator specialized for lists.
-    """
+    def descr_next(self, space):
+        if self.w_seq is None:
+            raise OperationError(space.w_StopIteration, space.w_None)
+        try:
+            w_item = space.getitem(self.w_seq, space.wrap(self.index))
+        except OperationError, e:
+            self.w_seq = None
+            if not e.match(space, space.w_IndexError):
+                raise
+            raise OperationError(space.w_StopIteration, space.w_None)
+        self.index += 1
+        return w_item
+
+
+class W_FastListIterObject(W_AbstractSeqIterObject):
+    """Sequence iterator specialized for lists."""
+
+    def descr_next(self, space):
+        from pypy.objspace.std.listobject import W_ListObject
+        w_seq = self.w_seq
+        if w_seq is None:
+            raise OperationError(space.w_StopIteration, space.w_None)
+        assert isinstance(w_seq, W_ListObject)
+        index = self.index
+        try:
+            w_item = w_seq.getitem(index)
+        except IndexError:
+            self.w_seq = None
+            raise OperationError(space.w_StopIteration, space.w_None)
+        self.index = index + 1
+        return w_item
+
 
 class W_FastTupleIterObject(W_AbstractSeqIterObject):
     """Sequence iterator specialized for tuples, accessing directly
     their RPython-level list of wrapped objects.
     """
-    def __init__(w_self, w_seq, wrappeditems):
-        W_AbstractSeqIterObject.__init__(w_self, w_seq)
-        w_self.tupleitems = wrappeditems
+    def __init__(self, w_seq, wrappeditems):
+        W_AbstractSeqIterObject.__init__(self, w_seq)
+        self.tupleitems = wrappeditems
 
-class W_ReverseSeqIterObject(W_Object):
-    from pypy.objspace.std.itertype import reverse_iter_typedef as typedef
+    def descr_next(self, space):
+        if self.tupleitems is None:
+            raise OperationError(space.w_StopIteration, space.w_None)
+        index = self.index
+        try:
+            w_item = self.tupleitems[index]
+        except IndexError:
+            self.tupleitems = None
+            self.w_seq = None
+            raise OperationError(space.w_StopIteration, space.w_None)
+        self.index = index + 1
+        return w_item
 
-    def __init__(w_self, space, w_seq, index=-1):
-        w_self.w_seq = w_seq
-        w_self.w_len = space.len(w_seq)
-        w_self.index = space.int_w(w_self.w_len) + index
 
+class W_ReverseSeqIterObject(W_Root):
+    def __init__(self, space, w_seq, index=-1):
+        self.w_seq = w_seq
+        self.w_len = space.len(w_seq)
+        self.index = space.int_w(self.w_len) + index
 
-registerimplementation(W_SeqIterObject)
-registerimplementation(W_FastListIterObject)
-registerimplementation(W_FastTupleIterObject)
-registerimplementation(W_ReverseSeqIterObject)
+    def descr_reduce(self, space):
+        """
+        XXX to do: remove this __reduce__ method and do
+        a registration with copy_reg, instead.
+        """
+        from pypy.interpreter.mixedmodule import MixedModule
+        w_mod = space.getbuiltinmodule('_pickle_support')
+        mod = space.interp_w(MixedModule, w_mod)
+        new_inst = mod.get('reverseseqiter_new')
+        tup = [self.w_seq, space.wrap(self.index)]
+        return space.newtuple([new_inst, space.newtuple(tup)])
 
-def iter__SeqIter(space, w_seqiter):
-    return w_seqiter
+    def descr_length_hint(self, space):
+        if self.w_seq is None:
+            return space.wrap(0)
+        index = self.index + 1
+        w_length = space.len(self.w_seq)
+        # if length of sequence is less than index :exhaust iterator
+        if space.is_true(space.gt(space.wrap(self.index), w_length)):
+            w_len = space.wrap(0)
+            self.w_seq = None
+        else:
+            w_len = space.wrap(index)
+        if space.is_true(space.lt(w_len, space.wrap(0))):
+            w_len = space.wrap(0)
+        return w_len
 
-def next__SeqIter(space, w_seqiter):
-    if w_seqiter.w_seq is None:
-        raise OperationError(space.w_StopIteration, space.w_None)
-    try:
-        w_item = space.getitem(w_seqiter.w_seq, space.wrap(w_seqiter.index))
-    except OperationError, e:
-        w_seqiter.w_seq = None
-        if not e.match(space, space.w_IndexError):
-            raise
-        raise OperationError(space.w_StopIteration, space.w_None)
-    w_seqiter.index += 1
-    return w_item
+    def descr_iter(self, space):
+        return self
 
+    def descr_next(self, space):
+        if self.w_seq is None or self.index < 0:
+            raise OperationError(space.w_StopIteration, space.w_None)
+        try:
+            w_item = space.getitem(self.w_seq, space.wrap(self.index))
+            self.index -= 1
+        except OperationError, e:
+            self.w_seq = None
+            if not e.match(space, space.w_IndexError):
+                raise
+            raise OperationError(space.w_StopIteration, space.w_None)
+        return w_item
 
-def iter__FastTupleIter(space, w_seqiter):
-    return w_seqiter
-
-def next__FastTupleIter(space, w_seqiter):
-    if w_seqiter.tupleitems is None:
-        raise OperationError(space.w_StopIteration, space.w_None)
-    index = w_seqiter.index
-    try:
-        w_item = w_seqiter.tupleitems[index]
-    except IndexError:
-        w_seqiter.tupleitems = None
-        w_seqiter.w_seq = None
-        raise OperationError(space.w_StopIteration, space.w_None)
-    w_seqiter.index = index + 1
-    return w_item
-
-
-def iter__FastListIter(space, w_seqiter):
-    return w_seqiter
-
-def next__FastListIter(space, w_seqiter):
-    from pypy.objspace.std.listobject import W_ListObject
-    w_seq = w_seqiter.w_seq
-    if w_seq is None:
-        raise OperationError(space.w_StopIteration, space.w_None)
-    assert isinstance(w_seq, W_ListObject)
-    index = w_seqiter.index
-    try:
-        w_item = w_seq.getitem(index)
-    except IndexError:
-        w_seqiter.w_seq = None
-        raise OperationError(space.w_StopIteration, space.w_None)
-    w_seqiter.index = index + 1
-    return w_item
-
-
-def iter__ReverseSeqIter(space, w_seqiter):
-    return w_seqiter
-
-def next__ReverseSeqIter(space, w_seqiter):
-    if w_seqiter.w_seq is None or w_seqiter.index < 0:
-        raise OperationError(space.w_StopIteration, space.w_None)
-    try:
-        w_item = space.getitem(w_seqiter.w_seq, space.wrap(w_seqiter.index))
-        w_seqiter.index -= 1
-    except OperationError, e:
-        w_seqiter.w_seq = None
-        if not e.match(space, space.w_IndexError):
-            raise
-        raise OperationError(space.w_StopIteration, space.w_None)
-    return w_item
-
-register_all(vars())
+W_ReverseSeqIterObject.typedef = StdTypeDef(
+    "reversesequenceiterator",
+    __iter__ = interp2app(W_ReverseSeqIterObject.descr_iter),
+    next = interp2app(W_ReverseSeqIterObject.descr_next),
+    __reduce__ = interp2app(W_ReverseSeqIterObject.descr_reduce),
+    __length_hint__ = interp2app(W_ReverseSeqIterObject.descr_length_hint),
+)
+W_ReverseSeqIterObject.typedef.acceptable_as_base_class = False

File pypy/objspace/std/itertype.py

-from pypy.interpreter import gateway
-from pypy.objspace.std.stdtypedef import StdTypeDef
-from pypy.interpreter.error import OperationError
-
-# ____________________________________________________________
-
-def descr_seqiter__reduce__(w_self, space):
-    """
-    XXX to do: remove this __reduce__ method and do
-    a registration with copy_reg, instead.
-    """
-
-    # cpython does not support pickling iterators but stackless python do
-    #msg = 'Pickling for iterators dissabled as cpython does not support it'
-    #raise OperationError(space.w_TypeError, space.wrap(msg))
-
-    from pypy.objspace.std.iterobject import W_AbstractSeqIterObject
-    assert isinstance(w_self, W_AbstractSeqIterObject)
-    from pypy.interpreter.mixedmodule import MixedModule
-    w_mod    = space.getbuiltinmodule('_pickle_support')
-    mod      = space.interp_w(MixedModule, w_mod)
-    new_inst = mod.get('seqiter_new')
-    tup      = [w_self.w_seq, space.wrap(w_self.index)]
-    return space.newtuple([new_inst, space.newtuple(tup)])
-
-
-def descr_seqiter__length_hint__(space, w_self):
-    from pypy.objspace.std.iterobject import W_AbstractSeqIterObject
-    assert isinstance(w_self, W_AbstractSeqIterObject)
-    return w_self.getlength(space)
-
-# ____________________________________________________________
-
-def descr_reverseseqiter__reduce__(w_self, space):
-    """
-    XXX to do: remove this __reduce__ method and do
-    a registration with copy_reg, instead.
-    """
-    from pypy.objspace.std.iterobject import W_ReverseSeqIterObject
-    assert isinstance(w_self, W_ReverseSeqIterObject)
-    from pypy.interpreter.mixedmodule import MixedModule
-    w_mod    = space.getbuiltinmodule('_pickle_support')
-    mod      = space.interp_w(MixedModule, w_mod)
-    new_inst = mod.get('reverseseqiter_new')
-    tup      = [w_self.w_seq, space.wrap(w_self.index)]
-    return space.newtuple([new_inst, space.newtuple(tup)])
-
-
-def descr_reverseseqiter__length_hint__(space, w_self):
-    from pypy.objspace.std.iterobject import W_ReverseSeqIterObject
-    assert isinstance(w_self, W_ReverseSeqIterObject)
-    if w_self.w_seq is None:
-        return space.wrap(0)
-    index = w_self.index + 1
-    w_length = space.len(w_self.w_seq)
-    # if length of sequence is less than index :exhaust iterator
-    if space.is_true(space.gt(space.wrap(w_self.index), w_length)):
-        w_len = space.wrap(0)
-        w_self.w_seq = None
-    else:
-        w_len = space.wrap(index)
-    if space.is_true(space.lt(w_len, space.wrap(0))):
-        w_len = space.wrap(0)
-    return w_len
-
-# ____________________________________________________________
-iter_typedef = StdTypeDef("sequenceiterator",
-    __doc__ = '''iter(collection) -> iterator
-iter(callable, sentinel) -> iterator
-
-Get an iterator from an object.  In the first form, the argument must
-supply its own iterator, or be a sequence.
-In the second form, the callable is called until it returns the sentinel.''',
-
-    __reduce__ = gateway.interp2app(descr_seqiter__reduce__),
-    __length_hint__ = gateway.interp2app(descr_seqiter__length_hint__),
-    )
-iter_typedef.acceptable_as_base_class = False
-
-reverse_iter_typedef = StdTypeDef("reversesequenceiterator",
-
-    __reduce__ = gateway.interp2app(descr_reverseseqiter__reduce__),
-    __length_hint__ = gateway.interp2app(descr_reverseseqiter__length_hint__),
-    )
-reverse_iter_typedef.acceptable_as_base_class = False

File pypy/objspace/std/listobject.py

View file
+"""The builtin list implementation
+
+Lists optimize their storage by holding certain primitive datatypes in
+unwrapped form. For more information:
+
+http://morepypy.blogspot.com/2011/10/more-compact-lists-with-list-strategies.html
+
+"""
+
 import operator
-from sys import maxint
+import sys
 
 from pypy.interpreter.baseobjspace import W_Root
 from pypy.interpreter.error import OperationError, operationerrfmt
 from pypy.objspace.std.stringobject import W_StringObject
 from pypy.objspace.std.tupleobject import W_AbstractTupleObject
 from pypy.objspace.std.unicodeobject import W_UnicodeObject
-from pypy.objspace.std.util import negate, get_positive_index
-from rpython.rlib import rerased, jit, debug
+from pypy.objspace.std.util import get_positive_index, negate
+from rpython.rlib import debug, jit, rerased
 from rpython.rlib.listsort import make_timsort_class
-from rpython.rlib.objectmodel import (instantiate, newlist_hint, specialize,
-    resizelist_hint)
+from rpython.rlib.objectmodel import (
+    instantiate, newlist_hint, resizelist_hint, specialize)
 from rpython.tool.sourcetools import func_with_new_name
 
 __all__ = ['W_ListObject', 'make_range_list', 'make_empty_list_with_size']
 
 
 class W_ListObject(W_Root):
-    def __init__(w_self, space, wrappeditems, sizehint=-1):
+
+    def __init__(self, space, wrappeditems, sizehint=-1):
         assert isinstance(wrappeditems, list)
-        w_self.space = space
+        self.space = space
         if space.config.objspace.std.withliststrategies:
-            w_self.strategy = get_strategy_from_list_objects(space,
-                                                             wrappeditems,
-                                                             sizehint)
+            self.strategy = get_strategy_from_list_objects(space, wrappeditems,
+                                                           sizehint)
         else:
-            w_self.strategy = space.fromcache(ObjectListStrategy)
-        w_self.init_from_list_w(wrappeditems)
+            self.strategy = space.fromcache(ObjectListStrategy)
+        self.init_from_list_w(wrappeditems)
 
     @staticmethod
     def from_storage_and_strategy(space, storage, strategy):
-        w_self = instantiate(W_ListObject)
-        w_self.space = space
-        w_self.strategy = strategy
-        w_self.lstorage = storage
+        self = instantiate(W_ListObject)
+        self.space = space
+        self.strategy = strategy
+        self.lstorage = storage
         if not space.config.objspace.std.withliststrategies:
-            w_self.switch_to_object_strategy()
-        return w_self
+            self.switch_to_object_strategy()
+        return self
 
     @staticmethod
     def newlist_str(space, list_s):
         storage = strategy.erase(list_s)
         return W_ListObject.from_storage_and_strategy(space, storage, strategy)
 
-    def __repr__(w_self):
+    def __repr__(self):
         """ representation for debugging purposes """
-        return "%s(%s, %s)" % (w_self.__class__.__name__, w_self.strategy,
-                               w_self.lstorage._x)
+        return "%s(%s, %s)" % (self.__class__.__name__, self.strategy,
+                               self.lstorage._x)
 
     def unwrap(w_list, space):
         # for tests only!
         strategy and storage according to the other W_List"""
         self.strategy.copy_into(self, other)
 
-    def find(self, w_item, start=0, end=maxint):
+    def find(self, w_item, start=0, end=sys.maxint):
         """Find w_item in list[start:end]. If not found, raise ValueError"""
         return self.strategy.find(self, w_item, start, end)
 
         'L.remove(value) -- remove first occurrence of value'
         # needs to be safe against eq_w() mutating the w_list behind our back
         try:
-            i = self.find(w_value, 0, maxint)
+            i = self.find(w_value, 0, sys.maxint)
         except ValueError:
             raise OperationError(space.w_ValueError,
                                  space.wrap("list.remove(x): x not in list"))
         if i < self.length():  # otherwise list was mutated
             self.pop(i)
 
-    @unwrap_spec(w_start=WrappedDefault(0), w_stop=WrappedDefault(maxint))
+    @unwrap_spec(w_start=WrappedDefault(0), w_stop=WrappedDefault(sys.maxint))
     def descr_index(self, space, w_value, w_start, w_stop):
         '''L.index(value, [start, [stop]]) -> integer -- return
         first index of value'''

File pypy/objspace/std/model.py

View file
             from pypy.objspace.std.longtype   import long_typedef
             from pypy.objspace.std.unicodetype import unicode_typedef
             from pypy.objspace.std.nonetype import none_typedef
-            from pypy.objspace.std.itertype import iter_typedef
         self.pythontypes = [value for key, value in result.__dict__.items()
                             if not key.startswith('_')]   # don't look
 
         self.pythontypes.append(dictmultiobject.W_DictMultiObject.typedef)
         self.pythontypes.append(setobject.W_SetObject.typedef)
         self.pythontypes.append(setobject.W_FrozensetObject.typedef)
+        self.pythontypes.append(iterobject.W_AbstractSeqIterObject.typedef)
 
         # the set of implementation types
         self.typeorder = {
             longobject.W_LongObject: [],
             noneobject.W_NoneObject: [],
             complexobject.W_ComplexObject: [],
-            iterobject.W_SeqIterObject: [],
-            iterobject.W_FastListIterObject: [],
-            iterobject.W_FastTupleIterObject: [],
-            iterobject.W_ReverseSeqIterObject: [],
             unicodeobject.W_UnicodeObject: [],
             pypy.interpreter.pycode.PyCode: [],
             pypy.interpreter.special.Ellipsis: [],

File pypy/objspace/std/objspace.py

View file
 from pypy.objspace.std.dictmultiobject import W_DictMultiObject
 from pypy.objspace.std.floatobject import W_FloatObject
 from pypy.objspace.std.intobject import W_IntObject
+from pypy.objspace.std.iterobject import W_AbstractSeqIterObject
 from pypy.objspace.std.listobject import W_ListObject
 from pypy.objspace.std.longobject import W_LongObject, newlong
 from pypy.objspace.std.noneobject import W_NoneObject
         self._interplevel_classes[self.w_list] = W_ListObject
         self._interplevel_classes[self.w_set] = W_SetObject
         self._interplevel_classes[self.w_tuple] = W_AbstractTupleObject
+        self._interplevel_classes[self.w_sequenceiterator] = \
+                W_AbstractSeqIterObject
 
     @specialize.memo()
     def _get_interplevel_cls(self, w_type):

File pypy/objspace/std/setobject.py

View file
 class W_BaseSetObject(W_Root):
     typedef = None
 
-    def __init__(w_self, space, w_iterable=None):
+    def __init__(self, space, w_iterable=None):
         """Initialize the set by taking ownership of 'setdata'."""
-        w_self.space = space
-        set_strategy_and_setdata(space, w_self, w_iterable)
+        self.space = space
+        set_strategy_and_setdata(space, self, w_iterable)
 
-    def __repr__(w_self):
+    def __repr__(self):
         """representation for debugging purposes"""
-        reprlist = [repr(w_item) for w_item in w_self.getkeys()]
-        return "<%s(%s)>" % (w_self.__class__.__name__, ', '.join(reprlist))
+        reprlist = [repr(w_item) for w_item in self.getkeys()]
+        return "<%s(%s)>" % (self.__class__.__name__, ', '.join(reprlist))
 
-    def from_storage_and_strategy(w_self, storage, strategy):
-        obj = w_self._newobj(w_self.space, None)
+    def from_storage_and_strategy(self, storage, strategy):
+        obj = self._newobj(self.space, None)
         assert isinstance(obj, W_BaseSetObject)
         obj.strategy = strategy
         obj.sstorage = storage
 
 
 class W_SetObject(W_BaseSetObject):
-    def _newobj(w_self, space, w_iterable):
+    def _newobj(self, space, w_iterable):
         """Make a new set by taking ownership of 'w_iterable'."""
-        if type(w_self) is W_SetObject:
+        if type(self) is W_SetObject:
             return W_SetObject(space, w_iterable)
-        w_type = space.type(w_self)
+        w_type = space.type(self)
         w_obj = space.allocate_instance(W_SetObject, w_type)
         W_SetObject.__init__(w_obj, space, w_iterable)
         return w_obj
 class W_FrozensetObject(W_BaseSetObject):
     hash = 0
 
-    def _newobj(w_self, space, w_iterable):
+    def _newobj(self, space, w_iterable):
         """Make a new frozenset by taking ownership of 'w_iterable'."""
-        if type(w_self) is W_FrozensetObject:
+        if type(self) is W_FrozensetObject:
             return W_FrozensetObject(space, w_iterable)
-        w_type = space.type(w_self)
+        w_type = space.type(self)
         w_obj = space.allocate_instance(W_FrozensetObject, w_type)
         W_FrozensetObject.__init__(w_obj, space, w_iterable)
         return w_obj
 
 class W_SetIterObject(W_Root):
 
-    def __init__(w_self, space, iterimplementation):
-        w_self.space = space
-        w_self.iterimplementation = iterimplementation
+    def __init__(self, space, iterimplementation):
+        self.space = space
+        self.iterimplementation = iterimplementation
 
     def descr_length_hint(self, space):
         return space.wrap(self.iterimplementation.length())

File pypy/objspace/std/specialisedtupleobject.py

View file
 def make_specialised_class(typetuple):
     assert type(typetuple) == tuple
 
-    nValues = len(typetuple)
-    iter_n = unrolling_iterable(range(nValues))
+    typelen = len(typetuple)
+    iter_n = unrolling_iterable(range(typelen))
 
     class cls(W_AbstractTupleObject):
         def __init__(self, space, *values_w):
             self.space = space
-            assert len(values_w) == nValues
+            assert len(values_w) == typelen
             for i in iter_n:
                 w_obj = values_w[i]
                 val_type = typetuple[i]
                 setattr(self, 'value%s' % i, unwrapped)
 
         def length(self):
-            return nValues
+            return typelen
 
         def tolist(self):
-            list_w = [None] * nValues
+            list_w = [None] * typelen
             for i in iter_n:
                 value = getattr(self, 'value%s' % i)
                 if typetuple[i] != object:
         def descr_hash(self, space):
             mult = 1000003
             x = 0x345678
-            z = nValues
+            z = typelen
             for i in iter_n:
                 value = getattr(self, 'value%s' % i)
                 if typetuple[i] == object:
             if not isinstance(w_other, W_AbstractTupleObject):
                 return space.w_NotImplemented
             if not isinstance(w_other, cls):
-                if nValues != w_other.length():
+                if typelen != w_other.length():
                     return space.w_False
                 for i in iter_n:
                     myval = getattr(self, 'value%s' % i)
 
         def getitem(self, space, index):
             if index < 0:
-                index += nValues
+                index += typelen
             for i in iter_n:
                 if index == i:
                     value = getattr(self, 'value%s' % i)

File pypy/objspace/std/test/test_lengthhint.py

View file
         self._test_length_hint(self.space.wrap(u'Y' * self.SIZE))
 
     def test_tuple(self):
-        self._test_length_hint(self.space.newtuple(self.ITEMS))
+        self._test_length_hint(self.space.wrap(tuple(self.ITEMS)))
 
     def test_reversed(self):
         # test the generic reversed iterator (w_foo lacks __reversed__)

File pypy/objspace/std/test/test_stdobjspace.py

File contents unchanged.

File pypy/objspace/std/tupleobject.py

View file
+"""The builtin tuple implementation"""
+
 import sys
-from pypy.interpreter import gateway
+
 from pypy.interpreter.baseobjspace import W_Root
 from pypy.interpreter.error import OperationError
-from pypy.interpreter.gateway import interp2app, interpindirect2app
+from pypy.interpreter.gateway import (
+    WrappedDefault, interp2app, interpindirect2app, unwrap_spec)
 from pypy.objspace.std import slicetype
 from pypy.objspace.std.inttype import wrapint
 from pypy.objspace.std.sliceobject import W_SliceObject, normalize_simple_slice
                 count += 1
         return space.wrap(count)
 
-    @gateway.unwrap_spec(w_start=gateway.WrappedDefault(0),
-                         w_stop=gateway.WrappedDefault(sys.maxint))
+    @unwrap_spec(w_start=WrappedDefault(0), w_stop=WrappedDefault(sys.maxint))
     @jit.look_inside_iff(lambda self, _1, _2, _3, _4: _unroll_condition(self))
     def descr_index(self, space, w_obj, w_start, w_stop):
         """index(obj, [start, [stop]]) -> first index that obj appears in the

File rpython/config/translationoption.py

View file
 from rpython.config.config import ChoiceOption, StrOption, Config
 from rpython.config.config import ConfigError
 from rpython.config.support import detect_number_of_processors
-from rpython.jit.backend.detect_cpu import autodetect
-from rpython.jit.backend.detect_cpu import MODEL_X86, MODEL_X86_NO_SSE2, MODEL_X86_64
 
 DEFL_INLINE_THRESHOLD = 32.4    # just enough to inline add__Int_Int()
 # and just small enough to prevend inlining of some rlist functions.
 
 DEFL_GC = "minimark"
 
-_is_x86 = autodetect() in (MODEL_X86, MODEL_X86_64, MODEL_X86_NO_SSE2)
-
-if sys.platform.startswith("linux") and _is_x86:
+if sys.platform.startswith("linux"):
     DEFL_ROOTFINDER_WITHJIT = "asmgcc"
 else:
     DEFL_ROOTFINDER_WITHJIT = "shadowstack"

File rpython/jit/codewriter/effectinfo.py

View file
     OS_NONE                     = 0    # normal case, no oopspec
     OS_ARRAYCOPY                = 1    # "list.ll_arraycopy"
     OS_STR2UNICODE              = 2    # "str.str2unicode"
+    OS_SHRINK_ARRAY             = 3    # rgc.ll_shrink_array
     #
     OS_STR_CONCAT               = 22   # "stroruni.concat"
     OS_STR_SLICE                = 23   # "stroruni.slice"
     OS_JIT_FORCE_VIRTUAL        = 120
 
     # for debugging:
-    _OS_CANRAISE = set([OS_NONE, OS_STR2UNICODE, OS_LIBFFI_CALL,
-                        OS_RAW_MALLOC_VARSIZE_CHAR, OS_JIT_FORCE_VIRTUAL])
+    _OS_CANRAISE = set([
+        OS_NONE, OS_STR2UNICODE, OS_LIBFFI_CALL, OS_RAW_MALLOC_VARSIZE_CHAR,
+        OS_JIT_FORCE_VIRTUAL, OS_SHRINK_ARRAY,
+    ])
 
     def __new__(cls, readonly_descrs_fields, readonly_descrs_arrays,
                 write_descrs_fields, write_descrs_arrays,

File rpython/jit/codewriter/jtransform.py

View file
             prepare = self._handle_libffi_call
         elif oopspec_name.startswith('math.sqrt'):
             prepare = self._handle_math_sqrt_call
+        elif oopspec_name.startswith('rgc.'):
+            prepare = self._handle_rgc_call
         else:
             prepare = self.prepare_builtin_call
         try:
         return self._handle_oopspec_call(op, args, EffectInfo.OS_MATH_SQRT,
                                          EffectInfo.EF_ELIDABLE_CANNOT_RAISE)
 
+    def _handle_rgc_call(self, op, oopspec_name, args):
+        if oopspec_name == 'rgc.ll_shrink_array':
+            return self._handle_oopspec_call(op, args, EffectInfo.OS_SHRINK_ARRAY, EffectInfo.EF_CAN_RAISE)
+        else:
+            raise NotImplementedError(oopspec_name)
+
     def rewrite_op_jit_force_quasi_immutable(self, op):
         v_inst, c_fieldname = op.args
         descr1 = self.cpu.fielddescrof(v_inst.concretetype.TO,

File rpython/jit/metainterp/optimizeopt/vstring.py

View file
         assert size <= MAX_CONST_LEN
         self._chars = [None] * size
 
+    def shrink(self, length):
+        assert length >= 0
+        del self._chars[length:]
+
     def setup_slice(self, longerlist, start, stop):
         assert 0 <= start <= stop <= len(longerlist)
         self._chars = longerlist[start:stop]
             if oopspecindex == EffectInfo.OS_STR2UNICODE:
                 if self.opt_call_str_STR2UNICODE(op):
                     return
+            if oopspecindex == EffectInfo.OS_SHRINK_ARRAY:
+                if self.opt_call_SHRINK_ARRAY(op):
+                    return
         self.emit_operation(op)
 
     optimize_CALL_PURE = optimize_CALL
             return True
         return False
 
+    def opt_call_SHRINK_ARRAY(self, op):
+        v1 = self.getvalue(op.getarg(1))
+        v2 = self.getvalue(op.getarg(2))
+        # If the index is constant, if the argument is virtual (we only support
+        # VStringPlainValue for now) we can optimize away the call.
+        if v2.is_constant() and v1.is_virtual() and isinstance(v1, VStringPlainValue):
+            length = v2.box.getint()
+            v1.shrink(length)
+            self.last_emitted_operation = REMOVED
+            self.make_equal_to(op.result, v1)
+            return True
+        return False
+
     def generate_modified_call(self, oopspecindex, args, result, mode):
         oopspecindex += mode.OS_offset
         cic = self.optimizer.metainterp_sd.callinfocollection

File rpython/jit/metainterp/test/test_string.py

View file
 import py
 
-from rpython.jit.codewriter.policy import StopAtXPolicy
-from rpython.jit.metainterp.test.support import LLJitMixin, OOJitMixin
+from rpython.jit.metainterp.test.support import LLJitMixin
 from rpython.rlib.debug import debug_print
-from rpython.rlib.jit import JitDriver, dont_look_inside, we_are_jitted,\
-     promote_string
-from rpython.rlib.rstring import StringBuilder
-from rpython.rtyper.ootypesystem import ootype
+from rpython.rlib.jit import (JitDriver, dont_look_inside, we_are_jitted,
+    promote_string)
+from rpython.rlib.rstring import StringBuilder, UnicodeBuilder
 
 
 class StringTests:
-    _str, _chr = str, chr
+    _str, _chr, _StringBuilder = str, chr, StringBuilder
 
     def test_eq_residual(self):
         _str = self._str
         s1 = self.meta_interp(f, [])
         s2 = f()
         for c1, c2 in zip(s1.chars, s2):
-            assert c1==c2
+            assert c1 == c2
 
     def test_virtual_strings_boxed(self):
         _str = self._str
         self.meta_interp(f, [0])
         self.check_resops(call=7)
 
+    def test_join_chars(self):
+        jitdriver = JitDriver(reds=['a', 'b', 'c', 'i'], greens=[])
+        _str = self._str
+
+        def f(a, b, c):
+            i = 0
+            while i < 10:
+                jitdriver.jit_merge_point(a=a, b=b, c=c, i=i)
+                x = []
+                if a:
+                    x.append(_str("a"))
+                if b:
+                    x.append(_str("b"))
+                if c:
+                    x.append(_str("c"))
+                i += len(_str("").join(x))
+            return i
+        res = self.meta_interp(f, [1, 1, 1])
+        assert res == f(True, True, True)
+        # The "".join should be unrolled, since the length of x is known since
+        # it is virtual, ensure there are no calls to ll_join_chars, or
+        # allocations.
+        self.check_resops({'jump': 1, 'guard_true': 5, 'int_lt': 2,
+                           'int_add': 2, 'int_is_true': 3})
+
+    def test_virtual_copystringcontent(self):
+        jitdriver = JitDriver(reds=['n', 'result'], greens=[])
+        _str, _StringBuilder = self._str, self._StringBuilder
+
+        def main(n):
+            result = 0
+            while n >= 0:
+                jitdriver.jit_merge_point(n=n, result=result)
+                b = _StringBuilder(6)
+                b.append(_str("Hello!"))
+                result += ord(b.build()[0])
+                n -= 1
+            return result
+        res = self.meta_interp(main, [9])
+        assert res == main(9)
+
+    def test_virtual_copystringcontent2(self):
+        jitdriver = JitDriver(reds=['n', 'result'], greens=[])
+        _str, _StringBuilder = self._str, self._StringBuilder
+
+        def main(n):
+            result = 0
+            while n >= 0:
+                jitdriver.jit_merge_point(n=n, result=result)
+                b = _StringBuilder(6)
+                b.append(_str("Hello!"))
+                result += ord((b.build() + _str("xyz"))[0])
+                n -= 1
+            return result
+        res = self.meta_interp(main, [9])
+        assert res == main(9)
+
+    def test_bytearray(self):
+        py.test.skip("implement it")
+
+        def f(i):
+            b = bytearray("abc")
+            b[1] = i
+            return b[1]
+
+        res = self.interp_operations(f, [13])
+        assert res == 13
+
+    def test_shrink_array(self):
+        jitdriver = JitDriver(reds=['result', 'n'], greens=[])
+        _str, _StringBuilder = self._str, self._StringBuilder
+
+        def f(n):
+            result = 0
+            while n >= 0:
+                jitdriver.jit_merge_point(n=n, result=result)
+                b = _StringBuilder(20)
+                b.append(_str("Testing!"))
+                result += len(b.build())
+                n -= 1
+            return result
+
+        res = self.meta_interp(f, [9])
+        assert res == f(9)
+        self.check_resops({
+            'jump': 1, 'guard_true': 2, 'int_ge': 2, 'int_add': 2, 'int_sub': 2
+        })
+
+
 #class TestOOtype(StringTests, OOJitMixin):
 #    CALL = "oosend"
 #    CALL_PURE = "oosend_pure"
     CALL = "call"
     CALL_PURE = "call_pure"
 
+
 class TestLLtypeUnicode(TestLLtype):
-    _str, _chr = unicode, unichr
+    _str, _chr, _StringBuilder = unicode, unichr, UnicodeBuilder
 
     def test_str2unicode(self):
         _str = self._str
         self.check_resops(call_pure=0, unicodesetitem=0, call=2,
                           newunicode=0, unicodegetitem=0,
                           copyunicodecontent=0)
-
-    def test_join_chars(self):
-        jitdriver = JitDriver(reds=['a', 'b', 'c', 'i'], greens=[])
-        def f(a, b, c):
-            i = 0
-            while i < 10:
-                jitdriver.jit_merge_point(a=a, b=b, c=c, i=i)
-                x = []
-                if a:
-                    x.append("a")
-                if b:
-                    x.append("b")
-                if c:
-                    x.append("c")
-                i += len("".join(x))
-            return i
-        res = self.meta_interp(f, [1, 1, 1])
-        assert res == f(True, True, True)
-        # The "".join should be unrolled, since the length of x is known since
-        # it is virtual, ensure there are no calls to ll_join_chars, or
-        # allocations.
-        self.check_resops({'jump': 1, 'guard_true': 5, 'int_lt': 2,
-                           'int_add': 2, 'int_is_true': 3})
-
-    def test_virtual_copystringcontent(self):
-        jitdriver = JitDriver(reds=['n', 'result'], greens=[])
-        def main(n):
-            result = 0
-            while n >= 0:
-                jitdriver.jit_merge_point(n=n, result=result)
-                b = StringBuilder(6)
-                b.append("Hello!")
-                result += ord(b.build()[0])
-                n -= 1
-            return result
-        res = self.meta_interp(main, [9])
-        assert res == main(9)
-
-    def test_virtual_copystringcontent2(self):
-        jitdriver = JitDriver(reds=['n', 'result'], greens=[])
-        def main(n):
-            result = 0
-            while n >= 0:
-                jitdriver.jit_merge_point(n=n, result=result)
-                b = StringBuilder(6)
-                b.append("Hello!")
-                result += ord((b.build() + "xyz")[0])
-                n -= 1
-            return result
-        res = self.meta_interp(main, [9])
-        assert res == main(9)
-
-    def test_bytearray(self):
-        py.test.skip("implement it")
-        def f(i):
-            b = bytearray("abc")
-            b[1] = i
-            return b[1]
-
-        res = self.interp_operations(f, [13])
-        assert res == 13

File rpython/rlib/rgc.py

View file
             return True
     return False
 
+
 @jit.oopspec('list.ll_arraycopy(source, dest, source_start, dest_start, length)')
 @enforceargs(None, None, int, int, int)
 @specialize.ll()
     keepalive_until_here(source)
     keepalive_until_here(dest)
 
+
+@jit.oopspec('rgc.ll_shrink_array(p, smallerlength)')
+@specialize.ll()
 def ll_shrink_array(p, smallerlength):
     from rpython.rtyper.lltypesystem.lloperation import llop
     from rpython.rlib.objectmodel import keepalive_until_here
     ARRAY = getattr(TP, TP._arrayfld)
     offset = (llmemory.offsetof(TP, TP._arrayfld) +
               llmemory.itemoffsetof(ARRAY, 0))
-    source_addr = llmemory.cast_ptr_to_adr(p)    + offset
-    dest_addr   = llmemory.cast_ptr_to_adr(newp) + offset
+    source_addr = llmemory.cast_ptr_to_adr(p) + offset
+    dest_addr = llmemory.cast_ptr_to_adr(newp) + offset
     llmemory.raw_memcopy(source_addr, dest_addr,
                          llmemory.sizeof(ARRAY.OF) * smallerlength)
 
     keepalive_until_here(p)
     keepalive_until_here(newp)
     return newp
-ll_shrink_array._annspecialcase_ = 'specialize:ll'
-ll_shrink_array._jit_look_inside_ = False
+
 
 def no_collect(func):
     func._dont_inline_ = True

File rpython/rtyper/module/ll_os.py

View file
 
     @registering_if(os, 'getpid')
     def register_os_getpid(self):
-        return self.extdef_for_os_function_returning_int('getpid')
+        return self.extdef_for_os_function_returning_int('getpid', threadsafe=False)
 
     @registering_if(os, 'getgid')
     def register_os_getgid(self):