[pypy-commit] pypy default: merged upstream
alex_gaynor
noreply at buildbot.pypy.org
Fri Dec 6 23:07:29 CET 2013
Author: Alex Gaynor <alex.gaynor at gmail.com>
Branch:
Changeset: r68391:e07994044752
Date: 2013-12-06 16:06 -0600
http://bitbucket.org/pypy/pypy/changeset/e07994044752/
Log: merged upstream
diff --git a/lib-python/2.7/ctypes/test/test_python_api.py b/lib-python/2.7/ctypes/test/test_python_api.py
--- a/lib-python/2.7/ctypes/test/test_python_api.py
+++ b/lib-python/2.7/ctypes/test/test_python_api.py
@@ -73,6 +73,7 @@
del pyobj
self.assertEqual(grc(s), ref)
+ @xfail
def test_PyOS_snprintf(self):
PyOS_snprintf = pythonapi.PyOS_snprintf
PyOS_snprintf.argtypes = POINTER(c_char), c_size_t, c_char_p
diff --git a/pypy/doc/cpython_differences.rst b/pypy/doc/cpython_differences.rst
--- a/pypy/doc/cpython_differences.rst
+++ b/pypy/doc/cpython_differences.rst
@@ -83,7 +83,7 @@
_winreg
-* Supported by being rewritten in pure Python (possibly using ``ctypes``):
+* Supported by being rewritten in pure Python (possibly using ``cffi``):
see the `lib_pypy/`_ directory. Examples of modules that we
support this way: ``ctypes``, ``cPickle``, ``cmath``, ``dbm``, ``datetime``...
Note that some modules are both in there and in the list above;
@@ -316,5 +316,4 @@
type and vice versa. For builtin types, a dictionary will be returned that
cannot be changed (but still looks and behaves like a normal dictionary).
-
.. include:: _ref.txt
diff --git a/pypy/doc/ctypes-implementation.rst b/pypy/doc/ctypes-implementation.rst
--- a/pypy/doc/ctypes-implementation.rst
+++ b/pypy/doc/ctypes-implementation.rst
@@ -72,7 +72,13 @@
Here is a list of the limitations and missing features of the
current implementation:
-* No support for ``PyXxx`` functions from ``libpython``, for obvious reasons.
+* ``ctypes.pythonapi`` lets you access the CPython C API emulation layer
+ of PyPy, at your own risks and without doing anything sensible about
+ the GIL. Since PyPy 2.3, these functions are also named with an extra
+ "Py", for example ``PyPyInt_FromLong()``. Basically, don't use this,
+ but it might more or less work in simple cases if you do. (Obviously,
+ assuming the PyObject pointers you get have any particular fields in
+ any particular order is just going to crash.)
* We copy Python strings instead of having pointers to raw buffers
diff --git a/pypy/doc/extradoc.rst b/pypy/doc/extradoc.rst
--- a/pypy/doc/extradoc.rst
+++ b/pypy/doc/extradoc.rst
@@ -72,13 +72,13 @@
.. _bibtex: https://bitbucket.org/pypy/extradoc/raw/tip/talk/bibtex.bib
.. _`Runtime Feedback in a Meta-Tracing JIT for Efficient Dynamic Languages`: https://bitbucket.org/pypy/extradoc/raw/extradoc/talk/icooolps2011/jit-hints.pdf
-.. _`Allocation Removal by Partial Evaluation in a Tracing JIT`: http://codespeak.net/svn/pypy/extradoc/talk/pepm2011/bolz-allocation-removal.pdf
-.. _`Towards a Jitting VM for Prolog Execution`: http://www.stups.uni-duesseldorf.de/publications/bolz-prolog-jit.pdf
+.. _`Allocation Removal by Partial Evaluation in a Tracing JIT`: https://bitbucket.org/pypy/extradoc/raw/extradoc/talk/pepm2011/bolz-allocation-removal.pdf
+.. _`Towards a Jitting VM for Prolog Execution`: http://www.stups.uni-duesseldorf.de/mediawiki/images/a/a7/Pub-BoLeSch2010.pdf
.. _`High performance implementation of Python for CLI/.NET with JIT compiler generation for dynamic languages`: http://buildbot.pypy.org/misc/antocuni-thesis.pdf
.. _`How to *not* write Virtual Machines for Dynamic Languages`: https://bitbucket.org/pypy/extradoc/raw/tip/talk/dyla2007/dyla.pdf
.. _`Tracing the Meta-Level: PyPy's Tracing JIT Compiler`: https://bitbucket.org/pypy/extradoc/raw/tip/talk/icooolps2009/bolz-tracing-jit.pdf
.. _`Faster than C#: Efficient Implementation of Dynamic Languages on .NET`: https://bitbucket.org/pypy/extradoc/raw/tip/talk/icooolps2009-dotnet/cli-jit.pdf
-.. _`Automatic JIT Compiler Generation with Runtime Partial Evaluation`: http://www.stups.uni-duesseldorf.de/thesis/final-master.pdf
+.. _`Automatic JIT Compiler Generation with Runtime Partial Evaluation`: http://wwwold.cobra.cs.uni-duesseldorf.de/thesis/final-master.pdf
.. _`RPython: A Step towards Reconciling Dynamically and Statically Typed OO Languages`: http://www.disi.unige.it/person/AnconaD/papers/Recent_abstracts.html#AACM-DLS07
.. _`EU Reports`: index-report.html
.. _`Hardware Transactional Memory Support for Lightweight Dynamic Language Evolution`: http://sabi.net/nriley/pubs/dls6-riley.pdf
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
@@ -25,3 +25,17 @@
.. branch: less-stringly-ops
Use subclasses of SpaceOperation instead of SpaceOperator objects.
Random cleanups in flowspace and annotator.
+
+.. branch: ndarray-buffer
+adds support for the buffer= argument to the ndarray ctor
+
+.. branch: better_ftime_detect2
+On OpenBSD do not pull in libcompat.a as it is about to be removed.
+And more generally, if you have gettimeofday(2) you will not need ftime(3).
+
+.. branch: timeb_h
+Remove dependency upon <sys/timeb.h> on OpenBSD. This will be disappearing
+along with libcompat.a.
+
+.. branch: OlivierBlanvillain/fix-3-broken-links-on-pypy-published-pap-1386250839215
+Fix 3 broken links on PyPy published papers in docs.
diff --git a/pypy/interpreter/buffer.py b/pypy/interpreter/buffer.py
--- a/pypy/interpreter/buffer.py
+++ b/pypy/interpreter/buffer.py
@@ -47,6 +47,9 @@
def get_raw_address(self):
raise ValueError("no raw buffer")
+ def is_writable(self):
+ return False
+
# __________ app-level support __________
def descr_len(self, space):
@@ -135,6 +138,9 @@
__slots__ = () # no extra slot here
+ def is_writable(self):
+ return True
+
def setitem(self, index, char):
"Write a character into the buffer."
raise NotImplementedError # Must be overriden. No bounds checks.
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
@@ -59,6 +59,9 @@
def descr__buffer__(self, space):
return self.buffer.descr__buffer__(space)
+ def descr_str(self, space):
+ return space.wrap(self.buffer.as_str())
+
MiniBuffer.typedef = TypeDef(
"buffer",
@@ -68,6 +71,7 @@
__setitem__ = interp2app(MiniBuffer.descr_setitem),
__buffer__ = interp2app(MiniBuffer.descr__buffer__),
__weakref__ = make_weakref_descr(MiniBuffer),
+ __str__ = interp2app(MiniBuffer.descr_str),
)
MiniBuffer.typedef.acceptable_as_base_class = False
diff --git a/pypy/module/_cffi_backend/test/_backend_test_c.py b/pypy/module/_cffi_backend/test/_backend_test_c.py
--- a/pypy/module/_cffi_backend/test/_backend_test_c.py
+++ b/pypy/module/_cffi_backend/test/_backend_test_c.py
@@ -2143,7 +2143,13 @@
c = newp(BCharArray, b"hi there")
#
buf = buffer(c)
- assert str(buf).startswith('<_cffi_backend.buffer object at 0x')
+ assert repr(buf).startswith('<_cffi_backend.buffer object at 0x')
+ assert bytes(buf) == b"hi there\x00"
+ if sys.version_info < (3,):
+ assert str(buf) == "hi there\x00"
+ assert unicode(buf) == u+"hi there\x00"
+ else:
+ assert str(buf) == repr(buf)
# --mb_length--
assert len(buf) == len(b"hi there\x00")
# --mb_item--
diff --git a/pypy/module/cpyext/api.py b/pypy/module/cpyext/api.py
--- a/pypy/module/cpyext/api.py
+++ b/pypy/module/cpyext/api.py
@@ -400,16 +400,16 @@
'_PyObject_CallFunction_SizeT', '_PyObject_CallMethod_SizeT',
'PyBuffer_FromMemory', 'PyBuffer_FromReadWriteMemory', 'PyBuffer_FromObject',
- 'PyBuffer_FromReadWriteObject', 'PyBuffer_New', 'PyBuffer_Type', 'init_bufferobject',
+ 'PyBuffer_FromReadWriteObject', 'PyBuffer_New', 'PyBuffer_Type', '_Py_init_bufferobject',
'PyCObject_FromVoidPtr', 'PyCObject_FromVoidPtrAndDesc', 'PyCObject_AsVoidPtr',
'PyCObject_GetDesc', 'PyCObject_Import', 'PyCObject_SetVoidPtr',
- 'PyCObject_Type', 'init_pycobject',
+ 'PyCObject_Type', '_Py_init_pycobject',
'PyCapsule_New', 'PyCapsule_IsValid', 'PyCapsule_GetPointer',
'PyCapsule_GetName', 'PyCapsule_GetDestructor', 'PyCapsule_GetContext',
'PyCapsule_SetPointer', 'PyCapsule_SetName', 'PyCapsule_SetDestructor',
- 'PyCapsule_SetContext', 'PyCapsule_Import', 'PyCapsule_Type', 'init_capsule',
+ 'PyCapsule_SetContext', 'PyCapsule_Import', 'PyCapsule_Type', '_Py_init_capsule',
'PyObject_AsReadBuffer', 'PyObject_AsWriteBuffer', 'PyObject_CheckReadBuffer',
@@ -687,11 +687,15 @@
globals()['va_get_%s' % name_no_star] = func
def setup_init_functions(eci, translating):
- init_buffer = rffi.llexternal('init_bufferobject', [], lltype.Void,
+ if translating:
+ prefix = 'PyPy'
+ else:
+ prefix = 'cpyexttest'
+ init_buffer = rffi.llexternal('_%s_init_bufferobject' % prefix, [], lltype.Void,
compilation_info=eci, _nowrapper=True)
- init_pycobject = rffi.llexternal('init_pycobject', [], lltype.Void,
+ init_pycobject = rffi.llexternal('_%s_init_pycobject' % prefix, [], lltype.Void,
compilation_info=eci, _nowrapper=True)
- init_capsule = rffi.llexternal('init_capsule', [], lltype.Void,
+ init_capsule = rffi.llexternal('_%s_init_capsule' % prefix, [], lltype.Void,
compilation_info=eci, _nowrapper=True)
INIT_FUNCTIONS.extend([
lambda space: init_buffer(),
@@ -699,12 +703,8 @@
lambda space: init_capsule(),
])
from pypy.module.posix.interp_posix import add_fork_hook
- if translating:
- reinit_tls = rffi.llexternal('PyThread_ReInitTLS', [], lltype.Void,
- compilation_info=eci)
- else:
- reinit_tls = rffi.llexternal('PyPyThread_ReInitTLS', [], lltype.Void,
- compilation_info=eci)
+ reinit_tls = rffi.llexternal('%sThread_ReInitTLS' % prefix, [], lltype.Void,
+ compilation_info=eci)
add_fork_hook('child', reinit_tls)
def init_function(func):
@@ -746,7 +746,7 @@
from rpython.translator.c.database import LowLevelDatabase
db = LowLevelDatabase()
- generate_macros(export_symbols, rename=True, do_deref=True)
+ generate_macros(export_symbols, prefix='cpyexttest')
# Structure declaration code
members = []
@@ -812,7 +812,7 @@
INTERPLEVEL_API[name] = w_obj
- name = name.replace('Py', 'PyPy')
+ name = name.replace('Py', 'cpyexttest')
if isptr:
ptr = ctypes.c_void_p.in_dll(bridge, name)
if typ == 'PyObject*':
@@ -824,7 +824,7 @@
ptr.value = ctypes.cast(ll2ctypes.lltype2ctypes(value),
ctypes.c_void_p).value
elif typ in ('PyObject*', 'PyTypeObject*'):
- if name.startswith('PyPyExc_'):
+ if name.startswith('PyPyExc_') or name.startswith('cpyexttestExc_'):
# we already have the pointer
in_dll = ll2ctypes.get_ctypes_type(PyObject).in_dll(bridge, name)
py_obj = ll2ctypes.ctypes2lltype(PyObject, in_dll)
@@ -859,28 +859,27 @@
setup_init_functions(eci, translating=False)
return modulename.new(ext='')
-def generate_macros(export_symbols, rename=True, do_deref=True):
+def mangle_name(prefix, name):
+ if name.startswith('Py'):
+ return prefix + name[2:]
+ elif name.startswith('_Py'):
+ return '_' + prefix + name[3:]
+ else:
+ return None
+
+def generate_macros(export_symbols, prefix):
"NOT_RPYTHON"
pypy_macros = []
renamed_symbols = []
for name in export_symbols:
- if name.startswith("PyPy"):
- renamed_symbols.append(name)
- continue
- if not rename:
- continue
name = name.replace("#", "")
- newname = name.replace('Py', 'PyPy')
- if not rename:
- newname = name
+ newname = mangle_name(prefix, name)
+ assert newname, name
pypy_macros.append('#define %s %s' % (name, newname))
if name.startswith("PyExc_"):
pypy_macros.append('#define _%s _%s' % (name, newname))
renamed_symbols.append(newname)
- if rename:
- export_symbols[:] = renamed_symbols
- else:
- export_symbols[:] = [sym.replace("#", "") for sym in export_symbols]
+ export_symbols[:] = renamed_symbols
# Generate defines
for macro_name, size in [
@@ -1041,7 +1040,7 @@
from rpython.translator.c.database import LowLevelDatabase
db = LowLevelDatabase()
- generate_macros(export_symbols, rename=False, do_deref=False)
+ generate_macros(export_symbols, prefix='PyPy')
functions = generate_decls_and_callbacks(db, [], api_struct=False)
code = "#include <Python.h>\n" + "\n".join(functions)
@@ -1071,7 +1070,8 @@
export_struct(name, struct)
for name, func in FUNCTIONS.iteritems():
- deco = entrypoint_lowlevel("cpyext", func.argtypes, name, relax=True)
+ newname = mangle_name('PyPy', name) or name
+ deco = entrypoint_lowlevel("cpyext", func.argtypes, newname, relax=True)
deco(func.get_wrapper(space))
setup_init_functions(eci, translating=True)
diff --git a/pypy/module/cpyext/include/bufferobject.h b/pypy/module/cpyext/include/bufferobject.h
--- a/pypy/module/cpyext/include/bufferobject.h
+++ b/pypy/module/cpyext/include/bufferobject.h
@@ -37,7 +37,7 @@
PyObject* PyBuffer_New(Py_ssize_t size);
-void init_bufferobject(void);
+void _Py_init_bufferobject(void);
#ifdef __cplusplus
}
diff --git a/pypy/module/cpyext/include/pycapsule.h b/pypy/module/cpyext/include/pycapsule.h
--- a/pypy/module/cpyext/include/pycapsule.h
+++ b/pypy/module/cpyext/include/pycapsule.h
@@ -50,7 +50,7 @@
PyAPI_FUNC(void *) PyCapsule_Import(const char *name, int no_block);
-void init_capsule(void);
+void _Py_init_capsule(void);
#ifdef __cplusplus
}
diff --git a/pypy/module/cpyext/include/pycobject.h b/pypy/module/cpyext/include/pycobject.h
--- a/pypy/module/cpyext/include/pycobject.h
+++ b/pypy/module/cpyext/include/pycobject.h
@@ -48,7 +48,7 @@
} PyCObject;
#endif
-void init_pycobject(void);
+void _Py_init_pycobject(void);
#ifdef __cplusplus
}
diff --git a/pypy/module/cpyext/src/bufferobject.c b/pypy/module/cpyext/src/bufferobject.c
--- a/pypy/module/cpyext/src/bufferobject.c
+++ b/pypy/module/cpyext/src/bufferobject.c
@@ -783,7 +783,7 @@
return size;
}
-void init_bufferobject(void)
+void _Py_init_bufferobject(void)
{
PyType_Ready(&PyBuffer_Type);
}
diff --git a/pypy/module/cpyext/src/capsule.c b/pypy/module/cpyext/src/capsule.c
--- a/pypy/module/cpyext/src/capsule.c
+++ b/pypy/module/cpyext/src/capsule.c
@@ -321,7 +321,7 @@
PyCapsule_Type__doc__ /*tp_doc*/
};
-void init_capsule()
+void _Py_init_capsule()
{
PyType_Ready(&PyCapsule_Type);
}
diff --git a/pypy/module/cpyext/src/cobject.c b/pypy/module/cpyext/src/cobject.c
--- a/pypy/module/cpyext/src/cobject.c
+++ b/pypy/module/cpyext/src/cobject.c
@@ -156,7 +156,7 @@
PyCObject_Type__doc__ /*tp_doc*/
};
-void init_pycobject()
+void _Py_init_pycobject()
{
PyType_Ready(&PyCObject_Type);
}
diff --git a/pypy/module/cpyext/test/test_thread.py b/pypy/module/cpyext/test/test_thread.py
--- a/pypy/module/cpyext/test/test_thread.py
+++ b/pypy/module/cpyext/test/test_thread.py
@@ -8,8 +8,10 @@
module = self.import_extension('foo', [
("get_thread_ident", "METH_NOARGS",
"""
- /* Use the 'PyPy' prefix to ensure we access our functions */
- return PyInt_FromLong(PyPyThread_get_thread_ident());
+#ifndef PyThread_get_thread_ident
+#error "seems we are not accessing PyPy's functions"
+#endif
+ return PyInt_FromLong(PyThread_get_thread_ident());
"""),
])
import thread, threading
@@ -32,17 +34,19 @@
module = self.import_extension('foo', [
("test_acquire_lock", "METH_NOARGS",
"""
- /* Use the 'PyPy' prefix to ensure we access our functions */
- PyThread_type_lock lock = PyPyThread_allocate_lock();
- if (PyPyThread_acquire_lock(lock, 1) != 1) {
+#ifndef PyThread_allocate_lock
+#error "seems we are not accessing PyPy's functions"
+#endif
+ PyThread_type_lock lock = PyThread_allocate_lock();
+ if (PyThread_acquire_lock(lock, 1) != 1) {
PyErr_SetString(PyExc_AssertionError, "first acquire");
return NULL;
}
- if (PyPyThread_acquire_lock(lock, 0) != 0) {
+ if (PyThread_acquire_lock(lock, 0) != 0) {
PyErr_SetString(PyExc_AssertionError, "second acquire");
return NULL;
}
- PyPyThread_free_lock(lock);
+ PyThread_free_lock(lock);
Py_RETURN_NONE;
"""),
@@ -53,15 +57,17 @@
module = self.import_extension('foo', [
("test_release_lock", "METH_NOARGS",
"""
- /* Use the 'PyPy' prefix to ensure we access our functions */
- PyThread_type_lock lock = PyPyThread_allocate_lock();
- PyPyThread_acquire_lock(lock, 1);
- PyPyThread_release_lock(lock);
- if (PyPyThread_acquire_lock(lock, 0) != 1) {
+#ifndef PyThread_release_lock
+#error "seems we are not accessing PyPy's functions"
+#endif
+ PyThread_type_lock lock = PyThread_allocate_lock();
+ PyThread_acquire_lock(lock, 1);
+ PyThread_release_lock(lock);
+ if (PyThread_acquire_lock(lock, 0) != 1) {
PyErr_SetString(PyExc_AssertionError, "first acquire");
return NULL;
}
- PyPyThread_free_lock(lock);
+ PyThread_free_lock(lock);
Py_RETURN_NONE;
"""),
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
@@ -392,6 +392,21 @@
def __del__(self):
free_raw_storage(self.storage, track_allocation=False)
+class ConcreteArrayWithBase(ConcreteArrayNotOwning):
+ def __init__(self, shape, dtype, order, strides, backstrides, storage, orig_base):
+ ConcreteArrayNotOwning.__init__(self, shape, dtype, order,
+ strides, backstrides, storage)
+ self.orig_base = orig_base
+
+ def base(self):
+ return self.orig_base
+
+
+class ConcreteNonWritableArrayWithBase(ConcreteArrayWithBase):
+ 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 descr_setitem(self, space, orig_array, w_index, w_value):
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
@@ -49,11 +49,24 @@
return W_NDimArray(impl)
@staticmethod
- def from_shape_and_storage(space, shape, storage, dtype, order='C', owning=False, w_subtype=None):
+ def from_shape_and_storage(space, shape, storage, dtype, order='C', owning=False,
+ w_subtype=None, w_base=None, writable=True):
from pypy.module.micronumpy.arrayimpl import concrete
assert shape
strides, backstrides = calc_strides(shape, dtype, order)
- if owning:
+ if w_base is not None:
+ if owning:
+ raise OperationError(space.w_ValueError,
+ space.wrap("Cannot have owning=True when specifying a buffer"))
+ if writable:
+ impl = concrete.ConcreteArrayWithBase(shape, dtype, order, strides,
+ backstrides, storage, w_base)
+ else:
+ impl = concrete.ConcreteNonWritableArrayWithBase(shape, dtype, order,
+ strides, backstrides,
+ storage, w_base)
+
+ elif owning:
# Will free storage when GCd
impl = concrete.ConcreteArray(shape, dtype, order, strides,
backstrides, storage=storage)
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
@@ -1,3 +1,5 @@
+from rpython.rtyper.lltypesystem import rffi
+from rpython.rlib.rawstorage import RAW_STORAGE_PTR
from pypy.interpreter.error import operationerrfmt, OperationError
from pypy.interpreter.typedef import TypeDef, GetSetProperty, make_weakref_descr
from pypy.interpreter.gateway import interp2app, unwrap_spec, applevel, \
@@ -20,6 +22,7 @@
from rpython.rlib.rstring import StringBuilder
from pypy.module.micronumpy.arrayimpl.base import BaseArrayImplementation
from pypy.module.micronumpy.conversion_utils import order_converter, multi_axis_converter
+from pypy.module.micronumpy import support
from pypy.module.micronumpy.constants import *
def _find_shape(space, w_size, dtype):
@@ -1067,13 +1070,35 @@
offset=0, w_strides=None, order='C'):
from pypy.module.micronumpy.arrayimpl.concrete import ConcreteArray
from pypy.module.micronumpy.support import calc_strides
- if (offset != 0 or not space.is_none(w_strides) or
- not space.is_none(w_buffer)):
- raise OperationError(space.w_NotImplementedError,
- space.wrap("unsupported param"))
dtype = space.interp_w(interp_dtype.W_Dtype,
space.call_function(space.gettypefor(interp_dtype.W_Dtype), w_dtype))
shape = _find_shape(space, w_shape, dtype)
+
+ if not space.is_none(w_buffer):
+ if (not space.is_none(w_strides)):
+ raise OperationError(space.w_NotImplementedError,
+ space.wrap("unsupported param"))
+
+ buf = space.buffer_w(w_buffer)
+ try:
+ raw_ptr = buf.get_raw_address()
+ except ValueError:
+ raise OperationError(space.w_TypeError, space.wrap(
+ "Only raw buffers are supported"))
+ if not shape:
+ raise OperationError(space.w_TypeError, space.wrap(
+ "numpy scalars from buffers not supported yet"))
+ totalsize = support.product(shape) * dtype.get_size()
+ if totalsize+offset > buf.getlength():
+ raise OperationError(space.w_TypeError, space.wrap(
+ "buffer is too small for requested array"))
+ storage = rffi.cast(RAW_STORAGE_PTR, raw_ptr)
+ storage = rffi.ptradd(storage, offset)
+ return W_NDimArray.from_shape_and_storage(space, shape, storage, dtype,
+ w_subtype=w_subtype,
+ w_base=w_buffer,
+ writable=buf.is_writable())
+
if not shape:
return W_NDimArray.new_scalar(space, dtype)
if space.is_w(w_subtype, space.gettypefor(W_NDimArray)):
@@ -1093,8 +1118,6 @@
Create an array from an existing buffer, given its address as int.
PyPy-only implementation detail.
"""
- from rpython.rtyper.lltypesystem import rffi
- from rpython.rlib.rawstorage import RAW_STORAGE_PTR
storage = rffi.cast(RAW_STORAGE_PTR, addr)
dtype = space.interp_w(interp_dtype.W_Dtype,
space.call_function(space.gettypefor(interp_dtype.W_Dtype),
diff --git a/pypy/module/micronumpy/iter.py b/pypy/module/micronumpy/iter.py
--- a/pypy/module/micronumpy/iter.py
+++ b/pypy/module/micronumpy/iter.py
@@ -71,7 +71,6 @@
final_strides = arr.get_strides() + strides
final_backstrides = arr.get_backstrides() + backstrides
final_dtype = subdtype
- print self.name,'strides',arr.get_strides(),strides
if subdtype.subdtype:
final_dtype = subdtype.subdtype
return W_NDimArray.new_slice(space, arr.start + ofs, final_strides,
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
@@ -238,13 +238,16 @@
while not out_iter.done():
axis_reduce__driver.jit_merge_point(shapelen=shapelen, func=func,
dtype=dtype)
- w_val = arr_iter.getitem().convert_to(dtype)
- if out_iter.first_line:
- if identity is not None:
- w_val = func(dtype, identity, w_val)
+ if arr_iter.done():
+ w_val = identity
else:
- cur = temp_iter.getitem()
- w_val = func(dtype, cur, w_val)
+ w_val = arr_iter.getitem().convert_to(dtype)
+ if out_iter.first_line:
+ if identity is not None:
+ w_val = func(dtype, identity, w_val)
+ else:
+ cur = temp_iter.getitem()
+ w_val = func(dtype, cur, w_val)
out_iter.setitem(w_val)
if cumulative:
temp_iter.setitem(w_val)
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
@@ -219,6 +219,7 @@
class AppTestNumArray(BaseNumpyAppTest):
spaceconfig = dict(usemodules=["micronumpy", "struct", "binascii"])
+
def w_CustomIndexObject(self, index):
class CustomIndexObject(object):
def __init__(self, index):
@@ -1299,6 +1300,9 @@
assert a.sum() == 105
assert a.max() == 14
assert array([]).sum() == 0.0
+ assert array([]).reshape(0, 2).sum() == 0.
+ assert (array([]).reshape(0, 2).sum(0) == [0., 0.]).all()
+ assert (array([]).reshape(0, 2).prod(0) == [1., 1.]).all()
raises(ValueError, 'array([]).max()')
assert (a.sum(0) == [30, 35, 40]).all()
assert (a.sum(axis=0) == [30, 35, 40]).all()
@@ -2089,6 +2093,69 @@
a = np.ndarray([1], dtype=bool)
assert a[0] == True
+
+class AppTestNumArrayFromBuffer(BaseNumpyAppTest):
+ spaceconfig = dict(usemodules=["micronumpy", "array", "mmap"])
+
+ def setup_class(cls):
+ from rpython.tool.udir import udir
+ BaseNumpyAppTest.setup_class.im_func(cls)
+ cls.w_tmpname = cls.space.wrap(str(udir.join('mmap-')))
+
+ def test_ndarray_from_buffer(self):
+ import numpypy as np
+ import array
+ buf = array.array('c', ['\x00']*2*3)
+ a = np.ndarray((3,), buffer=buf, dtype='i2')
+ a[0] = ord('b')
+ a[1] = ord('a')
+ a[2] = ord('r')
+ assert list(buf) == ['b', '\x00', 'a', '\x00', 'r', '\x00']
+ assert a.base is buf
+
+ def test_ndarray_subclass_from_buffer(self):
+ import numpypy as np
+ import array
+ buf = array.array('c', ['\x00']*2*3)
+ class X(np.ndarray):
+ pass
+ a = X((3,), buffer=buf, dtype='i2')
+ assert type(a) is X
+
+ def test_ndarray_from_buffer_and_offset(self):
+ import numpypy as np
+ import array
+ buf = array.array('c', ['\x00']*7)
+ buf[0] = 'X'
+ a = np.ndarray((3,), buffer=buf, offset=1, dtype='i2')
+ a[0] = ord('b')
+ a[1] = ord('a')
+ a[2] = ord('r')
+ assert list(buf) == ['X', 'b', '\x00', 'a', '\x00', 'r', '\x00']
+
+ def test_ndarray_from_buffer_out_of_bounds(self):
+ import numpypy as np
+ import array
+ buf = array.array('c', ['\x00']*2*10) # 20 bytes
+ info = raises(TypeError, "np.ndarray((11,), buffer=buf, dtype='i2')")
+ assert str(info.value).startswith('buffer is too small')
+ info = raises(TypeError, "np.ndarray((5,), buffer=buf, offset=15, dtype='i2')")
+ assert str(info.value).startswith('buffer is too small')
+
+ def test_ndarray_from_readonly_buffer(self):
+ import numpypy as np
+ from mmap import mmap, ACCESS_READ
+ f = open(self.tmpname, "w+")
+ f.write("hello")
+ f.flush()
+ buf = mmap(f.fileno(), 5, access=ACCESS_READ)
+ a = np.ndarray((5,), buffer=buf, dtype='c')
+ raises(ValueError, "a[0] = 'X'")
+ buf.close()
+ f.close()
+
+
+
class AppTestMultiDim(BaseNumpyAppTest):
def test_init(self):
import numpypy
@@ -3060,9 +3127,6 @@
exc = raises(IndexError, "a[0][None]")
assert exc.value.message == "invalid index"
- exc = raises(IndexError, "a[0][None]")
- assert exc.value.message == 'invalid index'
-
a[0]["x"][0] = 200
assert a[0]["x"][0] == 200
diff --git a/pypy/module/mmap/interp_mmap.py b/pypy/module/mmap/interp_mmap.py
--- a/pypy/module/mmap/interp_mmap.py
+++ b/pypy/module/mmap/interp_mmap.py
@@ -314,6 +314,14 @@
self.check_valid_writeable()
self.mmap.setslice(start, string)
+ def is_writable(self):
+ try:
+ self.mmap.check_writeable()
+ except RMMapError:
+ return False
+ else:
+ return True
+
def get_raw_address(self):
self.check_valid()
return self.mmap.data
diff --git a/pypy/testrunner_cfg.py b/pypy/testrunner_cfg.py
--- a/pypy/testrunner_cfg.py
+++ b/pypy/testrunner_cfg.py
@@ -3,7 +3,7 @@
DIRS_SPLIT = [
'translator/c', 'rlib',
- 'rpython/memory', 'jit/metainterp', 'rpython/test',
+ 'memory/test', 'jit/metainterp',
'jit/backend/arm', 'jit/backend/x86',
]
diff --git a/rpython/flowspace/flowcontext.py b/rpython/flowspace/flowcontext.py
--- a/rpython/flowspace/flowcontext.py
+++ b/rpython/flowspace/flowcontext.py
@@ -329,7 +329,7 @@
if closure is None:
self.closure = []
else:
- self.closure = [const(c.cell_contents) for c in closure]
+ self.closure = list(closure)
assert len(self.closure) == len(self.pycode.co_freevars)
def init_locals_stack(self, code):
@@ -846,7 +846,13 @@
LOOKUP_METHOD = LOAD_ATTR
def LOAD_DEREF(self, varindex):
- self.pushvalue(self.closure[varindex])
+ cell = self.closure[varindex]
+ try:
+ content = cell.cell_contents
+ except ValueError:
+ name = self.pycode.co_freevars[varindex]
+ raise FlowingError("Undefined closure variable '%s'" % name)
+ self.pushvalue(const(content))
def STORE_FAST(self, varindex):
w_newvalue = self.popvalue()
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
@@ -1212,6 +1212,39 @@
graph = self.codetest(f)
assert 'getattr' in self.all_operations(graph)
+ def test_empty_cell_unused(self):
+ def test(flag):
+ if flag:
+ b = 5
+ def g():
+ if flag:
+ return b
+ else:
+ return 1
+ return g
+ g1 = test(False)
+ graph = self.codetest(g1)
+ assert not self.all_operations(graph)
+ g2 = test(True)
+ graph = self.codetest(g2)
+ assert not self.all_operations(graph)
+
+ def test_empty_cell_error(self):
+ def test(flag):
+ if not flag:
+ b = 5
+ def g():
+ if flag:
+ return b
+ else:
+ return 1
+ return g
+ g = test(True)
+ with py.test.raises(FlowingError) as excinfo:
+ graph = self.codetest(g)
+ assert "Undefined closure variable 'b'" in str(excinfo.value)
+
+
DATA = {'x': 5,
'y': 6}
diff --git a/rpython/rtyper/module/ll_time.py b/rpython/rtyper/module/ll_time.py
--- a/rpython/rtyper/module/ll_time.py
+++ b/rpython/rtyper/module/ll_time.py
@@ -24,8 +24,12 @@
FTIME = 'ftime'
STRUCT_TIMEB = 'struct timeb'
includes = [TIME_H, 'time.h', 'errno.h', 'sys/select.h',
- 'sys/types.h', 'unistd.h', 'sys/timeb.h',
+ 'sys/types.h', 'unistd.h',
'sys/time.h', 'sys/resource.h']
+
+ if not sys.platform.startswith("openbsd"):
+ includes.append('sys/timeb.h')
+
need_rusage = True
@@ -86,16 +90,18 @@
c_gettimeofday = self.llexternal('gettimeofday',
[self.TIMEVALP, rffi.VOIDP], rffi.INT,
_nowrapper=True, releasegil=False)
+ c_ftime = None # We have gettimeofday(2), so force ftime(3) OFF.
else:
c_gettimeofday = None
- if self.HAVE_FTIME:
- self.configure(CConfigForFTime)
- c_ftime = self.llexternal(FTIME, [lltype.Ptr(self.TIMEB)],
- lltype.Void,
- _nowrapper=True, releasegil=False)
- else:
- c_ftime = None # to not confuse the flow space
+ # Only look for ftime(3) if gettimeofday(2) was not found.
+ if self.HAVE_FTIME:
+ self.configure(CConfigForFTime)
+ c_ftime = self.llexternal(FTIME, [lltype.Ptr(self.TIMEB)],
+ lltype.Void,
+ _nowrapper=True, releasegil=False)
+ else:
+ c_ftime = None # to not confuse the flow space
c_time = self.llexternal('time', [rffi.VOIDP], rffi.TIME_T,
_nowrapper=True, releasegil=False)
@@ -115,9 +121,9 @@
if rffi.cast(rffi.LONG, errcode) == 0:
result = decode_timeval(t)
lltype.free(t, flavor='raw')
- if result != -1:
- return result
- if self.HAVE_FTIME:
+ if result != -1:
+ return result
+ else: # assume using ftime(3)
t = lltype.malloc(self.TIMEB, flavor='raw')
c_ftime(t)
result = (float(intmask(t.c_time)) +
diff --git a/rpython/translator/c/src/exception.h b/rpython/translator/c/src/exception.h
--- a/rpython/translator/c/src/exception.h
+++ b/rpython/translator/c/src/exception.h
@@ -36,7 +36,6 @@
/* prototypes */
-#define RPyRaiseSimpleException(exc, msg) _RPyRaiseSimpleException(R##exc)
void _RPyRaiseSimpleException(RPYTHON_EXCEPTION rexc);
#endif
diff --git a/rpython/translator/c/src/support.h b/rpython/translator/c/src/support.h
--- a/rpython/translator/c/src/support.h
+++ b/rpython/translator/c/src/support.h
@@ -5,13 +5,9 @@
#define RUNNING_ON_LLINTERP 0
#define OP_JIT_RECORD_KNOWN_CLASS(i, c, r) /* nothing */
-#define FAIL_EXCEPTION(exc, msg) \
- { \
- RPyRaiseSimpleException(exc, msg); \
- }
-#define FAIL_OVF(msg) FAIL_EXCEPTION(PyExc_OverflowError, msg)
-#define FAIL_VAL(msg) FAIL_EXCEPTION(PyExc_ValueError, msg)
-#define FAIL_ZER(msg) FAIL_EXCEPTION(PyExc_ZeroDivisionError, msg)
+#define FAIL_OVF(msg) _RPyRaiseSimpleException(RPyExc_OverflowError)
+#define FAIL_VAL(msg) _RPyRaiseSimpleException(RPyExc_ValueError)
+#define FAIL_ZER(msg) _RPyRaiseSimpleException(RPyExc_ZeroDivisionError)
/* Extra checks can be enabled with the RPY_ASSERT or RPY_LL_ASSERT
* macros. They differ in the level at which the tests are made.
diff --git a/rpython/translator/platform/openbsd.py b/rpython/translator/platform/openbsd.py
--- a/rpython/translator/platform/openbsd.py
+++ b/rpython/translator/platform/openbsd.py
@@ -13,7 +13,7 @@
] + os.environ.get("CFLAGS", "").split()
def _libs(self, libraries):
- libraries=set(libraries + ("intl", "iconv", "compat"))
+ libraries=set(libraries + ("intl", "iconv"))
return ['-l%s' % lib for lib in libraries if lib not in ["crypt", "dl", "rt"]]
class OpenBSD_64(OpenBSD):
More information about the pypy-commit
mailing list