Author: Philip Jenvey <pjen...@underboss.org>
Branch: py3k
Changeset: r68475:c9fe258e0217
Date: 2013-12-18 15:40 -0800
http://bitbucket.org/pypy/pypy/changeset/c9fe258e0217/

Log:    merge default

diff --git a/pypy/module/__builtin__/app_operation.py 
b/pypy/module/__builtin__/app_operation.py
--- a/pypy/module/__builtin__/app_operation.py
+++ b/pypy/module/__builtin__/app_operation.py
@@ -2,8 +2,8 @@
 
 def bin(x):
     """Return the binary representation of an integer."""
-    x = operator.index(x)
-    return x.__format__("#b")
+    value = operator.index(x)
+    return value.__format__("#b")
 
 def oct(x):
     """Return the octal representation of an integer."""
diff --git a/pypy/module/__builtin__/test/test_builtin.py 
b/pypy/module/__builtin__/test/test_builtin.py
--- a/pypy/module/__builtin__/test/test_builtin.py
+++ b/pypy/module/__builtin__/test/test_builtin.py
@@ -84,6 +84,15 @@
         assert bin(-2) == "-0b10"
         assert bin(Foo()) == "0b100"
         raises(TypeError, bin, 0.)
+        class C(object):
+            def __index__(self):
+                return 42
+        assert bin(C()) == bin(42)
+        class D(object):
+            def __int__(self):
+                return 42
+        exc = raises(TypeError, bin, D())
+        assert "index" in exc.value.message
 
     def test_oct(self):
         class Foo:
diff --git a/pypy/module/_cffi_backend/cbuffer.py 
b/pypy/module/_cffi_backend/cbuffer.py
--- a/pypy/module/_cffi_backend/cbuffer.py
+++ b/pypy/module/_cffi_backend/cbuffer.py
@@ -5,7 +5,9 @@
 from pypy.interpreter.typedef import TypeDef, make_weakref_descr
 from pypy.module._cffi_backend import cdataobj, ctypeptr, ctypearray
 
+from rpython.rtyper.annlowlevel import llstr
 from rpython.rtyper.lltypesystem import rffi
+from rpython.rtyper.lltypesystem.rstr import copy_string_to_raw
 
 
 class LLBuffer(RWBuffer):
@@ -34,8 +36,7 @@
 
     def setslice(self, start, string):
         raw_cdata = rffi.ptradd(self.raw_cdata, start)
-        for i in range(len(string)):
-            raw_cdata[i] = string[i]
+        copy_string_to_raw(llstr(string), raw_cdata, 0, len(string))
 
 
 class MiniBuffer(W_Root):
diff --git a/pypy/module/_cffi_backend/cdataobj.py 
b/pypy/module/_cffi_backend/cdataobj.py
--- a/pypy/module/_cffi_backend/cdataobj.py
+++ b/pypy/module/_cffi_backend/cdataobj.py
@@ -206,8 +206,7 @@
                 w_value.get_array_length() == length):
                 # fast path: copying from exactly the correct type
                 s = w_value._cdata
-                for i in range(ctitemsize * length):
-                    cdata[i] = s[i]
+                rffi.c_memcpy(cdata, s, ctitemsize * length)
                 keepalive_until_here(w_value)
                 return
         #
@@ -259,7 +258,6 @@
         space = self.space
         if isinstance(w_other, W_CData):
             from pypy.module._cffi_backend import ctypeptr, ctypearray
-            from pypy.module._cffi_backend import ctypevoid
             ct = w_other.ctype
             if isinstance(ct, ctypearray.W_CTypeArray):
                 ct = ct.ctptr
diff --git a/pypy/module/math/app_math.py b/pypy/module/math/app_math.py
--- a/pypy/module/math/app_math.py
+++ b/pypy/module/math/app_math.py
@@ -1,7 +1,9 @@
 import sys
 
 def factorial(x):
-    """Find x!."""
+    """factorial(x) -> Integral
+
+    "Find x!. Raise a ValueError if x is negative or non-integral."""
     if isinstance(x, float):
         fl = int(x)
         if fl != x:
@@ -18,15 +20,15 @@
             res *= i
         return res
 
-    #Experimentally this gap seems good
-    gap = max(100, x>>7)
+    # Experimentally this gap seems good
+    gap = max(100, x >> 7)
     def _fac_odd(low, high):
-        if low+gap >= high:
+        if low + gap >= high:
             t = 1
             for i in range(low, high, 2):
                 t *= i
             return t
-        
+
         mid = ((low + high) >> 1) | 1
         return _fac_odd(low, mid) * _fac_odd(mid, high)
 
