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