[pypy-commit] pypy fix-result-types: hg merge default
rlamy
noreply at buildbot.pypy.org
Tue May 19 19:07:28 CEST 2015
Author: Ronan Lamy <ronan.lamy at gmail.com>
Branch: fix-result-types
Changeset: r77396:593186bc7eee
Date: 2015-05-19 17:37 +0100
http://bitbucket.org/pypy/pypy/changeset/593186bc7eee/
Log: hg merge default
diff --git a/pypy/doc/whatsnew-head.rst b/pypy/doc/whatsnew-head.rst
--- a/pypy/doc/whatsnew-head.rst
+++ b/pypy/doc/whatsnew-head.rst
@@ -109,3 +109,8 @@
branch pythonoptimize-env
Implement PYTHONOPTIMIZE environment variable, fixing issue #2044
+
+.. branch: numpy-flags
+
+branch numpy-flags
+Finish implementation of ndarray.flags, including str() and repr()
diff --git a/pypy/module/micronumpy/base.py b/pypy/module/micronumpy/base.py
--- a/pypy/module/micronumpy/base.py
+++ b/pypy/module/micronumpy/base.py
@@ -22,6 +22,9 @@
"""Base class for ndarrays and scalars (aka boxes)."""
_attrs_ = []
+ def get_flags(self):
+ return 0
+
class W_NDimArray(W_NumpyObject):
__metaclass__ = extendabletype
@@ -134,6 +137,9 @@
def get_start(self):
return self.implementation.start
+ def get_flags(self):
+ return self.implementation.flags
+
def ndims(self):
return len(self.get_shape())
ndims._always_inline_ = True
diff --git a/pypy/module/micronumpy/boxes.py b/pypy/module/micronumpy/boxes.py
--- a/pypy/module/micronumpy/boxes.py
+++ b/pypy/module/micronumpy/boxes.py
@@ -143,6 +143,10 @@
def get_scalar_value(self):
return self
+ def get_flags(self):
+ return (NPY.ARRAY_C_CONTIGUOUS | NPY.ARRAY_F_CONTIGUOUS |
+ NPY.ARRAY_WRITEABLE | NPY.ARRAY_OWNDATA)
+
def item(self, space):
return self.get_dtype(space).itemtype.to_builtin_type(space, self)
diff --git a/pypy/module/micronumpy/concrete.py b/pypy/module/micronumpy/concrete.py
--- a/pypy/module/micronumpy/concrete.py
+++ b/pypy/module/micronumpy/concrete.py
@@ -7,11 +7,12 @@
from rpython.rtyper.lltypesystem import rffi, lltype, llmemory
from pypy.module.micronumpy import support, loop, constants as NPY
from pypy.module.micronumpy.base import convert_to_array, W_NDimArray, \
- ArrayArgumentException
+ ArrayArgumentException, W_NumpyObject
from pypy.module.micronumpy.iterators import ArrayIter
from pypy.module.micronumpy.strides import (Chunk, Chunks, NewAxisChunk,
RecordChunk, calc_strides, calc_new_strides, shape_agreement,
- calculate_broadcast_strides, calc_backstrides, calc_start)
+ calculate_broadcast_strides, calc_backstrides, calc_start, is_c_contiguous,
+ is_f_contiguous)
from rpython.rlib.objectmodel import keepalive_until_here
from rpython.rtyper.annlowlevel import cast_gcref_to_instance
from pypy.interpreter.baseobjspace import W_Root
@@ -19,7 +20,8 @@
class BaseConcreteArray(object):
_immutable_fields_ = ['dtype?', 'storage', 'start', 'size', 'shape[*]',
- 'strides[*]', 'backstrides[*]', 'order', 'gcstruct']
+ 'strides[*]', 'backstrides[*]', 'order', 'gcstruct',
+ 'flags']
start = 0
parent = None
flags = 0
@@ -443,6 +445,11 @@
ConcreteArrayNotOwning.__init__(self, shape, dtype, order, strides, backstrides,
storage, start=start)
self.gcstruct = gcstruct
+ self.flags = NPY.ARRAY_ALIGNED | NPY.ARRAY_WRITEABLE
+ if is_c_contiguous(self):
+ self.flags |= NPY.ARRAY_C_CONTIGUOUS
+ if is_f_contiguous(self):
+ self.flags |= NPY.ARRAY_F_CONTIGUOUS
def __del__(self):
if self.gcstruct:
@@ -456,18 +463,39 @@
ConcreteArrayNotOwning.__init__(self, shape, dtype, order,
strides, backstrides, storage, start)
self.orig_base = orig_base
+ if isinstance(orig_base, W_NumpyObject):
+ self.flags = orig_base.get_flags() & NPY.ARRAY_ALIGNED
+ self.flags |= orig_base.get_flags() & NPY.ARRAY_WRITEABLE
+ else:
+ self.flags = 0
+ if is_c_contiguous(self):
+ self.flags |= NPY.ARRAY_C_CONTIGUOUS
+ if is_f_contiguous(self):
+ self.flags |= NPY.ARRAY_F_CONTIGUOUS
def base(self):
return self.orig_base
class ConcreteNonWritableArrayWithBase(ConcreteArrayWithBase):
+ def __init__(self, shape, dtype, order, strides, backstrides, storage,
+ orig_base, start=0):
+ ConcreteArrayWithBase.__init__(self, shape, dtype, order, strides,
+ backstrides, storage, orig_base, start)
+ self.flags &= ~ NPY.ARRAY_WRITEABLE
+
def descr_setitem(self, space, orig_array, w_index, w_value):
raise OperationError(space.w_ValueError, space.wrap(
"assignment destination is read-only"))
class NonWritableArray(ConcreteArray):
+ def __init__(self, shape, dtype, order, strides, backstrides,
+ storage=lltype.nullptr(RAW_STORAGE), zero=True):
+ ConcreteArray.__init__(self, shape, dtype, order, strides, backstrides,
+ storage, zero)
+ self.flags &= ~ NPY.ARRAY_WRITEABLE
+
def descr_setitem(self, space, orig_array, w_index, w_value):
raise OperationError(space.w_ValueError, space.wrap(
"assignment destination is read-only"))
@@ -491,6 +519,12 @@
self.size = support.product(shape) * self.dtype.elsize
self.start = start
self.orig_arr = orig_arr
+ self.flags = parent.flags & NPY.ARRAY_ALIGNED
+ self.flags |= parent.flags & NPY.ARRAY_WRITEABLE
+ if is_c_contiguous(self):
+ self.flags |= NPY.ARRAY_C_CONTIGUOUS
+ if is_f_contiguous(self):
+ self.flags |= NPY.ARRAY_F_CONTIGUOUS
def base(self):
return self.orig_arr
@@ -538,6 +572,12 @@
return sort_array(self, space, w_axis, w_order)
class NonWritableSliceArray(SliceArray):
+ def __init__(self, start, strides, backstrides, shape, parent, orig_arr,
+ dtype=None):
+ SliceArray.__init__(self, start, strides, backstrides, shape, parent,
+ orig_arr, dtype)
+ self.flags &= ~NPY.ARRAY_WRITEABLE
+
def descr_setitem(self, space, orig_array, w_index, w_value):
raise OperationError(space.w_ValueError, space.wrap(
"assignment destination is read-only"))
@@ -549,6 +589,8 @@
self.gcstruct = V_OBJECTSTORE
self.dtype = dtype
self.size = size
+ self.flags = (NPY.ARRAY_C_CONTIGUOUS | NPY.ARRAY_F_CONTIGUOUS |
+ NPY.ARRAY_WRITEABLE | NPY.ARRAY_ALIGNED)
def __del__(self):
free_raw_storage(self.storage)
diff --git a/pypy/module/micronumpy/constants.py b/pypy/module/micronumpy/constants.py
--- a/pypy/module/micronumpy/constants.py
+++ b/pypy/module/micronumpy/constants.py
@@ -77,8 +77,20 @@
WRAP = 1
RAISE = 2
+# These can be requested in constructor functions and tested for
ARRAY_C_CONTIGUOUS = 0x0001
ARRAY_F_CONTIGUOUS = 0x0002
+ARRAY_ALIGNED = 0x0100
+ARRAY_WRITEABLE = 0x0400
+ARRAY_UPDATEIFCOPY = 0x1000 # base contains a ref to an array, update it too
+# These can be tested for
+ARRAY_OWNDATA = 0x004
+# These can be requested in constructor functions
+ARRAY_FORECAST = 0x0010 # causes a cast to occur even if not safe to do so
+ARRAY_ENSURECOPY = 0x0020 # returned array will be CONTIGUOUS, ALIGNED, WRITEABLE
+ARRAY_ENSUREARRAY = 0x0040 # return only ndarray, not subtype
+ARRAY_ELEMENTSTRIDES = 0x0080 # strides are units of the dtype element size
+ARRAY_NOTSWAPPED = 0x0200 #native byte order
LITTLE = '<'
BIG = '>'
diff --git a/pypy/module/micronumpy/flagsobj.py b/pypy/module/micronumpy/flagsobj.py
--- a/pypy/module/micronumpy/flagsobj.py
+++ b/pypy/module/micronumpy/flagsobj.py
@@ -1,4 +1,5 @@
from rpython.rlib import jit
+from rpython.rlib.rstring import StringBuilder
from pypy.interpreter.baseobjspace import W_Root
from pypy.interpreter.error import OperationError
@@ -13,54 +14,55 @@
def clear_flags(arr, flags):
arr.flags &= ~flags
-def _update_contiguous_flags(arr):
- is_c_contig = is_c_contiguous(arr)
- if is_c_contig:
- enable_flags(arr, NPY.ARRAY_C_CONTIGUOUS)
- else:
- clear_flags(arr, NPY.ARRAY_C_CONTIGUOUS)
-
- is_f_contig = is_f_contiguous(arr)
- if is_f_contig:
- enable_flags(arr, NPY.ARRAY_F_CONTIGUOUS)
- else:
- clear_flags(arr, NPY.ARRAY_F_CONTIGUOUS)
-
+def get_tf_str(flags, key):
+ if flags & key:
+ return 'True'
+ return 'False'
class W_FlagsObject(W_Root):
def __init__(self, arr):
- self.flags = 0
+ if arr:
+ self.flags = arr.get_flags()
+ else:
+ self.flags = (NPY.ARRAY_C_CONTIGUOUS | NPY.ARRAY_F_CONTIGUOUS |
+ NPY.ARRAY_OWNDATA | NPY.ARRAY_ALIGNED)
def descr__new__(space, w_subtype):
self = space.allocate_instance(W_FlagsObject, w_subtype)
W_FlagsObject.__init__(self, None)
return self
- def descr_get_contiguous(self, space):
- return space.w_True
+ def descr_c_contiguous(self, space):
+ return space.wrap(bool(self.flags & NPY.ARRAY_C_CONTIGUOUS))
- def descr_get_fortran(self, space):
- return space.w_False
+ def descr_f_contiguous(self, space):
+ return space.wrap(bool(self.flags & NPY.ARRAY_F_CONTIGUOUS))
def descr_get_writeable(self, space):
- return space.w_True
+ return space.wrap(bool(self.flags & NPY.ARRAY_WRITEABLE))
+
+ def descr_get_owndata(self, space):
+ return space.wrap(bool(self.flags & NPY.ARRAY_OWNDATA))
+
+ def descr_get_aligned(self, space):
+ return space.wrap(bool(self.flags & NPY.ARRAY_ALIGNED))
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)))
+ return space.wrap(bool(
+ self.flags & NPY.ARRAY_F_CONTIGUOUS and not
+ self.flags & NPY.ARRAY_C_CONTIGUOUS ))
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)))
+ return space.wrap(bool(
+ self.flags & NPY.ARRAY_F_CONTIGUOUS or
+ self.flags & NPY.ARRAY_C_CONTIGUOUS ))
def descr_getitem(self, space, w_item):
key = space.str_w(w_item)
if key == "C" or key == "CONTIGUOUS" or key == "C_CONTIGUOUS":
- return self.descr_get_contiguous(space)
+ return self.descr_c_contiguous(space)
if key == "F" or key == "FORTRAN" or key == "F_CONTIGUOUS":
- return self.descr_get_fortran(space)
+ return self.descr_f_contiguous(space)
if key == "W" or key == "WRITEABLE":
return self.descr_get_writeable(space)
if key == "FNC":
@@ -85,6 +87,22 @@
def descr_ne(self, space, w_other):
return space.wrap(not self.eq(space, w_other))
+ def descr___str__(self, space):
+ s = StringBuilder()
+ s.append(' C_CONTIGUOUS : ')
+ s.append(get_tf_str(self.flags, NPY.ARRAY_C_CONTIGUOUS))
+ s.append('\n F_CONTIGUOUS : ')
+ s.append(get_tf_str(self.flags, NPY.ARRAY_F_CONTIGUOUS))
+ s.append('\n OWNDATA : ')
+ s.append(get_tf_str(self.flags, NPY.ARRAY_OWNDATA))
+ s.append('\n WRITEABLE : ')
+ s.append(get_tf_str(self.flags, NPY.ARRAY_WRITEABLE))
+ s.append('\n ALIGNED : ')
+ s.append(get_tf_str(self.flags, NPY.ARRAY_ALIGNED))
+ s.append('\n UPDATEIFCOPY : ')
+ s.append(get_tf_str(self.flags, NPY.ARRAY_UPDATEIFCOPY))
+ return space.wrap(s.build())
+
W_FlagsObject.typedef = TypeDef("numpy.flagsobj",
__new__ = interp2app(W_FlagsObject.descr__new__.im_func),
@@ -92,12 +110,16 @@
__setitem__ = interp2app(W_FlagsObject.descr_setitem),
__eq__ = interp2app(W_FlagsObject.descr_eq),
__ne__ = interp2app(W_FlagsObject.descr_ne),
+ __str__ = interp2app(W_FlagsObject.descr___str__),
+ __repr__ = interp2app(W_FlagsObject.descr___str__),
- contiguous = GetSetProperty(W_FlagsObject.descr_get_contiguous),
- c_contiguous = GetSetProperty(W_FlagsObject.descr_get_contiguous),
- f_contiguous = GetSetProperty(W_FlagsObject.descr_get_fortran),
- fortran = GetSetProperty(W_FlagsObject.descr_get_fortran),
+ contiguous = GetSetProperty(W_FlagsObject.descr_c_contiguous),
+ c_contiguous = GetSetProperty(W_FlagsObject.descr_c_contiguous),
+ f_contiguous = GetSetProperty(W_FlagsObject.descr_f_contiguous),
+ fortran = GetSetProperty(W_FlagsObject.descr_f_contiguous),
writeable = GetSetProperty(W_FlagsObject.descr_get_writeable),
+ owndata = GetSetProperty(W_FlagsObject.descr_get_owndata),
+ aligned = GetSetProperty(W_FlagsObject.descr_get_aligned),
fnc = GetSetProperty(W_FlagsObject.descr_get_fnc),
forc = GetSetProperty(W_FlagsObject.descr_get_forc),
)
diff --git a/pypy/module/micronumpy/iterators.py b/pypy/module/micronumpy/iterators.py
--- a/pypy/module/micronumpy/iterators.py
+++ b/pypy/module/micronumpy/iterators.py
@@ -39,8 +39,6 @@
from rpython.rlib import jit
from pypy.module.micronumpy import support, constants as NPY
from pypy.module.micronumpy.base import W_NDimArray
-from pypy.module.micronumpy.flagsobj import _update_contiguous_flags
-
class PureShapeIter(object):
def __init__(self, shape, idx_w):
@@ -96,7 +94,6 @@
@jit.unroll_safe
def __init__(self, array, size, shape, strides, backstrides):
assert len(shape) == len(strides) == len(backstrides)
- _update_contiguous_flags(array)
self.contiguous = (array.flags & NPY.ARRAY_C_CONTIGUOUS and
array.shape == shape and array.strides == strides)
diff --git a/pypy/module/micronumpy/nditer.py b/pypy/module/micronumpy/nditer.py
--- a/pypy/module/micronumpy/nditer.py
+++ b/pypy/module/micronumpy/nditer.py
@@ -4,7 +4,7 @@
from pypy.interpreter.gateway import interp2app, unwrap_spec, WrappedDefault
from pypy.interpreter.error import OperationError, oefmt
from pypy.module.micronumpy import support, concrete
-from pypy.module.micronumpy.base import W_NDimArray, convert_to_array
+from pypy.module.micronumpy.base import W_NDimArray, convert_to_array, W_NumpyObject
from pypy.module.micronumpy.descriptor import decode_w_dtype
from pypy.module.micronumpy.iterators import ArrayIter
from pypy.module.micronumpy.strides import (calculate_broadcast_strides,
@@ -364,7 +364,7 @@
return ret
-class W_NDIter(W_Root):
+class W_NDIter(W_NumpyObject):
_immutable_fields_ = ['ndim', ]
def __init__(self, space, w_seq, w_flags, w_op_flags, w_op_dtypes,
w_casting, w_op_axes, w_itershape, buffersize=0, order='K'):
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
@@ -9,6 +9,10 @@
b = type(a.flags)()
assert b is not a.flags
assert b['C'] is True
+ s = str(b)
+ assert s == '%s' %(' C_CONTIGUOUS : True\n F_CONTIGUOUS : True'
+ '\n OWNDATA : True\n WRITEABLE : False'
+ '\n ALIGNED : True\n UPDATEIFCOPY : False')
def test_repr(self):
import numpy as np
diff --git a/pypy/module/micronumpy/test/test_iterators.py b/pypy/module/micronumpy/test/test_iterators.py
--- a/pypy/module/micronumpy/test/test_iterators.py
+++ b/pypy/module/micronumpy/test/test_iterators.py
@@ -1,5 +1,7 @@
from pypy.module.micronumpy import support
from pypy.module.micronumpy.iterators import ArrayIter
+from pypy.module.micronumpy.strides import is_c_contiguous, is_f_contiguous
+from pypy.module.micronumpy import constants as NPY
class MockArray(object):
@@ -12,6 +14,10 @@
self.shape = shape
self.strides = strides
self.start = start
+ if is_c_contiguous(self):
+ self.flags |= NPY.ARRAY_C_CONTIGUOUS
+ if is_f_contiguous(self):
+ self.flags |= NPY.ARRAY_F_CONTIGUOUS
def get_shape(self):
return self.shape
diff --git a/pypy/module/micronumpy/test/test_ndarray.py b/pypy/module/micronumpy/test/test_ndarray.py
--- a/pypy/module/micronumpy/test/test_ndarray.py
+++ b/pypy/module/micronumpy/test/test_ndarray.py
@@ -258,17 +258,6 @@
# 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']
-
x = array([[0, 2], [1, 1], [2, 0]])
y = array(x.T, dtype=float)
assert (y == x.T).all()
@@ -2588,6 +2577,18 @@
assert a[0][1][1] == 13
assert a[1][2][1] == 15
+ def test_create_order(self):
+ import sys, numpy as np
+ for order in [False, True, 'C', 'F']:
+ a = np.empty((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'], "flags['C'] False for %r" % order
+ assert not a.flags['F']
+
def test_setitem_slice(self):
import numpy
a = numpy.zeros((3, 4))
diff --git a/pypy/objspace/descroperation.py b/pypy/objspace/descroperation.py
--- a/pypy/objspace/descroperation.py
+++ b/pypy/objspace/descroperation.py
@@ -759,9 +759,26 @@
noninplacespacemethod = specialname[3:-2]
if noninplacespacemethod in ['or', 'and']:
noninplacespacemethod += '_' # not too clean
+ seq_bug_compat = (symbol == '+=' or symbol == '*=')
+ rhs_method = '__r' + specialname[3:]
+
def inplace_impl(space, w_lhs, w_rhs):
w_impl = space.lookup(w_lhs, specialname)
if w_impl is not None:
+ # 'seq_bug_compat' is for cpython bug-to-bug compatibility:
+ # see objspace/test/test_descrobject.*rmul_overrides.
+ # For cases like "list += object-overriding-__radd__".
+ if (seq_bug_compat and space.type(w_lhs).flag_sequence_bug_compat
+ and not space.type(w_rhs).flag_sequence_bug_compat):
+ w_res = _invoke_binop(space, space.lookup(w_rhs, rhs_method),
+ w_rhs, w_lhs)
+ if w_res is not None:
+ return w_res
+ # xxx if __radd__ is defined but returns NotImplemented,
+ # then it might be called again below. Oh well, too bad.
+ # Anyway that's a case where we're likely to end up in
+ # a TypeError.
+ #
w_res = space.get_and_call_function(w_impl, w_lhs, w_rhs)
if _check_notimplemented(space, w_res):
return w_res
diff --git a/pypy/objspace/test/test_descroperation.py b/pypy/objspace/test/test_descroperation.py
--- a/pypy/objspace/test/test_descroperation.py
+++ b/pypy/objspace/test/test_descroperation.py
@@ -759,6 +759,12 @@
assert bytearray('2') * oops() == 42
assert 1000 * oops() == 42
assert '2'.__mul__(oops()) == '222'
+ x = '2'
+ x *= oops()
+ assert x == 42
+ x = [2]
+ x *= oops()
+ assert x == 42
def test_sequence_rmul_overrides_oldstyle(self):
class oops:
@@ -783,6 +789,12 @@
assert [2] + A1([3]) == [2, 3]
assert type([2] + A1([3])) is list
assert [2] + A2([3]) == 42
+ x = "2"
+ x += A2([3])
+ assert x == 42
+ x = [2]
+ x += A2([3])
+ assert x == 42
def test_data_descriptor_without_delete(self):
class D(object):
diff --git a/rpython/jit/metainterp/test/test_fficall.py b/rpython/jit/metainterp/test/test_fficall.py
--- a/rpython/jit/metainterp/test/test_fficall.py
+++ b/rpython/jit/metainterp/test/test_fficall.py
@@ -53,15 +53,12 @@
cif_description = get_description(atypes, rtype)
- expected_args = []
- for avalue in avalues:
- if lltype.typeOf(avalue) == rffi.ULONG:
- avalue = intmask(avalue)
- expected_args.append(avalue)
- expected_args = tuple(expected_args)
-
def verify(*args):
- assert args == expected_args
+ for a, exp_a in zip(args, avalues):
+ if (lltype.typeOf(exp_a) == rffi.ULONG and
+ lltype.typeOf(a) == lltype.Signed):
+ a = rffi.cast(rffi.ULONG, a)
+ assert a == exp_a
return rvalue
FUNC = lltype.FuncType([lltype.typeOf(avalue) for avalue in avalues],
lltype.typeOf(rvalue))
More information about the pypy-commit
mailing list