diff --git a/pypy/module/micronumpy/arrayimpl/concrete.py 
b/pypy/module/micronumpy/arrayimpl/concrete.py
--- a/pypy/module/micronumpy/arrayimpl/concrete.py
+++ b/pypy/module/micronumpy/arrayimpl/concrete.py
@@ -502,3 +502,6 @@
 
     def getlength(self):
         return self.impl.size
+
+    def get_raw_address(self):
+        return self.impl.storage
diff --git a/pypy/module/micronumpy/arrayimpl/scalar.py 
b/pypy/module/micronumpy/arrayimpl/scalar.py
--- a/pypy/module/micronumpy/arrayimpl/scalar.py
+++ b/pypy/module/micronumpy/arrayimpl/scalar.py
@@ -132,6 +132,12 @@
         if space.isinstance_w(w_idx, space.w_tuple):
             if space.len_w(w_idx) == 0:
                 return self.get_scalar_value()
+        if space.is_none(w_idx):
+            new_shape = [1]
+            arr = W_NDimArray.from_shape(space, new_shape, self.dtype)
+            arr_iter = arr.create_iter(new_shape)
+            arr_iter.setitem(self.value)
+            return arr
         raise OperationError(space.w_IndexError,
                              space.wrap("0-d arrays can't be indexed"))
 
diff --git a/pypy/module/micronumpy/interp_boxes.py 
b/pypy/module/micronumpy/interp_boxes.py
--- a/pypy/module/micronumpy/interp_boxes.py
+++ b/pypy/module/micronumpy/interp_boxes.py
@@ -158,6 +158,12 @@
         assert isinstance(box, W_Float64Box)
         return space.wrap(box.value)
 
+    def descr_oct(self, space):
+        return space.oct(self.descr_int(space))
+
+    def descr_hex(self, space):
+        return space.hex(self.descr_int(space))
+
     def descr_nonzero(self, space):
         dtype = self.get_dtype(space)
         return space.wrap(dtype.itemtype.bool(self))
@@ -506,6 +512,8 @@
     __int__ = interp2app(W_GenericBox.descr_int),
     __float__ = interp2app(W_GenericBox.descr_float),
     __bool__ = interp2app(W_GenericBox.descr_nonzero),
+    __oct__ = interp2app(W_GenericBox.descr_oct),
+    __hex__ = interp2app(W_GenericBox.descr_hex),
 
     __add__ = interp2app(W_GenericBox.descr_add),
     __sub__ = interp2app(W_GenericBox.descr_sub),
diff --git a/pypy/module/micronumpy/interp_flagsobj.py 
b/pypy/module/micronumpy/interp_flagsobj.py
--- a/pypy/module/micronumpy/interp_flagsobj.py
+++ b/pypy/module/micronumpy/interp_flagsobj.py
@@ -18,6 +18,16 @@
     def descr_get_writeable(self, space):
         return space.w_True
 
+    def descr_get_fnc(self, space):
+        return space.wrap(
+            space.is_true(self.descr_get_fortran(space)) and not
+            space.is_true(self.descr_get_contiguous(space)))
+
+    def descr_get_forc(self, space):
+        return space.wrap(
+            space.is_true(self.descr_get_fortran(space)) or
+            space.is_true(self.descr_get_contiguous(space)))
+
     def descr_getitem(self, space, w_item):
         key = space.str_w(w_item)
         if key == "C" or key == "CONTIGUOUS" or key == "C_CONTIGUOUS":
@@ -26,6 +36,10 @@
             return self.descr_get_fortran(space)
         if key == "W" or key == "WRITEABLE":
             return self.descr_get_writeable(space)
+        if key == "FNC":
+            return self.descr_get_fnc(space)
+        if key == "FORC":
+            return self.descr_get_forc(space)
         raise OperationError(space.w_KeyError, space.wrap(
             "Unknown flag"))
 
@@ -56,4 +70,6 @@
     f_contiguous = GetSetProperty(W_FlagsObject.descr_get_fortran),
     fortran = GetSetProperty(W_FlagsObject.descr_get_fortran),
     writeable = GetSetProperty(W_FlagsObject.descr_get_writeable),
+    fnc = GetSetProperty(W_FlagsObject.descr_get_fnc),
+    forc = GetSetProperty(W_FlagsObject.descr_get_forc),
 )
