Author: Ronan Lamy <ronan.l...@gmail.com> Branch: issue-2148 Changeset: r79980:4da2050ae801 Date: 2015-10-04 03:28 +0100 http://bitbucket.org/pypy/pypy/changeset/4da2050ae801/
Log: Move find_shape_and_elems() to ctors.py, since it's only used there diff --git a/pypy/module/micronumpy/ctors.py b/pypy/module/micronumpy/ctors.py --- a/pypy/module/micronumpy/ctors.py +++ b/pypy/module/micronumpy/ctors.py @@ -3,10 +3,12 @@ from rpython.rlib.buffer import SubBuffer from rpython.rlib.rstring import strip_spaces from rpython.rtyper.lltypesystem import lltype, rffi + from pypy.module.micronumpy import descriptor, loop, support from pypy.module.micronumpy.base import ( W_NDimArray, convert_to_array, W_NumpyObject) from pypy.module.micronumpy.converters import shape_converter +from . import constants as NPY def build_scalar(space, w_dtype, w_state): @@ -82,7 +84,6 @@ return w_res def _array(space, w_object, w_dtype=None, copy=True, w_order=None, subok=False): - from pypy.module.micronumpy import strides # for anything that isn't already an array, try __array__ method first if not isinstance(w_object, W_NDimArray): @@ -143,7 +144,7 @@ w_base=w_base, start=imp.start) else: # not an array - shape, elems_w = strides.find_shape_and_elems(space, w_object, dtype) + shape, elems_w = find_shape_and_elems(space, w_object, dtype) if dtype is None and space.isinstance_w(w_object, space.w_buffer): dtype = descriptor.get_dtype_cache(space).w_uint8dtype if dtype is None or (dtype.is_str_or_unicode() and dtype.elsize < 1): @@ -165,7 +166,6 @@ def numpify(space, w_object): """Convert the object to a W_NumpyObject""" # XXX: code duplication with _array() - from pypy.module.micronumpy import strides if isinstance(w_object, W_NumpyObject): return w_object # for anything that isn't already an array, try __array__ method first @@ -173,7 +173,7 @@ if w_array is not None: return w_array - shape, elems_w = strides.find_shape_and_elems(space, w_object, None) + shape, elems_w = find_shape_and_elems(space, w_object, None) dtype = find_dtype_for_seq(space, elems_w, None) if dtype is None: dtype = descriptor.get_dtype_cache(space).w_float64dtype @@ -188,6 +188,64 @@ loop.assign(space, w_arr, elems_w) return w_arr +def find_shape_and_elems(space, w_iterable, dtype): + isstr = space.isinstance_w(w_iterable, space.w_str) + if not support.issequence_w(space, w_iterable) or isstr: + if dtype is None or dtype.char != NPY.CHARLTR: + return [], [w_iterable] + is_rec_type = dtype is not None and dtype.is_record() + if is_rec_type and is_single_elem(space, w_iterable, is_rec_type): + return [], [w_iterable] + if isinstance(w_iterable, W_NDimArray) and w_iterable.is_scalar(): + return [], [w_iterable] + return _find_shape_and_elems(space, w_iterable, is_rec_type) + + +def _find_shape_and_elems(space, w_iterable, is_rec_type): + from pypy.objspace.std.bufferobject import W_Buffer + shape = [space.len_w(w_iterable)] + if space.isinstance_w(w_iterable, space.w_buffer): + batch = [space.wrap(0)] * shape[0] + for i in range(shape[0]): + batch[i] = space.ord(space.getitem(w_iterable, space.wrap(i))) + else: + batch = space.listview(w_iterable) + while True: + if not batch: + return shape[:], [] + if is_single_elem(space, batch[0], is_rec_type): + for w_elem in batch: + if not is_single_elem(space, w_elem, is_rec_type): + raise OperationError(space.w_ValueError, space.wrap( + "setting an array element with a sequence")) + return shape[:], batch + new_batch = [] + size = space.len_w(batch[0]) + for w_elem in batch: + if (is_single_elem(space, w_elem, is_rec_type) or + 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 + +def is_single_elem(space, w_elem, is_rec_type): + 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 + space.isinstance_w(w_elem, space.w_list)): + return False + if isinstance(w_elem, W_NDimArray) and not w_elem.is_scalar(): + return False + return True + def _dtype_guess(space, dtype, w_elem): from .casting import scalar2dtype, find_binop_result_dtype if isinstance(w_elem, W_NDimArray) and w_elem.is_scalar(): 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 @@ -189,67 +189,6 @@ return rstrides, rbackstrides -def is_single_elem(space, w_elem, is_rec_type): - 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 - space.isinstance_w(w_elem, space.w_list)): - return False - if isinstance(w_elem, W_NDimArray) and not w_elem.is_scalar(): - return False - return True - - -def find_shape_and_elems(space, w_iterable, dtype): - isstr = space.isinstance_w(w_iterable, space.w_str) - if not support.issequence_w(space, w_iterable) or isstr: - if dtype is None or dtype.char != NPY.CHARLTR: - return [], [w_iterable] - is_rec_type = dtype is not None and dtype.is_record() - if is_rec_type and is_single_elem(space, w_iterable, is_rec_type): - return [], [w_iterable] - if isinstance(w_iterable, W_NDimArray) and w_iterable.is_scalar(): - return [], [w_iterable] - return _find_shape_and_elems(space, w_iterable, is_rec_type) - - -def _find_shape_and_elems(space, w_iterable, is_rec_type): - from pypy.objspace.std.bufferobject import W_Buffer - shape = [space.len_w(w_iterable)] - if space.isinstance_w(w_iterable, space.w_buffer): - batch = [space.wrap(0)] * shape[0] - for i in range(shape[0]): - batch[i] = space.ord(space.getitem(w_iterable, space.wrap(i))) - else: - batch = space.listview(w_iterable) - while True: - if not batch: - return shape[:], [] - if is_single_elem(space, batch[0], is_rec_type): - for w_elem in batch: - if not is_single_elem(space, w_elem, is_rec_type): - raise OperationError(space.w_ValueError, space.wrap( - "setting an array element with a sequence")) - return shape[:], batch - new_batch = [] - size = space.len_w(batch[0]) - for w_elem in batch: - if (is_single_elem(space, w_elem, is_rec_type) or - 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 - - - @jit.unroll_safe def shape_agreement(space, shape1, w_arr2, broadcast_down=True): if w_arr2 is None: 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 @@ -169,7 +169,7 @@ [1, 1, 1, 105, 105] def test_find_shape(self): - from pypy.module.micronumpy.strides import find_shape_and_elems + from pypy.module.micronumpy.ctors import find_shape_and_elems space = self.space shape, elems = find_shape_and_elems(space, @@ -2485,7 +2485,7 @@ x = array([(u'a', 'b')], dtype=t) x['a'] = u'1' assert str(x) == "[(u'1', 'b')]" - + def test_boolean_indexing(self): import numpy as np @@ -2709,7 +2709,7 @@ "input array from shape (3,1) into shape (3)" a[:, 1] = b[:,0] > 0.5 assert (a == [[0, 1], [0, 1], [0, 1]]).all() - + def test_ufunc(self): from numpy import array @@ -3868,7 +3868,7 @@ assert a[0]['y'] == 2 assert a[1]['y'] == 1 - + a = array([(1, [])], dtype=[('a', int32), ('b', int32, 0)]) assert a['b'].shape == (1, 0) b = loads(dumps(a)) _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit