[pypy-commit] pypy py3.5: hg merge default
arigo
pypy.commits at gmail.com
Tue Oct 18 04:47:16 EDT 2016
Author: Armin Rigo <arigo at tunes.org>
Branch: py3.5
Changeset: r87853:48faf85ce555
Date: 2016-10-18 10:46 +0200
http://bitbucket.org/pypy/pypy/changeset/48faf85ce555/
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
@@ -73,11 +73,16 @@
Make optimiseopt iterative instead of recursive so it can be reasoned about
more easily and debugging is faster.
-.. branch: stdlib-2.7.11
+.. branch: Tiberiumk/fix-2412-1476011166874
+.. branch: redirect-assembler-jitlog
-Update stdlib to version 2.7.11
-.. branch: vendor/stdlib
+
.. branch: stdlib-2.7.12
Update stdlib to version 2.7.12
+
+.. branch: buffer-interface2
+
+Improve support for new buffer interface in cpyext, bf_getbuffer on built-in
+types still missing
diff --git a/pypy/interpreter/baseobjspace.py b/pypy/interpreter/baseobjspace.py
--- a/pypy/interpreter/baseobjspace.py
+++ b/pypy/interpreter/baseobjspace.py
@@ -225,7 +225,12 @@
return self._buffer(space, flags).buffer_w_ex(space, flags)
def _buffer(self, space, flags):
- w_impl = space.lookup(self, '__buffer__')
+ if flags & space.BUF_WRITABLE:
+ w_impl = space.lookup(self, '__wbuffer__')
+ else:
+ w_impl = space.lookup(self, '__rbuffer__')
+ if w_impl is None:
+ w_impl = space.lookup(self, '__buffer__')
if w_impl is not None:
w_result = space.get_and_call_function(w_impl, self,
space.newint(flags))
diff --git a/pypy/module/cpyext/include/object.h b/pypy/module/cpyext/include/object.h
--- a/pypy/module/cpyext/include/object.h
+++ b/pypy/module/cpyext/include/object.h
@@ -133,7 +133,7 @@
/* Py3k buffer interface, adapted for PyPy */
#define Py_MAX_NDIMS 32
-#define Py_MAX_FMT 5
+#define Py_MAX_FMT 128
typedef struct bufferinfo {
void *buf;
PyObject *obj; /* owned reference */
diff --git a/pypy/module/cpyext/memoryobject.py b/pypy/module/cpyext/memoryobject.py
--- a/pypy/module/cpyext/memoryobject.py
+++ b/pypy/module/cpyext/memoryobject.py
@@ -4,6 +4,7 @@
from rpython.rtyper.lltypesystem import lltype, rffi
from rpython.rlib.rarithmetic import widen
from pypy.objspace.std.memoryobject import W_MemoryView
+from pypy.module.cpyext.import_ import PyImport_Import
from pypy.interpreter.error import oefmt
from pypy.module.cpyext.pyobject import PyObject, from_ref
@@ -18,23 +19,32 @@
view.c_itemsize = buf.getitemsize()
rffi.setintfield(view, 'c_ndim', ndim)
view.c_format = rffi.cast(rffi.CCHARP, view.c__format)
- view.c_shape = rffi.cast(Py_ssize_tP, view.c__shape)
- view.c_strides = rffi.cast(Py_ssize_tP, view.c__strides)
fmt = buf.getformat()
n = Py_MAX_FMT - 1 # NULL terminated buffer
if len(fmt) > n:
- ### WARN?
- pass
+ w_message = space.newbytes("PyPy specific Py_MAX_FMT is %d which is too "
+ "small for buffer format, %d needed" % (
+ Py_MAX_FMT, len(fmt)))
+ w_stacklevel = space.newint(1)
+ w_module = PyImport_Import(space, space.newbytes("warnings"))
+ w_warn = space.getattr(w_module, space.newbytes("warn"))
+ space.call_function(w_warn, w_message, space.w_None, w_stacklevel)
else:
n = len(fmt)
for i in range(n):
view.c_format[i] = fmt[i]
view.c_format[n] = '\x00'
- shape = buf.getshape()
- strides = buf.getstrides()
- for i in range(ndim):
- view.c_shape[i] = shape[i]
- view.c_strides[i] = strides[i]
+ if ndim > 0:
+ view.c_shape = rffi.cast(Py_ssize_tP, view.c__shape)
+ view.c_strides = rffi.cast(Py_ssize_tP, view.c__strides)
+ shape = buf.getshape()
+ strides = buf.getstrides()
+ for i in range(ndim):
+ view.c_shape[i] = shape[i]
+ view.c_strides[i] = strides[i]
+ else:
+ view.c_shape = lltype.nullptr(Py_ssize_tP.TO)
+ view.c_strides = lltype.nullptr(Py_ssize_tP.TO)
view.c_suboffsets = lltype.nullptr(Py_ssize_tP.TO)
view.c_internal = lltype.nullptr(rffi.VOIDP.TO)
return 0
@@ -77,12 +87,12 @@
@cpython_api([lltype.Ptr(Py_buffer), lltype.Char], rffi.INT_real, error=CANNOT_FAIL)
def PyBuffer_IsContiguous(space, view, fort):
- """Return 1 if the memory defined by the view is C-style (fortran is
- 'C') or Fortran-style (fortran is 'F') contiguous or either one
- (fortran is 'A'). Return 0 otherwise."""
+ """Return 1 if the memory defined by the view is C-style (fort is
+ 'C') or Fortran-style (fort is 'F') contiguous or either one
+ (fort is 'A'). Return 0 otherwise."""
# traverse the strides, checking for consistent stride increases from
# right-to-left (c) or left-to-right (fortran). Copied from cpython
- if not view.c_suboffsets:
+ if view.c_suboffsets:
return 0
if (fort == 'C'):
return _IsCContiguous(view)
@@ -114,6 +124,7 @@
if ndim >= Py_MAX_NDIMS:
# XXX warn?
return view
+ fill_Py_buffer(space, w_obj.buf, view)
try:
view.c_buf = rffi.cast(rffi.VOIDP, w_obj.buf.get_raw_address())
view.c_obj = make_ref(space, w_obj)
@@ -122,9 +133,9 @@
except ValueError:
w_s = w_obj.descr_tobytes(space)
view.c_obj = make_ref(space, w_s)
+ view.c_buf = rffi.cast(rffi.VOIDP, rffi.str2charp(space.str_w(w_s), track_allocation=False))
rffi.setintfield(view, 'c_readonly', 1)
isstr = True
- fill_Py_buffer(space, w_obj.buf, view)
return view
@cpython_api([lltype.Ptr(Py_buffer)], PyObject)
diff --git a/pypy/module/cpyext/pyerrors.py b/pypy/module/cpyext/pyerrors.py
--- a/pypy/module/cpyext/pyerrors.py
+++ b/pypy/module/cpyext/pyerrors.py
@@ -21,7 +21,7 @@
@cpython_api([PyObject, CONST_STRING], lltype.Void)
def PyErr_SetString(space, w_type, message_ptr):
message = rffi.charp2str(message_ptr)
- PyErr_SetObject(space, w_type, space.wrap(message))
+ PyErr_SetObject(space, w_type, space.newbytes(message))
@cpython_api([PyObject], lltype.Void, error=CANNOT_FAIL)
def PyErr_SetNone(space, w_type):
@@ -146,12 +146,12 @@
Return value: always NULL."""
# XXX Doesn't actually do anything with PyErr_CheckSignals.
if llfilename:
- w_filename = rffi.charp2str(llfilename)
- filename = space.wrap(w_filename)
+ filename = rffi.charp2str(llfilename)
+ w_filename = space.newbytes(filename)
else:
- filename = space.w_None
+ w_filename = space.w_None
- PyErr_SetFromErrnoWithFilenameObject(space, w_type, filename)
+ PyErr_SetFromErrnoWithFilenameObject(space, w_type, w_filename)
@cpython_api([PyObject, PyObject], PyObject)
@jit.dont_look_inside # direct use of _get_errno()
@@ -166,13 +166,13 @@
msg = _strerror(errno)
if w_value:
w_error = space.call_function(w_type,
- space.wrap(errno),
- space.wrap(msg),
+ space.newint(errno),
+ space.newbytes(msg),
w_value)
else:
w_error = space.call_function(w_type,
- space.wrap(errno),
- space.wrap(msg))
+ space.newint(errno),
+ space.newbytes(msg))
raise OperationError(w_type, w_error)
@cpython_api([], rffi.INT_real, error=-1)
@@ -250,11 +250,11 @@
documentation. There is no C API for warning control."""
if w_category is None:
w_category = space.w_None
- w_message = space.wrap(rffi.charp2str(message_ptr))
- w_stacklevel = space.wrap(rffi.cast(lltype.Signed, stacklevel))
+ w_message = space.newbytes(rffi.charp2str(message_ptr))
+ w_stacklevel = space.newint(rffi.cast(lltype.Signed, stacklevel))
- w_module = PyImport_Import(space, space.wrap("warnings"))
- w_warn = space.getattr(w_module, space.wrap("warn"))
+ w_module = PyImport_Import(space, space.newbytes("warnings"))
+ w_warn = space.getattr(w_module, space.newbytes("warn"))
space.call_function(w_warn, w_message, w_category, w_stacklevel)
return 0
@@ -315,10 +315,10 @@
@cpython_api([PyObject, PyObject], rffi.INT_real, error=-1)
def PyTraceBack_Print(space, w_tb, w_file):
- space.call_method(w_file, "write", space.wrap(
+ space.call_method(w_file, "write", space.newbytes(
'Traceback (most recent call last):\n'))
w_traceback = space.call_method(space.builtin, '__import__',
- space.wrap("traceback"))
+ space.newbytes("traceback"))
space.call_method(w_traceback, "print_tb", w_tb, space.w_None, w_file)
return 0
diff --git a/pypy/module/cpyext/slotdefs.py b/pypy/module/cpyext/slotdefs.py
--- a/pypy/module/cpyext/slotdefs.py
+++ b/pypy/module/cpyext/slotdefs.py
@@ -14,6 +14,7 @@
getbufferproc, ssizessizeobjargproc)
from pypy.module.cpyext.pyobject import from_ref, make_ref, Py_DecRef
from pypy.module.cpyext.pyerrors import PyErr_Occurred
+from pypy.module.cpyext.memoryobject import fill_Py_buffer
from pypy.module.cpyext.state import State
from pypy.interpreter.error import OperationError, oefmt
from pypy.interpreter.argument import Arguments
@@ -340,6 +341,10 @@
def getndim(self):
return self.ndim
+ def setitem(self, index, char):
+ # absolutely no safety checks, what could go wrong?
+ self.ptr[index] = char
+
def wrap_getbuffer(space, w_self, w_args, func):
func_target = rffi.cast(getbufferproc, func)
with lltype.scoped_alloc(Py_buffer) as pybuf:
@@ -589,13 +594,27 @@
@cpython_api([PyObject, Py_bufferP, rffi.INT_real],
rffi.INT_real, header=None, error=-1)
@func_renamer("cpyext_%s_%s" % (name.replace('.', '_'), typedef.name))
- def buff_w(space, w_self, pybuf, flags):
- # XXX this is wrong, needs a test
- raise oefmt(space.w_NotImplemented,
- "calling bf_getbuffer on a builtin type not supported yet")
- #args = Arguments(space, [w_self],
- # w_stararg=w_args, w_starstararg=w_kwds)
- #return space.call_args(space.get(buff_fn, w_self), args)
+ def buff_w(space, w_self, view, flags):
+ args = Arguments(space, [space.newint(flags)])
+ w_obj = space.call_args(space.get(buff_fn, w_self), args)
+ if view:
+ #like PyObject_GetBuffer
+ flags = widen(flags)
+ buf = space.buffer_w(w_obj, flags)
+ try:
+ view.c_buf = rffi.cast(rffi.VOIDP, buf.get_raw_address())
+ view.c_obj = make_ref(space, w_obj)
+ except ValueError:
+ w_s = space.newbytes(buf.as_str())
+ view.c_obj = make_ref(space, w_s)
+ view.c_buf = rffi.cast(rffi.VOIDP, rffi.str2charp(
+ space.str_w(w_s), track_allocation=False))
+ rffi.setintfield(view, 'c_readonly', 1)
+ ret = fill_Py_buffer(space, buf, view)
+ return ret
+ return 0
+ # XXX remove this when it no longer crashes a translated PyPy
+ return
api_func = buff_w.api_func
else:
# missing: tp_as_number.nb_nonzero, tp_as_number.nb_coerce
@@ -874,13 +893,13 @@
slotdefs = eval(slotdefs_str)
# PyPy addition
slotdefs += (
- # XXX that might not be what we want!
TPSLOT("__buffer__", "tp_as_buffer.c_bf_getbuffer", None, "wrap_getbuffer", ""),
)
if not PY3:
slotdefs += (
- TPSLOT("__buffer__", "tp_as_buffer.c_bf_getreadbuffer", None, "wrap_getreadbuffer", ""),
+ TPSLOT("__rbuffer__", "tp_as_buffer.c_bf_getreadbuffer", None, "wrap_getreadbuffer", ""),
+ TPSLOT("__wbuffer__", "tp_as_buffer.c_bf_getwritebuffer", None, "wrap_getwritebuffer", ""),
)
diff --git a/pypy/module/cpyext/test/array.c b/pypy/module/cpyext/test/array.c
--- a/pypy/module/cpyext/test/array.c
+++ b/pypy/module/cpyext/test/array.c
@@ -2856,15 +2856,30 @@
(iternextfunc)arrayiter_next, /* tp_iternext */
0, /* tp_methods */
};
+static PyObject *
+readbuffer_as_string(PyObject *self, PyObject *args)
+{
+ PyObject *obj;
+ const void *ptr;
+ Py_ssize_t size;
+
+ if (!PyArg_ParseTuple(args, "O", &obj)) {
+ return NULL;
+ }
+ if (PyObject_AsReadBuffer(obj, &ptr, &size) < 0)
+ return NULL;
+ return PyString_FromStringAndSize((char*)ptr, size);
+}
+
/*********************** Install Module **************************/
-/* No functions in array module. */
static PyMethodDef a_methods[] = {
{"_array_reconstructor", array_reconstructor, METH_VARARGS,
PyDoc_STR("Internal. Used for pickling support.")},
{"switch_multiply", (PyCFunction)switch_multiply, METH_NOARGS, NULL},
+ {"readbuffer_as_string", (PyCFunction)readbuffer_as_string, METH_VARARGS, NULL},
{NULL, NULL, 0, NULL} /* Sentinel */
};
diff --git a/pypy/module/cpyext/test/test_arraymodule.py b/pypy/module/cpyext/test/test_arraymodule.py
--- a/pypy/module/cpyext/test/test_arraymodule.py
+++ b/pypy/module/cpyext/test/test_arraymodule.py
@@ -1,8 +1,17 @@
from pypy.module.cpyext.test.test_cpyext import AppTestCpythonExtensionBase
-
+from pypy.conftest import option
class AppTestArrayModule(AppTestCpythonExtensionBase):
- enable_leak_checking = False
+ enable_leak_checking = True
+
+ def setup_class(cls):
+ from rpython.tool.udir import udir
+ AppTestCpythonExtensionBase.setup_class.im_func(cls)
+ if option.runappdirect:
+ cls.w_udir = str(udir)
+ else:
+ cls.w_udir = cls.space.wrap(str(udir))
+
def test_basic(self):
module = self.import_module(name='array')
@@ -80,6 +89,7 @@
assert res == [2, 4, 6]
def test_subclass(self):
+ import struct
module = self.import_module(name='array')
class Sub(module.array):
pass
@@ -88,3 +98,37 @@
res = [1, 2, 3] * arr
assert res == [1, 2, 3, 1, 2, 3]
+ val = module.readbuffer_as_string(arr)
+ assert val == struct.pack('i', 2)
+
+ def test_unicode_readbuffer(self):
+ # Not really part of array, refactor
+ import struct
+ module = self.import_module(name='array')
+ val = module.readbuffer_as_string('abcd')
+ assert val == 'abcd'
+ val = module.readbuffer_as_string(u'\u03a3')
+ assert val is not None
+
+ def test_readinto(self):
+ module = self.import_module(name='array')
+ a = module.array('c')
+ a.fromstring('0123456789')
+ filename = self.udir + "/_test_file"
+ f = open(filename, 'w+b')
+ f.write('foobar')
+ f.seek(0)
+ n = f.readinto(a)
+ f.close()
+ assert n == 6
+ assert len(a) == 10
+ assert a.tostring() == 'foobar6789'
+
+ def test_iowrite(self):
+ module = self.import_module(name='array')
+ from io import BytesIO
+ a = module.array('c')
+ a.fromstring('0123456789')
+ fd = BytesIO()
+ # only test that it works
+ fd.write(a)
diff --git a/pypy/module/cpyext/test/test_getargs.py b/pypy/module/cpyext/test/test_getargs.py
--- a/pypy/module/cpyext/test/test_getargs.py
+++ b/pypy/module/cpyext/test/test_getargs.py
@@ -123,9 +123,10 @@
return result;
''')
assert b'foo\0bar\0baz' == pybuffer(b'foo\0bar\0baz')
- return # XXX
+ #return # XXX?
assert b'foo\0bar\0baz' == pybuffer(bytearray(b'foo\0bar\0baz'))
+
def test_pyarg_parse_string_fails(self):
"""
Test the failing case of PyArg_ParseTuple(): it must not keep
diff --git a/pypy/module/cpyext/test/test_memoryobject.py b/pypy/module/cpyext/test/test_memoryobject.py
--- a/pypy/module/cpyext/test/test_memoryobject.py
+++ b/pypy/module/cpyext/test/test_memoryobject.py
@@ -1,10 +1,14 @@
import pytest
+
from rpython.rtyper.lltypesystem import rffi
from pypy.module.cpyext.test.test_api import BaseApiTest
from pypy.module.cpyext.test.test_cpyext import AppTestCpythonExtensionBase
from rpython.rlib.buffer import StringBuffer
+only_pypy ="config.option.runappdirect and '__pypy__' not in sys.builtin_module_names"
+
class TestMemoryViewObject(BaseApiTest):
+ skip('needs c_bf_getbuffer wrapper from slotdefs')
def test_fromobject(self, space, api):
w_hello = space.newbytes("hello")
assert api.PyObject_CheckBuffer(w_hello)
@@ -24,6 +28,8 @@
assert w_view.c_shape[0] == 5
assert w_view.c_strides[0] == 1
assert w_view.c_len == 5
+ o = rffi.charp2str(w_view.c_buf)
+ assert o == 'hello'
class AppTestPyBuffer_FillInfo(AppTestCpythonExtensionBase):
def test_fillWithObject(self):
@@ -80,8 +86,12 @@
assert viewlen == y.itemsize * len(y)
@pytest.mark.skipif(True, reason="no _numpypy on py3k")
+ #@pytest.mark.skipif(only_pypy, reason='pypy only test')
def test_buffer_info(self):
- from _numpypy import multiarray as np
+ try:
+ from _numpypy import multiarray as np
+ except ImportError:
+ skip('pypy built without _numpypy')
module = self.import_module(name='buffer_test')
get_buffer_info = module.get_buffer_info
raises(ValueError, get_buffer_info, np.arange(5)[::2], ('SIMPLE',))
@@ -91,3 +101,29 @@
arr = np.zeros((10, 1), order='C')
shape, strides = get_buffer_info(arr, ['C_CONTIGUOUS'])
assert strides[-1] == 8
+ dt1 = np.dtype(
+ [('a', 'b'), ('b', 'i'),
+ ('sub0', np.dtype('b,i')),
+ ('sub1', np.dtype('b,i')),
+ ('sub2', np.dtype('b,i')),
+ ('sub3', np.dtype('b,i')),
+ ('sub4', np.dtype('b,i')),
+ ('sub5', np.dtype('b,i')),
+ ('sub6', np.dtype('b,i')),
+ ('sub7', np.dtype('b,i')),
+ ('c', 'i')],
+ )
+ x = np.arange(dt1.itemsize, dtype='int8').view(dt1)
+ # pytest can catch warnings from v2.8 and up, we ship 2.5
+ import warnings
+ warnings.filterwarnings("error")
+ try:
+ try:
+ y = get_buffer_info(x, ['SIMPLE'])
+ except UserWarning as e:
+ pass
+ else:
+ assert False ,"PyPy-specific UserWarning not raised" \
+ " on too long format string"
+ finally:
+ warnings.resetwarnings()
diff --git a/pypy/module/cpyext/typeobject.py b/pypy/module/cpyext/typeobject.py
--- a/pypy/module/cpyext/typeobject.py
+++ b/pypy/module/cpyext/typeobject.py
@@ -610,7 +610,7 @@
# uninitialized fields:
# c_tp_print
# XXX implement
- # c_tp_compare and the following fields (see http://docs.python.org/c-api/typeobj.html )
+ # c_tp_compare and more?
w_base = best_base(space, w_type.bases_w)
pto.c_tp_base = rffi.cast(PyTypeObjectPtr, make_ref(space, w_base))
@@ -668,7 +668,6 @@
return find_best_base(bases_w)
def inherit_slots(space, pto, w_base):
- # XXX missing: nearly everything
base_pyo = make_ref(space, w_base)
try:
base = rffi.cast(PyTypeObjectPtr, base_pyo)
@@ -687,6 +686,15 @@
pto.c_tp_getattro = base.c_tp_getattro
if not pto.c_tp_as_buffer:
pto.c_tp_as_buffer = base.c_tp_as_buffer
+ if base.c_tp_as_buffer:
+ # inherit base.c_tp_as_buffer functions not inherited from w_type
+ # note: builtin types are handled in setup_buffer_procs
+ pto_as = pto.c_tp_as_buffer
+ base_as = base.c_tp_as_buffer
+ if not pto_as.c_bf_getbuffer:
+ pto_as.c_bf_getbuffer = base_as.c_bf_getbuffer
+ if not pto_as.c_bf_releasebuffer:
+ pto_as.c_bf_releasebuffer = base_as.c_bf_releasebuffer
finally:
Py_DecRef(space, base_pyo)
@@ -716,21 +724,22 @@
w_obj = space.allocate_instance(W_PyCTypeObject, w_metatype)
track_reference(space, py_obj, w_obj)
- w_obj.__init__(space, py_type)
+ # __init__ wraps all slotdefs functions from py_type via add_operators
+ w_obj.__init__(space, py_type)
w_obj.ready()
finish_type_2(space, py_type, w_obj)
- # inheriting tp_as_* slots
base = py_type.c_tp_base
if base:
- if not py_type.c_tp_as_number:
+ # XXX refactor - parts of this are done in finish_type_2 -> inherit_slots
+ if not py_type.c_tp_as_number:
py_type.c_tp_as_number = base.c_tp_as_number
py_type.c_tp_flags |= base.c_tp_flags & Py_TPFLAGS_HAVE_INPLACEOPS
if not py_type.c_tp_as_sequence:
py_type.c_tp_as_sequence = base.c_tp_as_sequence
py_type.c_tp_flags |= base.c_tp_flags & Py_TPFLAGS_HAVE_INPLACEOPS
if not py_type.c_tp_as_mapping: py_type.c_tp_as_mapping = base.c_tp_as_mapping
- if not py_type.c_tp_as_buffer: py_type.c_tp_as_buffer = base.c_tp_as_buffer
+ #if not py_type.c_tp_as_buffer: py_type.c_tp_as_buffer = base.c_tp_as_buffer
return w_obj
diff --git a/pypy/module/micronumpy/test/dummy_module.py b/pypy/module/micronumpy/test/dummy_module.py
--- a/pypy/module/micronumpy/test/dummy_module.py
+++ b/pypy/module/micronumpy/test/dummy_module.py
@@ -29,7 +29,8 @@
globals()['uint'] = dtype('uint').type
types = ['Generic', 'Number', 'Integer', 'SignedInteger', 'UnsignedInteger',
- 'Inexact', 'Floating', 'ComplexFloating', 'Flexible', 'Character']
+ 'Inexact', 'Floating', 'ComplexFloating', 'Flexible', 'Character',
+ ]
for t in types:
globals()[t.lower()] = typeinfo[t]
@@ -42,4 +43,4 @@
return a
def isscalar(a):
- return type(a) in [typeinfo[t] for t in types]
+ return any([isinstance(a, typeinfo[t]) for t in types])
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
@@ -1486,7 +1486,7 @@
assert d[1] == 12
def test_sum(self):
- from numpy import array, zeros, float16, complex64, str_
+ from numpy import array, zeros, float16, complex64, str_, isscalar, add
a = array(range(5))
assert a.sum() == 10
assert a[:4].sum() == 6
@@ -1515,6 +1515,13 @@
assert list(zeros((0, 2)).sum(axis=1)) == []
+ a = array([1, 2, 3, 4]).sum()
+ s = isscalar(a)
+ assert s is True
+ a = add.reduce([1.0, 2, 3, 4])
+ s = isscalar(a)
+ assert s is True,'%r is not a scalar' % type(a)
+
def test_reduce_nd(self):
from numpy import arange, array
a = arange(15).reshape(5, 3)
diff --git a/pypy/module/micronumpy/ufuncs.py b/pypy/module/micronumpy/ufuncs.py
--- a/pypy/module/micronumpy/ufuncs.py
+++ b/pypy/module/micronumpy/ufuncs.py
@@ -288,10 +288,8 @@
_, dtype, _ = self.find_specialization(space, dtype, dtype, out,
casting='unsafe')
- call__array_wrap__ = True
if shapelen == len(axes):
if out:
- call__array_wrap__ = False
if out.ndims() > 0:
raise oefmt(space.w_ValueError,
"output parameter for reduction operation %s has "
@@ -302,15 +300,20 @@
if out:
out.set_scalar_value(res)
return out
+ w_NDimArray = space.gettypefor(W_NDimArray)
+ call__array_wrap__ = False
if keepdims:
shape = [1] * len(obj_shape)
out = W_NDimArray.from_shape(space, shape, dtype, w_instance=obj)
out.implementation.setitem(0, res)
+ call__array_wrap__ = True
res = out
- elif not space.is_w(space.type(w_obj), space.gettypefor(W_NDimArray)):
+ elif (space.issubtype_w(space.type(w_obj), w_NDimArray) and
+ not space.is_w(space.type(w_obj), w_NDimArray)):
# subtypes return a ndarray subtype, not a scalar
out = W_NDimArray.from_shape(space, [1], dtype, w_instance=obj)
out.implementation.setitem(0, res)
+ call__array_wrap__ = True
res = out
if call__array_wrap__:
res = space.call_method(obj, '__array_wrap__', res, space.w_None)
@@ -359,8 +362,7 @@
return out
loop.reduce(
space, self.func, obj, axis_flags, dtype, out, self.identity)
- if call__array_wrap__:
- out = space.call_method(obj, '__array_wrap__', out, space.w_None)
+ out = space.call_method(obj, '__array_wrap__', out, space.w_None)
return out
def descr_outer(self, space, args_w):
diff --git a/pypy/module/operator/test/test_operator.py b/pypy/module/operator/test/test_operator.py
--- a/pypy/module/operator/test/test_operator.py
+++ b/pypy/module/operator/test/test_operator.py
@@ -203,6 +203,13 @@
return 13289
assert operator.index(myint(7)) == 7
+ def test_index_int_subclass(self):
+ import operator
+ class myint(int):
+ def __index__(self):
+ return 13289
+ assert operator.index(myint(7)) == 7
+
def test_compare_digest(self):
import _operator as operator
diff --git a/pypy/objspace/std/memoryobject.py b/pypy/objspace/std/memoryobject.py
--- a/pypy/objspace/std/memoryobject.py
+++ b/pypy/objspace/std/memoryobject.py
@@ -409,10 +409,14 @@
def w_get_shape(self, space):
self._check_released(space)
+ if self.buf.getndim() == 0:
+ return space.w_None
return space.newtuple([space.wrap(x) for x in self.getshape()])
def w_get_strides(self, space):
self._check_released(space)
+ if self.buf.getndim() == 0:
+ return space.w_None
return space.newtuple([space.wrap(x) for x in self.getstrides()])
def w_get_suboffsets(self, space):
diff --git a/rpython/jit/backend/detect_cpu.py b/rpython/jit/backend/detect_cpu.py
--- a/rpython/jit/backend/detect_cpu.py
+++ b/rpython/jit/backend/detect_cpu.py
@@ -61,6 +61,7 @@
'i86pc': MODEL_X86, # Solaris/Intel
'x86': MODEL_X86, # Apple
'Power Macintosh': MODEL_PPC_64,
+ 'powerpc': MODEL_PPC_64, # freebsd
'ppc64': MODEL_PPC_64,
'ppc64le': MODEL_PPC_64,
'x86_64': MODEL_X86,
diff --git a/rpython/translator/c/src/asm.c b/rpython/translator/c/src/asm.c
--- a/rpython/translator/c/src/asm.c
+++ b/rpython/translator/c/src/asm.c
@@ -8,10 +8,6 @@
/* # include "src/asm_gcc_x86_64.c" */
#endif
-#if defined(__GNUC__) && defined(__ppc__)
-# include "src/asm_ppc.c"
-#endif
-
#if defined(_MSC_VER)
# include "src/asm_msvc.c"
#endif
diff --git a/rpython/translator/c/src/asm.h b/rpython/translator/c/src/asm.h
--- a/rpython/translator/c/src/asm.h
+++ b/rpython/translator/c/src/asm.h
@@ -10,10 +10,6 @@
# include "src/asm_gcc_x86_64.h"
#endif
-#if defined(__GNUC__) && defined(__ppc__)
-# include "src/asm_ppc.h"
-#endif
-
#if defined(MS_WINDOWS) && defined(_MSC_VER)
# include "src/asm_msvc.h"
#endif
More information about the pypy-commit
mailing list