diff --git a/pypy/module/micronumpy/interp_numarray.py 
b/pypy/module/micronumpy/interp_numarray.py
--- a/pypy/module/micronumpy/interp_numarray.py
+++ b/pypy/module/micronumpy/interp_numarray.py
@@ -493,8 +493,11 @@
         if not space.is_none(w_dtype):
             raise OperationError(space.w_NotImplementedError, space.wrap(
                 "__array__(dtype) not implemented"))
-        # stub implementation of __array__()
-        return self
+        if type(self) is W_NDimArray:
+            return self
+        return W_NDimArray.from_shape_and_storage(
+            space, self.get_shape(), self.implementation.storage,
+            self.get_dtype(), w_base=self)
 
     def descr_array_iface(self, space):
         addr = self.implementation.get_storage_as_int(space)
@@ -1009,8 +1012,8 @@
         multiarray = numpypy.get("multiarray")
         assert isinstance(multiarray, MixedModule)
         reconstruct = multiarray.get("_reconstruct")
-
-        parameters = space.newtuple([space.gettypefor(W_NDimArray), 
space.newtuple([space.wrap(0)]), space.wrap("b")])
+        parameters = space.newtuple([self.getclass(space),
+                        space.newtuple([space.wrap(0)]), space.wrap("b")])
 
         builder = StringBuilder()
         if isinstance(self.implementation, SliceArray):
@@ -1033,14 +1036,22 @@
         return space.newtuple([reconstruct, parameters, state])
 
     def descr_setstate(self, space, w_state):
-        from rpython.rtyper.lltypesystem import rffi
-
-        shape = space.getitem(w_state, space.wrap(1))
-        dtype = space.getitem(w_state, space.wrap(2))
-        assert isinstance(dtype, interp_dtype.W_Dtype)
-        isfortran = space.getitem(w_state, space.wrap(3))
-        storage = space.getitem(w_state, space.wrap(4))
-
+        lens = space.len_w(w_state)
+        # numpy compatability, see multiarray/methods.c
+        if lens == 5:
+            base_index = 1
+        elif lens == 4:
+            base_index = 0
+        else:
+            raise OperationError(space.w_ValueError, space.wrap(
+                 "__setstate__ called with len(args[1])==%d, not 5 or 4" % 
lens))
+        shape = space.getitem(w_state, space.wrap(base_index))
+        dtype = space.getitem(w_state, space.wrap(base_index+1))
+        isfortran = space.getitem(w_state, space.wrap(base_index+2))
+        storage = space.getitem(w_state, space.wrap(base_index+3))
+        if not isinstance(dtype, interp_dtype.W_Dtype):
+            raise OperationError(space.w_ValueError, space.wrap(
+                 "__setstate__(self, (shape, dtype, .. called with improper 
dtype '%r'" % dtype))
         self.implementation = W_NDimArray.from_shape_and_storage(space,
                 [space.int_w(i) for i in space.listview(shape)],
                 rffi.str2charp(space.str_w(storage), track_allocation=False),
@@ -1056,9 +1067,9 @@
         return w_obj
         pass
 
-@unwrap_spec(offset=int, order=str)
+@unwrap_spec(offset=int)
 def descr_new_array(space, w_subtype, w_shape, w_dtype=None, w_buffer=None,
-                    offset=0, w_strides=None, order='C'):
+                    offset=0, w_strides=None, w_order=None):
     from pypy.module.micronumpy.arrayimpl.concrete import ConcreteArray
     from pypy.module.micronumpy.support import calc_strides
     dtype = space.interp_w(interp_dtype.W_Dtype,
@@ -1092,6 +1103,11 @@
 
     if not shape:
         return W_NDimArray.new_scalar(space, dtype)
+    order = order_converter(space, w_order, NPY_CORDER)
+    if order == NPY_CORDER:
+        order = 'C'
+    else:
+        order = 'F'
     if space.is_w(w_subtype, space.gettypefor(W_NDimArray)):
         return W_NDimArray.from_shape(space, shape, dtype, order)
     strides, backstrides = calc_strides(shape, dtype.base, order)
@@ -1162,6 +1178,7 @@
     __str__ = interp2app(W_NDimArray.descr_str),
     __int__ = interp2app(W_NDimArray.descr_int),
     __float__ = interp2app(W_NDimArray.descr_float),
+    __buffer__ = interp2app(W_NDimArray.descr_get_data),
 
     __pos__ = interp2app(W_NDimArray.descr_pos),
     __neg__ = interp2app(W_NDimArray.descr_neg),
diff --git a/pypy/module/micronumpy/loop.py b/pypy/module/micronumpy/loop.py
--- a/pypy/module/micronumpy/loop.py
+++ b/pypy/module/micronumpy/loop.py
@@ -564,8 +564,11 @@
                 index_w[i] = indexes_w[i]
         w_idx = space.newtuple(prefix_w[:prefixlen] + iter.get_index(space,
                                                                   shapelen))
-        arr.descr_setitem(space, space.newtuple(index_w),
-                          val_arr.descr_getitem(space, w_idx))
+        if val_arr.is_scalar():
+            w_value = val_arr.get_scalar_value()
+        else:
+            w_value = val_arr.descr_getitem(space, w_idx)
+        arr.descr_setitem(space, space.newtuple(index_w), w_value)
         iter.next()
 
 byteswap_driver = jit.JitDriver(name='numpy_byteswap_driver',
diff --git a/pypy/module/micronumpy/strides.py 
b/pypy/module/micronumpy/strides.py
--- a/pypy/module/micronumpy/strides.py
+++ b/pypy/module/micronumpy/strides.py
@@ -51,8 +51,8 @@
             rstrides.append(strides[i])
             rbackstrides.append(backstrides[i])
     if backwards:
-        rstrides = rstrides + [0] * (len(res_shape) - len(orig_shape))  
-        rbackstrides = rbackstrides + [0] * (len(res_shape) - len(orig_shape)) 
+        rstrides = rstrides + [0] * (len(res_shape) - len(orig_shape))
+        rbackstrides = rbackstrides + [0] * (len(res_shape) - len(orig_shape))
     else:
         rstrides = [0] * (len(res_shape) - len(orig_shape)) + rstrides
         rbackstrides = [0] * (len(res_shape) - len(orig_shape)) + rbackstrides
@@ -62,7 +62,7 @@
     if (is_rec_type and space.isinstance_w(w_elem, space.w_tuple)):
         return True
     if (space.isinstance_w(w_elem, space.w_tuple) or
-        isinstance(w_elem, W_NDimArray) or    
+        isinstance(w_elem, W_NDimArray) or
         space.isinstance_w(w_elem, space.w_list)):
         return False
     return True
@@ -87,6 +87,12 @@
                 space.len_w(w_elem) != size):
                 raise OperationError(space.w_ValueError, space.wrap(
                     "setting an array element with a sequence"))
+            w_array = space.lookup(w_elem, '__array__')
+            if w_array is not None:
+                # Make sure we call the array implementation of listview,
+                # since for some ndarray subclasses (matrix, for instance)
+                # listview does not reduce but rather returns the same class
+                w_elem = space.get_and_call_function(w_array, w_elem, 
space.w_None)
             new_batch += space.listview(w_elem)
         shape.append(size)
         batch = new_batch
diff --git a/pypy/module/micronumpy/test/test_flagsobj.py 
b/pypy/module/micronumpy/test/test_flagsobj.py
--- a/pypy/module/micronumpy/test/test_flagsobj.py
+++ b/pypy/module/micronumpy/test/test_flagsobj.py
@@ -12,6 +12,10 @@
         a = np.array([1,2,3])
         assert a.flags.c_contiguous == True
         assert a.flags['W'] == True
+        assert a.flags.fnc == False
+        assert a.flags.forc == True
+        assert a.flags['FNC'] == False
+        assert a.flags['FORC'] == True
         raises(KeyError, "a.flags['blah']")
         raises(KeyError, "a.flags['C_CONTIGUOUS'] = False")
         raises((TypeError, AttributeError), "a.flags.c_contiguous = False")
diff --git a/pypy/module/micronumpy/test/test_numarray.py 
b/pypy/module/micronumpy/test/test_numarray.py
--- a/pypy/module/micronumpy/test/test_numarray.py
+++ b/pypy/module/micronumpy/test/test_numarray.py
@@ -271,6 +271,17 @@
         # test uninitialized value crash?
         assert len(str(a)) > 0
 
+        import sys
+        for order in [False, True, 'C', 'F']:
+            a = ndarray.__new__(ndarray, (2, 3), float, order=order)
+            assert a.shape == (2, 3)
+            if order in [True, 'F'] and '__pypy__' not in 
sys.builtin_module_names:
+                assert a.flags['F']
+                assert not a.flags['C']
+            else:
+                assert a.flags['C']
+                assert not a.flags['F']
+
     def test_ndmin(self):
         from numpypy import array
 
@@ -309,6 +320,12 @@
         e = d.repeat(3, 0)
         assert e.shape == (9, 4, 0)
 
+    def test_buffer(self):
+        import numpy as np
+        a = np.array([1,2,3])
+        b = buffer(a)
+        assert type(b) is buffer
+
     def test_type(self):
         from numpypy import array
         ar = array(range(5))
@@ -623,6 +640,9 @@
             for y in range(2):
                 expected[x, y] = math.cos(a[x]) * math.cos(b[y])
         assert ((cos(a)[:,newaxis] * cos(b).T) == expected).all()
+        a = array(1)[newaxis]
+        assert a == array([1])
+        assert a.shape == (1,)
 
     def test_newaxis_slice(self):
         from numpypy import array, newaxis
@@ -1868,6 +1888,10 @@
         assert (a == [0, 1, 1, 0, 4, 0, 6, 7, 8, 9]).all()
         raises(IndexError, "arange(10)[array([10])] = 3")
         raises(IndexError, "arange(10)[[-11]] = 3")
+        a = zeros(10)
+        b = array([3,4,5])
+        a[b] = 1
+        assert (a == [0, 0, 0, 1, 1, 1, 0, 0, 0, 0]).all()
 
     def test_array_scalar_index(self):
         import numpypy as np
@@ -1941,11 +1965,13 @@
         assert a.itemsize == 3
         a = array(3.1415).astype('S3').dtype
         assert a.itemsize == 3
-        try:
+
+        import sys
+        if '__pypy__' not in sys.builtin_module_names:
             a = array(['1', '2','3']).astype(float)
             assert a[2] == 3.0
-        except NotImplementedError:
-            skip('astype("float") not implemented for str arrays')
+        else:
+            raises(NotImplementedError, array(['1', '2', '3']).astype, float)
 
     def test_base(self):
         from numpypy import array
diff --git a/pypy/module/micronumpy/test/test_scalar.py 
b/pypy/module/micronumpy/test/test_scalar.py
--- a/pypy/module/micronumpy/test/test_scalar.py
+++ b/pypy/module/micronumpy/test/test_scalar.py
@@ -18,6 +18,18 @@
         #raises(TypeError, np.complex_, '1+2j')
         assert math.isnan(np.complex_(None))
 
+    def test_builtin(self):
+        import numpy as np
+        assert oct(np.int32(11)) == '013'
+        assert oct(np.float32(11.6)) == '013'
+        assert oct(np.complex64(11-12j)) == '013'
+        assert hex(np.int32(11)) == '0xb'
+        assert hex(np.float32(11.6)) == '0xb'
+        assert hex(np.complex64(11-12j)) == '0xb'
+        assert bin(np.int32(11)) == '0b1011'
+        exc = raises(TypeError, "bin(np.float32(11.6))")
+        assert exc.value.message.find('object cannot be interpreted as an 
index') != -1
+
     def test_pickle(self):
         from numpypy import dtype, zeros
         try:
diff --git a/pypy/module/micronumpy/test/test_subtype.py 
b/pypy/module/micronumpy/test/test_subtype.py
--- a/pypy/module/micronumpy/test/test_subtype.py
+++ b/pypy/module/micronumpy/test/test_subtype.py
@@ -3,6 +3,7 @@
 
 
 class AppTestSupport(BaseNumpyAppTest):
+    spaceconfig = dict(usemodules=["micronumpy", "struct", "binascii"])
     def setup_class(cls):
         BaseNumpyAppTest.setup_class.im_func(cls)
         cls.w_NoNew = cls.space.appexec([], '''():
@@ -50,6 +51,14 @@
         b[0]=100
         assert a[0,0] == 100
 
+        assert type(a) is not ndarray
+        assert a[0,0] == 100
+        assert a.base is not None
+        b = a.__array__()
+        assert type(b) is ndarray
+        assert b[0,0] == 100
+        assert b.base is a
+
     def test_subtype_view(self):
         from numpypy import ndarray, array
         class matrix(ndarray):
@@ -62,6 +71,11 @@
         assert isinstance(b, matrix)
         assert (b == a).all()
 
+    def test_subtype_like_matrix(self):
+        import numpy as np
+        arr = np.array([1,2,3])
+        ret = np.ndarray.__new__(np.ndarray, arr.shape, arr.dtype, buffer=arr)
+        assert (arr == ret).all()
 
     def test_finalize(self):
         #taken from 
http://docs.scipy.org/doc/numpy/user/basics.subclassing.html#simple-example-adding-an-extra-attribute-to-ndarray
@@ -246,3 +260,116 @@
         c = array(a, float)
         assert c.dtype is dtype(float)
 
+    def test__getitem_modifies_shape(self):
+        import numpypy as N
+        # numpy's matrix class caused an infinite loop
+        class matrix(N.ndarray):
+            getcnt = 0
+            def __new__(subtype, data, dtype=None, copy=True):
+                arr = N.array(data, dtype=dtype, copy=copy)
+                shape = arr.shape
+
+                ret = N.ndarray.__new__(subtype, shape, arr.dtype,
+                                        buffer=arr,
+                                        order=True)
+                return ret
+
+            def __getitem__(self, index):
+                matrix.getcnt += 1
+                if matrix.getcnt > 10:
+                    # XXX strides.find_shape_and_elems is sensitive
+                    # to shape modification
+                    xxx
+                out = N.ndarray.__getitem__(self, index)
+
+                if not isinstance(out, N.ndarray):
+                    return out
+                    # Determine when we should have a column array
+                old_shape = out.shape
+                if out.ndim < 2:
+                    sh = out.shape[0]
+                    try:
+                        n = len(index)
+                    except:
+                        n = 0
+                    if n > 1:
+                        out.shape = (sh, 1)
+                    else:
+                        out.shape = (1, sh)
+                print 'out, shape was',old_shape,'now',out.shape
+                return out
+        a = matrix([[1., 2.]])
+        b = N.array([a])
+
+    def test_setstate_no_version(self):
+        # Some subclasses of ndarray, like MaskedArray, do not use
+        # version in __setstare__
+        from numpy import ndarray, array
+        from pickle import loads, dumps
+        import sys, new
+        class D(ndarray):
+            ''' A subtype with a constructor that accepts a list of
+                data values, where ndarray accepts a shape
+            '''
+            def __new__(subtype, data, dtype=None, copy=True):
+                arr = array(data, dtype=dtype, copy=copy)
+                shape = arr.shape
+                ret = ndarray.__new__(subtype, shape, arr.dtype,
+                                        buffer=arr,
+                                        order=True)
+                return ret
+            def __setstate__(self, state):
+                (version, shp, typ, isf, raw) = state
+                ndarray.__setstate__(self, (shp, typ, isf, raw))
+
+        D.__module__ = 'mod'
+        mod = new.module('mod')
+        mod.D = D
+        sys.modules['mod'] = mod
+        a = D([1., 2.])
+        s = dumps(a)
+        #Taken from numpy version 1.8
+        s_from_numpy = '''ignore this line
+            _reconstruct
+            p0
+            (cmod
+            D
+            p1
+            (I0
+            tp2
+            S'b'
+            p3
+            tp4
+            Rp5
+            (I1
+            (I2
+            tp6
+            cnumpy
+            dtype
+            p7
+            (S'f8'
+            p8
+            I0
+            I1
+            tp9
+            Rp10
+            (I3
+            S'<'
+            p11
+            NNNI-1
+            I-1
+            I0
+            tp12
+            bI00
+            S'\x00\x00\x00\x00\x00\x00\xf0?\x00\x00\x00\x00\x00\x00\x00@'
+            p13
+            tp14
+            b.'''.replace('            ','')
+        for ss,sn in zip(s.split('\n')[1:],s_from_numpy.split('\n')[1:]):
+            if len(ss)>10:
+                # ignore binary data, it will be checked later
+                continue
+            assert ss == sn
+        b = loads(s)
+        assert (a == b).all()
+        assert isinstance(b, D)
diff --git a/pypy/objspace/std/floattype.py b/pypy/objspace/std/floattype.py
--- a/pypy/objspace/std/floattype.py
+++ b/pypy/objspace/std/floattype.py
@@ -27,12 +27,8 @@
 def descr__new__(space, w_floattype, w_x):
     from pypy.objspace.std.floatobject import W_FloatObject
     w_value = w_x     # 'x' is the keyword argument name in CPython
-    w_special = space.lookup(w_value, "__float__")
-    if w_special is not None:
-        w_obj = space.get_and_call_function(w_special, w_value)
-        if not space.isinstance_w(w_obj, space.w_float):
-            raise OperationError(space.w_TypeError,
-                                 space.wrap("__float__ returned non-float"))
+    if space.lookup(w_value, "__float__") is not None:
+        w_obj = space.float(w_value)
         if space.is_w(w_floattype, space.w_float):
             return w_obj
         value = space.float_w(w_obj)
diff --git a/pypy/objspace/std/inttype.py b/pypy/objspace/std/inttype.py
--- a/pypy/objspace/std/inttype.py
+++ b/pypy/objspace/std/inttype.py
@@ -98,41 +98,15 @@
 ##     w_value = w_x     # 'x' is the keyword argument name in CPython
 ##     value = 0
 ##     if w_base is None:
-##         ok = False
 ##         # check for easy cases
 ##         if type(w_value) is W_IntObject:
 ##             value = w_value.intval
-##             ok = True
-##         elif space.isinstance_w(w_value, space.w_str):
-##             value, w_longval = string_to_int_or_long(space, 
space.str_w(w_value))
-##             ok = True
-##         elif space.isinstance_w(w_value, space.w_unicode):
-##             from pypy.objspace.std.unicodeobject import unicode_to_decimal_w
-##             string = unicode_to_decimal_w(space, w_value)
-##             value, w_longval = string_to_int_or_long(space, string)
-##             ok = True
-##         else:
-##             # If object supports the buffer interface
-##             try:
-##                 w_buffer = space.buffer(w_value)
-##             except OperationError, e:
-##                 if not e.match(space, space.w_TypeError):
-##                     raise
-##             else:
-##                 buf = space.interp_w(Buffer, w_buffer)
-##                 value, w_longval = string_to_int_or_long(space, 
buf.as_str())
-##                 ok = True
-
-##         if not ok:
+##         elif space.lookup(w_value, '__int__') is not None or \
+##                 space.lookup(w_value, '__trunc__') is not None:
 ##             # otherwise, use the __int__() or the __trunc__() methods
 ##             w_obj = w_value
 ##             if space.lookup(w_obj, '__int__') is None:
-##                 if space.lookup(w_obj, '__trunc__') is not None:
-##                     w_obj = space.trunc(w_obj)
-##                 else:
-##                     raise operationerrfmt(space.w_TypeError,
-##                         "int() argument must be a string or a number, not 
'%T'",
-##                         w_obj)
+##                 w_obj = space.trunc(w_obj)
 ##             w_obj = space.int(w_obj)
 ##             # 'int(x)' should return what x.__int__() returned, which should
 ##             # be an int or long or a subclass thereof.
@@ -141,13 +115,26 @@
 ##             # int_w is effectively what we want in this case,
 ##             # we cannot construct a subclass of int instance with an
 ##             # an overflowing long
+##             value = space.int_w(w_obj)
+##         elif space.isinstance_w(w_value, space.w_str):
+##             value, w_longval = string_to_int_or_long(space, 
space.str_w(w_value))
+##         elif space.isinstance_w(w_value, space.w_unicode):
+##             from pypy.objspace.std.unicodeobject import unicode_to_decimal_w
+##             string = unicode_to_decimal_w(space, w_value)
+##             value, w_longval = string_to_int_or_long(space, string)
+##         else:
+##             # If object supports the buffer interface
 ##             try:
-##                 value = space.int_w(w_obj)
+##                 w_buffer = space.buffer(w_value)
 ##             except OperationError, e:
-##                 if e.match(space, space.w_TypeError):
-##                     raise OperationError(space.w_ValueError,
-##                         space.wrap("value can't be converted to int"))
-##                 raise e
+##                 if not e.match(space, space.w_TypeError):
+##                     raise
+##                 raise operationerrfmt(space.w_TypeError,
+##                     "int() argument must be a string or a number, not '%T'",
+##                     w_value)
+##             else:
+##                 buf = space.interp_w(Buffer, w_buffer)
+##                 value, w_longval = string_to_int_or_long(space, 
buf.as_str())
 ##     else:
 ##         base = space.int_w(w_base)
 
diff --git a/pypy/objspace/std/longtype.py b/pypy/objspace/std/longtype.py
--- a/pypy/objspace/std/longtype.py
+++ b/pypy/objspace/std/longtype.py
@@ -2,6 +2,7 @@
 from pypy.interpreter import typedef
 from pypy.interpreter.gateway import (
     WrappedDefault, applevel, interp2app, interpindirect2app, unwrap_spec)
+from pypy.interpreter.buffer import Buffer
 from pypy.objspace.std.model import W_Object
 from pypy.objspace.std.stdtypedef import StdTypeDef
 from rpython.rlib.rstring import ParseStringError
@@ -27,6 +28,13 @@
             return w_value
         elif type(w_value) is W_LongObject:
             return newbigint(space, w_longtype, w_value.num)
+        elif space.lookup(w_value, '__int__') is not None:
+            w_obj = space.int(w_value)
+            return newbigint(space, w_longtype, space.bigint_w(w_obj))
+        elif space.lookup(w_value, '__trunc__') is not None:
+            w_obj = space.trunc(w_value)
+            w_obj = space.int(w_obj)
+            return newbigint(space, w_longtype, space.bigint_w(w_obj))
         elif space.isinstance_w(w_value, space.w_unicode):
             from pypy.objspace.std.unicodeobject import unicode_to_decimal_w
             return string_to_w_long(space, w_longtype,
@@ -36,21 +44,17 @@
             strvalue = space.bufferstr_w(w_value)
             return string_to_w_long(space, w_longtype, 
strvalue.decode('latin-1'))
         else:
-            # otherwise, use the __int__() or the __trunc__ methods
-            w_obj = w_value
-            if space.lookup(w_obj, '__int__') is not None:
-                w_obj = space.int(w_obj)
-            elif space.lookup(w_obj, '__trunc__') is not None:
-                w_obj = space.trunc(w_obj)
-                w_obj = space.int(w_obj)
-            else:
+            try:
+                w_buffer = space.buffer(w_value)
+            except OperationError, e:
+                if not e.match(space, space.w_TypeError):
+                    raise
                 raise operationerrfmt(space.w_TypeError,
                     "int() argument must be a string or a number, not '%T'",
-                    w_obj)
-            if space.is_w(w_longtype, space.w_int):
-                return w_obj
-            bigint = space.bigint_w(w_obj)
-            return newbigint(space, w_longtype, bigint)
+                    w_value)
+            else:
+                buf = space.interp_w(Buffer, w_buffer)
+                return string_to_w_long(space, w_longtype, buf.as_str())
     else:
         try:
             base = space.int_w(w_base)
diff --git a/pypy/objspace/std/test/test_intobject.py 
b/pypy/objspace/std/test/test_intobject.py
--- a/pypy/objspace/std/test/test_intobject.py
+++ b/pypy/objspace/std/test/test_intobject.py
@@ -461,9 +461,15 @@
                 return Integral()
         assert int(TruncReturnsNonInt()) == 42
 
+    def test_int_before_string(self):
+        class Integral(str):
+            def __int__(self):
+                return 42
+        assert int(Integral('abc')) == 42
+
     def test_getnewargs(self):
         assert  0 .__getnewargs__() == (0,)
-    
+
     def test_bit_length(self):
         for val, bits in [
             (0, 0),
diff --git a/pypy/objspace/std/test/test_longobject.py 
b/pypy/objspace/std/test/test_longobject.py
--- a/pypy/objspace/std/test/test_longobject.py
+++ b/pypy/objspace/std/test/test_longobject.py
@@ -259,6 +259,8 @@
         n = -sys.maxsize-1
         assert int(n) == n
         assert str(int(n)) == str(n)
+        a = memoryview(b'123')
+        assert int(a) == 123
 
     def test_huge_longs(self):
         import operator
@@ -297,6 +299,12 @@
                 return Integral()
         assert int(TruncReturnsNonInt()) == 42
 
+    def test_long_before_string(self):
+        class A(str):
+            def __long__(self):
+                return 42
+        assert int(A('abc')) == 42
+
     def test_conjugate(self):
         assert (7).conjugate() == 7
         assert (-7).conjugate() == -7
diff --git a/rpython/flowspace/specialcase.py b/rpython/flowspace/specialcase.py
--- a/rpython/flowspace/specialcase.py
+++ b/rpython/flowspace/specialcase.py
@@ -54,6 +54,12 @@
     from rpython.rlib.rfile import create_temp_rfile
     return space.appcall(create_temp_rfile)
 
+@register_flow_sc(os.remove)
+def sc_os_remove(space, *args_w):
+    # on top of PyPy only: 'os.remove != os.unlink'
+    # (on CPython they are '==', but not identical either)
+    return space.appcall(os.unlink, *args_w)
+
 # _________________________________________________________________________
 # a simplified version of the basic printing routines, for RPython programs
 class StdOutBuffer:
diff --git a/rpython/flowspace/test/test_objspace.py 
b/rpython/flowspace/test/test_objspace.py
--- a/rpython/flowspace/test/test_objspace.py
+++ b/rpython/flowspace/test/test_objspace.py
@@ -1244,6 +1244,20 @@
             graph = self.codetest(g)
         assert "Undefined closure variable 'b'" in str(excinfo.value)
 
+    def call_os_remove(msg):
+        os.remove(msg)
+        os.unlink(msg)
+
+    def test_call_os_remove(self):
+        x = self.codetest(self.call_os_remove)
+        simplify_graph(x)
+        self.show(x)
+        ops = x.startblock.operations
+        assert ops[0].opname == 'simple_call'
+        assert ops[0].args[0].value is os.unlink
+        assert ops[1].opname == 'simple_call'
+        assert ops[1].args[0].value is os.unlink
+
 
 DATA = {'x': 5,
         'y': 6}
_______________________________________________
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to