[pypy-commit] pypy cpyext-from: extend the new Py_bufferBuffer object to expose every field from Py_buffer
Author: Richard Plangger
Branch: cpyext-from
Changeset: r89387:09772a8274ba
Date: 2017-01-06 12:00 +0100
http://bitbucket.org/pypy/pypy/changeset/09772a8274ba/
Log:extend the new Py_bufferBuffer object to expose every field from
Py_buffer
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
@@ -208,25 +208,53 @@
py_mview = rffi.cast(PyMemoryViewObject, as_pyobj(space, w_mview))
view = py_mview.c_view
-fill_Py_buffer(space, buf, view)
+#_dup_Py_buffer(space, view, buf)
view.c_buf = rffi.cast(rffi.VOIDP, buf.get_raw_address())
# the docs say that in PyMemoryView_FromBuffer (and thus FromObject)
# this object must be NULL
view.c_obj = make_ref(space, w_obj)
# XXX what about w_mview.base = w_obj (see cpython 2.7 implementation)
-return py_mview
+return w_mview
+
+def _dup_Py_buffer(space, dest, src):
+if src.c_ndim == 1 and src.c_shape != 0:
+dest.c_shape = dest.smalltable[0]
+dest.c_shape[0] = src.smalltable[0]
+if src.c_ndim == 1 and src.c_strides != 0:
+dest.strides = dest.smalltable[1]
+dest.strides[0] = src.strides[0]
class Py_bufferBuffer(Buffer):
-_attrs_ = ['readonly', 'view']
+_attrs_ = ['view']
_immutable_ = True
def __init__(self, view):
self.view = view
-self.readonly = view.c_readonly
+
+@property
+def readonly(self):
+return rffi.cast(lltype.Signed, self.view.c_readonly)
+
+def getformat(self):
+return self.view.c_format[0]
def getlength(self):
-return self.view.c_len
+return rffi.cast(lltype.Signed, self.view.c_len)
+
+def getndim(self):
+return rffi.cast(lltype.Signed, self.view.c_ndim)
+
+def getshape(self):
+shape = self.view.c_shape
+return [shape[i] for i in range(self.getndim())]
+
+def getstrides(self):
+strides = self.view.c_strides
+return [strides[i] for i in range(self.getndim())]
+
+def getitemsize(self):
+return rffi.cast(lltype.Signed, self.view.c_itemsize)
def get_raw_address(self):
return self.view.c_buf
@@ -237,9 +265,7 @@
The memoryview object then owns the buffer, which means you shouldn't
try to release it yourself: it will be released on deallocation of the
memoryview object."""
-w_mview = W_MemoryView(Py_bufferBuffer(view))
-py_mview = rffi.cast(PyMemoryViewObject, as_pyobj(space, w_mview))
-return py_mview
+return W_MemoryView(Py_bufferBuffer(view))
@cpython_api([PyObject], PyObject)
def PyMemoryView_GET_BASE(space, w_obj):
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
@@ -20,9 +20,8 @@
def test_frombuffer(self, space, api):
w_buf = space.newbuffer(StringBuffer("hello"))
-py_memoryview = api.PyMemoryView_FromObject(w_buf)
-w_memoryview = from_ref(space, py_memoryview)
-view = api.PyMemoryView_GET_BUFFER(py_memoryview)
+w_memoryview = api.PyMemoryView_FromObject(w_buf)
+view = api.PyMemoryView_GET_BUFFER(w_memoryview)
assert view.c_ndim == 1
f = rffi.charp2str(view.c_format)
assert f == 'B'
@@ -31,7 +30,7 @@
assert view.c_len == 5
o = rffi.charp2str(view.c_buf)
assert o == 'hello'
-w_mv = from_ref(space, api.PyMemoryView_FromBuffer(view))
+w_mv = api.PyMemoryView_FromBuffer(view)
for f in ('format', 'itemsize', 'ndim', 'readonly',
'shape', 'strides', 'suboffsets'):
w_f = space.wrap(f)
___
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy missing-tp_new: merge default into branch
Author: Matti Picus
Branch: missing-tp_new
Changeset: r89388:ed458f15fed3
Date: 2017-01-05 07:19 +0200
http://bitbucket.org/pypy/pypy/changeset/ed458f15fed3/
Log:merge default into branch
diff too long, truncating to 2000 out of 2328 lines
diff --git a/LICENSE b/LICENSE
--- a/LICENSE
+++ b/LICENSE
@@ -28,7 +28,7 @@
DEALINGS IN THE SOFTWARE.
-PyPy Copyright holders 2003-2016
+PyPy Copyright holders 2003-2017
---
Except when otherwise stated (look for LICENSE files or information at
diff --git a/lib-python/2.7/ctypes/test/test_frombuffer.py
b/lib-python/2.7/ctypes/test/test_frombuffer.py
--- a/lib-python/2.7/ctypes/test/test_frombuffer.py
+++ b/lib-python/2.7/ctypes/test/test_frombuffer.py
@@ -32,7 +32,7 @@
del a; gc.collect(); gc.collect(); gc.collect()
self.assertEqual(x[:], expected)
-self.assertRaises((TypeError, ValueError),
+self.assertRaises(TypeError,
(c_char * 16).from_buffer, "a" * 16)
def test_fom_buffer_with_offset(self):
diff --git a/lib_pypy/_ctypes/basics.py b/lib_pypy/_ctypes/basics.py
--- a/lib_pypy/_ctypes/basics.py
+++ b/lib_pypy/_ctypes/basics.py
@@ -85,7 +85,17 @@
def from_buffer(self, obj, offset=0):
size = self._sizeofinstances()
+if isinstance(obj, (str, unicode)):
+# hack, buffer(str) will always return a readonly buffer.
+# CPython calls PyObject_AsWriteBuffer(...) here!
+# str cannot be modified, thus raise a type error in this case
+raise TypeError("Cannot use %s as modifiable buffer" %
str(type(obj)))
+
+# why not just call memoryview(obj)[offset:]?
+# array in Python 2.7 does not support the buffer protocol and will
+# fail, even though buffer is supported
buf = buffer(obj, offset, size)
+
if len(buf) < size:
raise ValueError(
"Buffer size too small (%d instead of at least %d bytes)"
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
@@ -428,11 +428,6 @@
``datetime.date`` is the superclass of ``datetime.datetime``).
Anyway, the proper fix is arguably to use a regular method call in
the first place: ``datetime.date.today().strftime(...)``
-
-* the ``__dict__`` attribute of new-style classes returns a normal dict, as
- opposed to a dict proxy like in CPython. Mutating the dict will change the
- 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).
* some functions and attributes of the ``gc`` module behave in a
slightly different way: for example, ``gc.enable`` and
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
@@ -76,3 +76,14 @@
PyMemoryViewObject with a PyBuffer attached so that the call to
``PyMemoryView_GET_BUFFER`` does not leak a PyBuffer-sized piece of memory.
Properly call ``bf_releasebuffer`` when not ``NULL``.
+
+.. branch: boehm-rawrefcount
+
+Support translations of cpyext with the Boehm GC (for special cases like
+revdb).
+
+.. branch: strbuf-as-buffer
+
+Implement StringBuffer.get_raw_address (missing feature for the buffer
protocol).
+More generally it is now possible to obtain the address of any object (if it
+is readonly) without pinning it.
diff --git a/pypy/goal/targetpypystandalone.py
b/pypy/goal/targetpypystandalone.py
--- a/pypy/goal/targetpypystandalone.py
+++ b/pypy/goal/targetpypystandalone.py
@@ -305,9 +305,9 @@
config.objspace.lonepycfiles = False
if config.objspace.usemodules.cpyext:
-if config.translation.gc != 'incminimark':
+if config.translation.gc not in ('incminimark', 'boehm'):
raise Exception("The 'cpyext' module requires the
'incminimark'"
-" GC. You need either
'targetpypystandalone.py"
+" 'boehm' GC. You need either
'targetpypystandalone.py"
" --withoutmod-cpyext' or '--gc=incminimark'")
config.translating = True
diff --git a/pypy/module/__pypy__/bytebuffer.py
b/pypy/module/__pypy__/bytebuffer.py
--- a/pypy/module/__pypy__/bytebuffer.py
+++ b/pypy/module/__pypy__/bytebuffer.py
@@ -4,6 +4,7 @@
from rpython.rlib.buffer import Buffer
from pypy.interpreter.gateway import unwrap_spec
+from rpython.rlib.rgc import nonmoving_raw_ptr_for_resizable_list
class ByteBuffer(Buffer):
@@ -22,6 +23,8 @@
def setitem(self, index, char):
self.data[index] = char
+def get_raw_address(self):
+return nonmoving_raw_ptr_for_resizable_list(self.data)
@unwrap_spec(length=int)
def bytebuffer(space, length):
diff --git a/pypy/module/_cffi_backend/func.py
b/pypy/module/_cffi_ba
[pypy-commit] pypy cpyext-from2: another approach, leaks memory
Author: Matti Picus Branch: cpyext-from2 Changeset: r89389:07be3b1bba7a Date: 2017-01-06 14:06 +0200 http://bitbucket.org/pypy/pypy/changeset/07be3b1bba7a/ Log:another approach, leaks memory 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 @@ -36,7 +36,22 @@ Fills a newly allocated PyMemoryViewObject with the given W_MemoryView object. """ py_obj = rffi.cast(PyMemoryViewObject, py_obj) -py_obj.c_view.c_obj = rffi.cast(PyObject, 0) +view = py_obj.c_view +ndim = w_obj.buf.getndim() +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_userdata) +rffi.setintfield(view, 'c_readonly', w_obj.buf.readonly) +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) def memory_realize(space, py_obj): """ @@ -88,29 +103,13 @@ return ret @cpython_api([PyObject], Py_bufferP, error=CANNOT_FAIL) -def PyMemoryView_GET_BUFFER(space, w_obj): +def PyMemoryView_GET_BUFFER(space, pyobj): """Return a pointer to the buffer-info structure wrapped by the given object. The object must be a memoryview instance; this macro doesn't check its type, you must do it yourself or you will risk crashes.""" -if not isinstance(w_obj, W_MemoryView): -return lltype.nullptr(Py_buffer) -py_memobj = rffi.cast(PyMemoryViewObject, as_pyobj(space, w_obj)) # no inc_ref -view = py_memobj.c_view -ndim = w_obj.buf.getndim() -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) # NO - this creates a ref cycle! -rffi.setintfield(view, 'c_readonly', w_obj.buf.readonly) -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) -return view +# XXX move to a c-macro +py_memobj = rffi.cast(PyMemoryViewObject, pyobj) # no inc_ref +return py_memobj.c_view def fill_Py_buffer(space, buf, view): # c_buf, c_obj have been filled in @@ -204,7 +203,9 @@ @cpython_api([PyObject], PyObject) def PyMemoryView_FromObject(space, w_obj): -return space.call_method(space.builtin, "memoryview", w_obj) +w_memview = space.call_method(space.builtin, "memoryview", w_obj) +py_memview = make_ref(space, w_memview, w_obj) +return py_memview @cpython_api([Py_bufferP], PyObject) def PyMemoryView_FromBuffer(space, view): @@ -212,6 +213,7 @@ The memoryview object then owns the buffer, which means you shouldn't try to release it yourself: it will be released on deallocation of the memoryview object.""" +assert view.c_obj w_obj = from_ref(space, view.c_obj) if isinstance(w_obj, W_MemoryView): return w_obj ___ pypy-commit mailing list [email protected] https://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy default: Fix ``"".replace("", "x", num)`` to give the same result as CPython
Author: Armin Rigo
Branch:
Changeset: r89390:bb49f0339d82
Date: 2017-01-06 13:09 +0100
http://bitbucket.org/pypy/pypy/changeset/bb49f0339d82/
Log:Fix ``"".replace("", "x", num)`` to give the same result as CPython
diff --git a/pypy/objspace/std/stringmethods.py
b/pypy/objspace/std/stringmethods.py
--- a/pypy/objspace/std/stringmethods.py
+++ b/pypy/objspace/std/stringmethods.py
@@ -548,6 +548,10 @@
sub = self._op_val(space, w_old)
by = self._op_val(space, w_new)
+# the following two lines are for being bug-to-bug compatible
+# with CPython: see issue #2448
+if count >= 0 and len(input) == 0:
+return self._empty()
try:
res = replace(input, sub, by, count)
except OverflowError:
diff --git a/pypy/objspace/std/test/test_bytesobject.py
b/pypy/objspace/std/test/test_bytesobject.py
--- a/pypy/objspace/std/test/test_bytesobject.py
+++ b/pypy/objspace/std/test/test_bytesobject.py
@@ -809,6 +809,16 @@
s = b"a" * (2**16)
raises(OverflowError, s.replace, b"", s)
+def test_replace_issue2448(self):
+# CPython's replace() method has a bug that makes
+# ''.replace('', 'x') gives a different answer than
+# ''.replace('', 'x', 1000). This is the case in all
+# known versions, at least until 2.7.13. Some people
+# call that a feature on the CPython issue report and
+# the discussion dies out, so it might never be fixed.
+assert ''.replace('', 'x') == 'x'
+assert ''.replace('', 'x', 1000) == ''
+
def test_getslice(self):
assert "foobar".__getslice__(4, 4321) == "ar"
s = b"abc"
___
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy cpyext-from2: fix tests, add result_is_ll
Author: Matti Picus
Branch: cpyext-from2
Changeset: r89391:14fae6e9cb91
Date: 2017-01-06 14:30 +0200
http://bitbucket.org/pypy/pypy/changeset/14fae6e9cb91/
Log:fix tests, add result_is_ll
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
@@ -201,7 +201,7 @@
return (_IsCContiguous(view) or _IsFortranContiguous(view))
return 0
-@cpython_api([PyObject], PyObject)
+@cpython_api([PyObject], PyObject, result_is_ll=True)
def PyMemoryView_FromObject(space, w_obj):
w_memview = space.call_method(space.builtin, "memoryview", w_obj)
py_memview = make_ref(space, w_memview, w_obj)
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
@@ -4,6 +4,7 @@
from pypy.module.cpyext.test.test_api import BaseApiTest
from pypy.module.cpyext.test.test_cpyext import AppTestCpythonExtensionBase
from rpython.rlib.buffer import StringBuffer
+from pypy.module.cpyext.pyobject import from_ref
only_pypy ="config.option.runappdirect and '__pypy__' not in
sys.builtin_module_names"
@@ -11,7 +12,7 @@
def test_fromobject(self, space, api):
w_hello = space.newbytes("hello")
assert api.PyObject_CheckBuffer(w_hello)
-w_view = api.PyMemoryView_FromObject(w_hello)
+w_view = from_ref(space, api.PyMemoryView_FromObject(w_hello))
w_char = space.call_method(w_view, '__getitem__', space.wrap(0))
assert space.eq_w(w_char, space.wrap('h'))
w_bytes = space.call_method(w_view, "tobytes")
@@ -19,7 +20,7 @@
def test_frombuffer(self, space, api):
w_buf = space.newbuffer(StringBuffer("hello"))
-w_memoryview = api.PyMemoryView_FromObject(w_buf)
+w_memoryview = from_ref(space, api.PyMemoryView_FromObject(w_buf))
view = api.PyMemoryView_GET_BUFFER(w_memoryview)
assert view.c_ndim == 1
f = rffi.charp2str(view.c_format)
___
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy rffi-parser-2: hg merge default
Author: Ronan Lamy
Branch: rffi-parser-2
Changeset: r89392:d93975c9dee0
Date: 2017-01-06 12:57 +
http://bitbucket.org/pypy/pypy/changeset/d93975c9dee0/
Log:hg merge default
diff too long, truncating to 2000 out of 31758 lines
diff --git a/LICENSE b/LICENSE
--- a/LICENSE
+++ b/LICENSE
@@ -28,7 +28,7 @@
DEALINGS IN THE SOFTWARE.
-PyPy Copyright holders 2003-2016
+PyPy Copyright holders 2003-2017
---
Except when otherwise stated (look for LICENSE files or information at
diff --git a/ctypes_configure/__init__.py b/ctypes_configure/__init__.py
deleted file mode 100644
diff --git a/ctypes_configure/cbuild.py b/ctypes_configure/cbuild.py
deleted file mode 100644
--- a/ctypes_configure/cbuild.py
+++ /dev/null
@@ -1,456 +0,0 @@
-
-import os, sys, inspect, re, imp, py
-from ctypes_configure import stdoutcapture
-import distutils
-
-debug = 0
-
-configdir = py.path.local.make_numbered_dir(prefix='ctypes_configure-')
-
-class ExternalCompilationInfo(object):
-
-_ATTRIBUTES = ['pre_include_lines', 'includes', 'include_dirs',
- 'post_include_lines', 'libraries', 'library_dirs',
- 'separate_module_sources', 'separate_module_files']
-_AVOID_DUPLICATES = ['separate_module_files', 'libraries', 'includes',
- 'include_dirs', 'library_dirs',
'separate_module_sources']
-
-def __init__(self,
- pre_include_lines = [],
- includes= [],
- include_dirs= [],
- post_include_lines = [],
- libraries = [],
- library_dirs= [],
- separate_module_sources = [],
- separate_module_files = []):
-"""
-pre_include_lines: list of lines that should be put at the top
-of the generated .c files, before any #include. They shouldn't
-contain an #include themselves.
-
-includes: list of .h file names to be #include'd from the
-generated .c files.
-
-include_dirs: list of dir names that is passed to the C compiler
-
-post_include_lines: list of lines that should be put at the top
-of the generated .c files, after the #includes.
-
-libraries: list of library names that is passed to the linker
-
-library_dirs: list of dir names that is passed to the linker
-
-separate_module_sources: list of multiline strings that are
-each written to a .c file and compiled separately and linked
-later on. (If function prototypes are needed for other .c files
-to access this, they can be put in post_include_lines.)
-
-separate_module_files: list of .c file names that are compiled
-separately and linked later on. (If an .h file is needed for
-other .c files to access this, it can be put in includes.)
-"""
-for name in self._ATTRIBUTES:
-value = locals()[name]
-assert isinstance(value, (list, tuple))
-setattr(self, name, tuple(value))
-
-def _value(self):
-return tuple([getattr(self, x) for x in self._ATTRIBUTES])
-
-def __hash__(self):
-return hash(self._value())
-
-def __eq__(self, other):
-return self.__class__ is other.__class__ and \
- self._value() == other._value()
-
-def __ne__(self, other):
-return not self == other
-
-def __repr__(self):
-info = []
-for attr in self._ATTRIBUTES:
-val = getattr(self, attr)
-info.append("%s=%s" % (attr, repr(val)))
-return "" % ", ".join(info)
-
-def merge(self, *others):
-others = list(others)
-attrs = {}
-for name in self._ATTRIBUTES:
-if name not in self._AVOID_DUPLICATES:
-s = []
-for i in [self] + others:
-s += getattr(i, name)
-attrs[name] = s
-else:
-s = set()
-attr = []
-for one in [self] + others:
-for elem in getattr(one, name):
-if elem not in s:
-s.add(elem)
-attr.append(elem)
-attrs[name] = attr
-return ExternalCompilationInfo(**attrs)
-
-def write_c_header(self, fileobj):
-for line in self.pre_include_lines:
-print >> fileobj, line
-for path in self.includes:
-print >> fileobj, '#include <%s>' % (path,)
-for line in self.post_include_lines:
-print >> fileobj, line
-
-def _copy_attributes(self):
-d = {}
-for attr in self._ATTRIBUTES:
-d[attr] = getattr(self, attr)
-return d
-
-def convert_sources_to_files(self, cache_dir=None, being_main=False):
-if not self.separate_module_sources:
-
[pypy-commit] pypy default: Remove unused function
Author: Ronan Lamy
Branch:
Changeset: r89393:366bc91ff0ea
Date: 2016-12-16 16:38 +
http://bitbucket.org/pypy/pypy/changeset/366bc91ff0ea/
Log:Remove unused function
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
@@ -617,14 +617,6 @@
% (cpyname, ))
build_exported_objects()
-def get_structtype_for_ctype(ctype):
-from pypy.module.cpyext.typeobjectdefs import PyTypeObjectPtr
-from pypy.module.cpyext.cdatetime import PyDateTime_CAPI
-from pypy.module.cpyext.intobject import PyIntObject
-return {"PyObject*": PyObject, "PyTypeObject*": PyTypeObjectPtr,
-"PyIntObject*": PyIntObject,
-"PyDateTime_CAPI*": lltype.Ptr(PyDateTime_CAPI)}[ctype]
-
# Note: as a special case, "PyObject" is the pointer type in RPython,
# corresponding to "PyObject *" in C. We do that only for PyObject.
# For example, "PyTypeObject" is the struct type even in RPython.
___
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy cpyext-from2: translation fixes
Author: Matti Picus Branch: cpyext-from2 Changeset: r89394:09411e996fff Date: 2017-01-06 15:45 +0200 http://bitbucket.org/pypy/pypy/changeset/09411e996fff/ Log:translation fixes 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 @@ -35,12 +35,13 @@ """ Fills a newly allocated PyMemoryViewObject with the given W_MemoryView object. """ +assert isinstance(w_obj, W_MemoryView) py_obj = rffi.cast(PyMemoryViewObject, py_obj) view = py_obj.c_view ndim = w_obj.buf.getndim() if ndim >= Py_MAX_NDIMS: # XXX warn? -return view +return fill_Py_buffer(space, w_obj.buf, view) try: view.c_buf = rffi.cast(rffi.VOIDP, w_obj.buf.get_raw_address()) @@ -108,7 +109,7 @@ object. The object must be a memoryview instance; this macro doesn't check its type, you must do it yourself or you will risk crashes.""" # XXX move to a c-macro -py_memobj = rffi.cast(PyMemoryViewObject, pyobj) # no inc_ref +py_memobj = rffi.cast(PyMemoryViewObject, pyobj) return py_memobj.c_view def fill_Py_buffer(space, buf, view): ___ pypy-commit mailing list [email protected] https://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy cpyext-from2: merge default into branch
Author: Matti Picus
Branch: cpyext-from2
Changeset: r89395:7e0eb703936d
Date: 2017-01-06 15:46 +0200
http://bitbucket.org/pypy/pypy/changeset/7e0eb703936d/
Log:merge default into branch
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
@@ -87,3 +87,7 @@
Implement StringBuffer.get_raw_address (missing feature for the buffer
protocol).
More generally it is now possible to obtain the address of any object (if it
is readonly) without pinning it.
+
+.. branch: cpyext-cleanup
+
+Refactor cpyext initialisation.
diff --git a/pypy/interpreter/baseobjspace.py b/pypy/interpreter/baseobjspace.py
--- a/pypy/interpreter/baseobjspace.py
+++ b/pypy/interpreter/baseobjspace.py
@@ -219,7 +219,7 @@
# cpyext types that may have only old buffer interface
w_impl = space.lookup(self, '__wbuffer__')
if w_impl is not None:
-w_result = space.get_and_call_function(w_impl, self,
+w_result = space.get_and_call_function(w_impl, self,
space.newint(flags))
if space.isinstance_w(w_result, space.w_buffer):
return w_result.buffer_w(space, flags)
@@ -665,9 +665,6 @@
def setup_builtin_modules(self):
"NOT_RPYTHON: only for initializing the space."
-if self.config.objspace.usemodules.cpyext:
-from pypy.module.cpyext.state import State
-self.fromcache(State).build_api(self)
self.getbuiltinmodule('sys')
self.getbuiltinmodule('imp')
self.getbuiltinmodule('__builtin__')
diff --git a/pypy/module/cpyext/__init__.py b/pypy/module/cpyext/__init__.py
--- a/pypy/module/cpyext/__init__.py
+++ b/pypy/module/cpyext/__init__.py
@@ -1,5 +1,4 @@
from pypy.interpreter.mixedmodule import MixedModule
-from pypy.interpreter import gateway
from pypy.module.cpyext.state import State
from pypy.module.cpyext import api
@@ -13,12 +12,17 @@
atexit_funcs = []
+def setup_after_space_initialization(self):
+state = self.space.fromcache(State)
+state.setup_rawrefcount()
+state.build_api()
+
def startup(self, space):
space.fromcache(State).startup(space)
method = pypy.module.cpyext.typeobject.get_new_method_def(space)
w_obj = pypy.module.cpyext.methodobject.W_PyCFunctionObject(space,
method, space.wrap(''))
space.appexec([space.type(w_obj)], """(methodtype):
-from pickle import Pickler
+from pickle import Pickler
Pickler.dispatch[methodtype] = Pickler.save_global
""")
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
@@ -1,5 +1,6 @@
import ctypes
import sys, os
+from collections import defaultdict
import py
@@ -71,7 +72,6 @@
class CConfig_constants:
_compilation_info_ = CConfig._compilation_info_
-VA_LIST_P = rffi.VOIDP # rffi.COpaquePtr('va_list')
CONST_STRING = lltype.Ptr(lltype.Array(lltype.Char,
hints={'nolength': True}),
use_cache=False)
@@ -364,8 +364,8 @@
func_name = func.func_name
if header is not None:
c_name = None
-assert func_name not in FUNCTIONS, (
-"%s already registered" % func_name)
+if func_name in FUNCTIONS_BY_HEADER[header]:
+raise ValueError("%s already registered" % func_name)
else:
c_name = func_name
api_function = ApiFunction(argtypes, restype, func, error,
@@ -463,9 +463,7 @@
return res
if header is not None:
-if header == DEFAULT_HEADER:
-FUNCTIONS[func_name] = api_function
-FUNCTIONS_BY_HEADER.setdefault(header, {})[func_name] =
api_function
+FUNCTIONS_BY_HEADER[header][func_name] = api_function
INTERPLEVEL_API[func_name] = unwrapper_catch # used in tests
return unwrapper # used in 'normal' RPython code.
return decorate
@@ -489,8 +487,7 @@
GLOBALS[name] = (typ, expr)
INTERPLEVEL_API = {}
-FUNCTIONS = {}
-FUNCTIONS_BY_HEADER = {}
+FUNCTIONS_BY_HEADER = defaultdict(dict)
# These are C symbols which cpyext will export, but which are defined in .c
# files somewhere in the implementation of cpyext (rather than being defined in
@@ -526,6 +523,8 @@
'PyCapsule_SetPointer', 'PyCapsule_SetName', 'PyCapsule_SetDestructor',
'PyCapsule_SetContext', 'PyCapsule_Import', 'PyCapsule_Type',
'_Py_get_capsule_type',
+'PyComplex_AsCComplex', 'PyComplex_FromCComplex',
+
'PyObject_AsReadBuffer', 'PyObject_AsWriteBuffer',
'PyObject_CheckReadBuffer',
'PyOS_getsig', 'PyOS_setsig',
@@ -572,7 +571,9 @@
# PyExc_AttributeError, PyExc_OverflowError, PyExc_ImportError,
# PyExc_NameError, PyExc_MemoryError, PyExc_RuntimeError,
[pypy-commit] pypy missing-tp_new: merge default into branch
Author: Matti Picus
Branch: missing-tp_new
Changeset: r89396:d1617cb7e740
Date: 2017-01-06 16:00 +0200
http://bitbucket.org/pypy/pypy/changeset/d1617cb7e740/
Log:merge default into branch
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
@@ -87,3 +87,7 @@
Implement StringBuffer.get_raw_address (missing feature for the buffer
protocol).
More generally it is now possible to obtain the address of any object (if it
is readonly) without pinning it.
+
+.. branch: cpyext-cleanup
+
+Refactor cpyext initialisation.
diff --git a/pypy/interpreter/baseobjspace.py b/pypy/interpreter/baseobjspace.py
--- a/pypy/interpreter/baseobjspace.py
+++ b/pypy/interpreter/baseobjspace.py
@@ -219,7 +219,7 @@
# cpyext types that may have only old buffer interface
w_impl = space.lookup(self, '__wbuffer__')
if w_impl is not None:
-w_result = space.get_and_call_function(w_impl, self,
+w_result = space.get_and_call_function(w_impl, self,
space.newint(flags))
if space.isinstance_w(w_result, space.w_buffer):
return w_result.buffer_w(space, flags)
@@ -665,9 +665,6 @@
def setup_builtin_modules(self):
"NOT_RPYTHON: only for initializing the space."
-if self.config.objspace.usemodules.cpyext:
-from pypy.module.cpyext.state import State
-self.fromcache(State).build_api(self)
self.getbuiltinmodule('sys')
self.getbuiltinmodule('imp')
self.getbuiltinmodule('__builtin__')
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
@@ -3419,17 +3419,22 @@
BCharA = new_array_type(BCharP, None)
p1 = from_buffer(BCharA, b"foo")
assert p1 == from_buffer(BCharA, b"foo")
+import gc; gc.collect()
+assert p1 == from_buffer(BCharA, b"foo")
py.test.raises(TypeError, from_buffer, BCharA, u+"foo")
try:
from __builtin__ import buffer
except ImportError:
pass
else:
+# Python 2 only
contents = from_buffer(BCharA, buffer(b"foo"))
+assert len(contents) == len(p1)
for i in range(len(contents)):
assert contents[i] == p1[i]
-p4 = from_buffer(BCharA, b"f\x00\x00\x00o\x00\x00\x00o\x00\x00\x00")
+p4 = buffer(u+"foo")
contents = from_buffer(BCharA, buffer(u+"foo"))
+assert len(contents) == len(p4)
for i in range(len(contents)):
assert contents[i] == p4[i]
try:
@@ -3438,6 +3443,7 @@
pass
else:
contents = from_buffer(BCharA, memoryview(b"foo"))
+assert len(contents) == len(p1)
for i in range(len(contents)):
assert contents[i] == p1[i]
diff --git a/pypy/module/cpyext/__init__.py b/pypy/module/cpyext/__init__.py
--- a/pypy/module/cpyext/__init__.py
+++ b/pypy/module/cpyext/__init__.py
@@ -1,5 +1,4 @@
from pypy.interpreter.mixedmodule import MixedModule
-from pypy.interpreter import gateway
from pypy.module.cpyext.state import State
from pypy.module.cpyext import api
@@ -13,12 +12,17 @@
atexit_funcs = []
+def setup_after_space_initialization(self):
+state = self.space.fromcache(State)
+state.setup_rawrefcount()
+state.build_api()
+
def startup(self, space):
space.fromcache(State).startup(space)
method = pypy.module.cpyext.typeobject.get_new_method_def(space)
w_obj = pypy.module.cpyext.methodobject.W_PyCFunctionObject(space,
method, space.wrap(''))
space.appexec([space.type(w_obj)], """(methodtype):
-from pickle import Pickler
+from pickle import Pickler
Pickler.dispatch[methodtype] = Pickler.save_global
""")
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
@@ -1,5 +1,6 @@
import ctypes
import sys, os
+from collections import defaultdict
import py
@@ -72,7 +73,6 @@
class CConfig_constants:
_compilation_info_ = CConfig._compilation_info_
-VA_LIST_P = rffi.VOIDP # rffi.COpaquePtr('va_list')
CONST_STRING = lltype.Ptr(lltype.Array(lltype.Char,
hints={'nolength': True}),
use_cache=False)
@@ -365,8 +365,8 @@
func_name = func.func_name
if header is not None:
c_name = None
-assert func_name not in FUNCTIONS, (
-"%s already registered" % func_name)
+if func_name in FUNCTIONS_BY_HEADER[header]:
+raise ValueError("%s already registered" % func_name)
else:
c_name = func_name
api_function = ApiFunction(a
[pypy-commit] pypy api_func-refactor: Replace body of @cpython_api with a _create_api_func() function
Author: Ronan Lamy
Branch: api_func-refactor
Changeset: r89397:de8be6201edb
Date: 2017-01-06 14:15 +
http://bitbucket.org/pypy/pypy/changeset/de8be6201edb/
Log:Replace body of @cpython_api with a _create_api_func() function
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
@@ -344,6 +344,14 @@
- set `gil` to "acquire", "release" or "around" to acquire the GIL,
release the GIL, or both
"""
+def decorate(func):
+return _create_api_func(func, argtypes, restype, error, header, gil,
+result_borrowed, result_is_ll)
+return decorate
+
+def _create_api_func(
+func, argtypes, restype, error=_NOT_SPECIFIED, header=DEFAULT_HEADER,
+gil=None, result_borrowed=False, result_is_ll=False):
if isinstance(restype, lltype.Typedef):
real_restype = restype.OF
else:
@@ -359,7 +367,7 @@
expect_integer = (isinstance(real_restype, lltype.Primitive) and
rffi.cast(restype, 0) == 0)
-def decorate(func):
+if True: # preserve indentation
func._always_inline_ = 'try'
func_name = func.func_name
if header is not None:
@@ -466,7 +474,7 @@
FUNCTIONS_BY_HEADER[header][func_name] = api_function
INTERPLEVEL_API[func_name] = unwrapper_catch # used in tests
return unwrapper # used in 'normal' RPython code.
-return decorate
+
def cpython_struct(name, fields, forward=None, level=1):
configname = name.replace(' ', '__')
___
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy api_func-refactor: deindent
Author: Ronan Lamy
Branch: api_func-refactor
Changeset: r89398:52133eacf24f
Date: 2017-01-06 14:15 +
http://bitbucket.org/pypy/pypy/changeset/52133eacf24f/
Log:deindent
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
@@ -367,113 +367,112 @@
expect_integer = (isinstance(real_restype, lltype.Primitive) and
rffi.cast(restype, 0) == 0)
-if True: # preserve indentation
-func._always_inline_ = 'try'
-func_name = func.func_name
-if header is not None:
-c_name = None
-if func_name in FUNCTIONS_BY_HEADER[header]:
-raise ValueError("%s already registered" % func_name)
-else:
-c_name = func_name
-api_function = ApiFunction(argtypes, restype, func, error,
- c_name=c_name, gil=gil,
- result_borrowed=result_borrowed,
- result_is_ll=result_is_ll)
-func.api_func = api_function
+func._always_inline_ = 'try'
+func_name = func.func_name
+if header is not None:
+c_name = None
+if func_name in FUNCTIONS_BY_HEADER[header]:
+raise ValueError("%s already registered" % func_name)
+else:
+c_name = func_name
+api_function = ApiFunction(argtypes, restype, func, error,
+c_name=c_name, gil=gil,
+result_borrowed=result_borrowed,
+result_is_ll=result_is_ll)
+func.api_func = api_function
-if error is _NOT_SPECIFIED:
-raise ValueError("function %s has no return value for exceptions"
- % func)
-names = api_function.argnames
-types_names_enum_ui = unrolling_iterable(enumerate(
-zip(api_function.argtypes,
-[tp_name.startswith("w_") for tp_name in names])))
+if error is _NOT_SPECIFIED:
+raise ValueError("function %s has no return value for exceptions"
+% func)
+names = api_function.argnames
+types_names_enum_ui = unrolling_iterable(enumerate(
+zip(api_function.argtypes,
+[tp_name.startswith("w_") for tp_name in names])))
[email protected]()
-def unwrapper(space, *args):
-from pypy.module.cpyext.pyobject import Py_DecRef, is_pyobj
-from pypy.module.cpyext.pyobject import from_ref, as_pyobj
-newargs = ()
-keepalives = ()
-assert len(args) == len(api_function.argtypes)
-for i, (ARG, is_wrapped) in types_names_enum_ui:
-input_arg = args[i]
-if is_PyObject(ARG) and not is_wrapped:
-# build a 'PyObject *' (not holding a reference)
-if not is_pyobj(input_arg):
-keepalives += (input_arg,)
-arg = rffi.cast(ARG, as_pyobj(space, input_arg))
-else:
-arg = rffi.cast(ARG, input_arg)
-elif ARG == rffi.VOIDP and not is_wrapped:
-# unlike is_PyObject case above, we allow any kind of
-# argument -- just, if it's an object, we assume the
-# caller meant for it to become a PyObject*.
-if input_arg is None or isinstance(input_arg, W_Root):
-keepalives += (input_arg,)
-arg = rffi.cast(ARG, as_pyobj(space, input_arg))
-else:
-arg = rffi.cast(ARG, input_arg)
-elif (is_PyObject(ARG) or ARG == rffi.VOIDP) and is_wrapped:
-# build a W_Root, possibly from a 'PyObject *'
-if is_pyobj(input_arg):
-arg = from_ref(space, input_arg)
-else:
-arg = input_arg
[email protected]()
+def unwrapper(space, *args):
+from pypy.module.cpyext.pyobject import Py_DecRef, is_pyobj
+from pypy.module.cpyext.pyobject import from_ref, as_pyobj
+newargs = ()
+keepalives = ()
+assert len(args) == len(api_function.argtypes)
+for i, (ARG, is_wrapped) in types_names_enum_ui:
+input_arg = args[i]
+if is_PyObject(ARG) and not is_wrapped:
+# build a 'PyObject *' (not holding a reference)
+if not is_pyobj(input_arg):
+keepalives += (input_arg,)
+arg = rffi.cast(ARG, as_pyobj(space, input_arg))
+else:
+arg = rffi.cast(ARG, input_arg)
+elif ARG == rffi.VOIDP and not is_wrapped:
+# unlike is_PyObject case above, we allow any kind of
+# argument -- just, if it's an object, we assume the
+
[pypy-commit] pypy api_func-refactor: Do not expose unexported functions to INTERPLEVEL_API either
Author: Ronan Lamy Branch: api_func-refactor Changeset: r89399:8db0229e854d Date: 2017-01-06 14:35 + http://bitbucket.org/pypy/pypy/changeset/8db0229e854d/ Log:Do not expose unexported functions to INTERPLEVEL_API either 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 @@ -471,7 +471,7 @@ if header is not None: FUNCTIONS_BY_HEADER[header][func_name] = api_function -INTERPLEVEL_API[func_name] = unwrapper_catch # used in tests +INTERPLEVEL_API[func_name] = unwrapper_catch # used in tests return unwrapper # used in 'normal' RPython code. ___ pypy-commit mailing list [email protected] https://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy default: merge cpyext-from2
Author: Richard Plangger
Branch:
Changeset: r89401:0615cd861fd0
Date: 2017-01-06 17:20 +0100
http://bitbucket.org/pypy/pypy/changeset/0615cd861fd0/
Log:merge cpyext-from2
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
@@ -35,8 +35,24 @@
"""
Fills a newly allocated PyMemoryViewObject with the given W_MemoryView
object.
"""
+assert isinstance(w_obj, W_MemoryView)
py_obj = rffi.cast(PyMemoryViewObject, py_obj)
-py_obj.c_view.c_obj = rffi.cast(PyObject, 0)
+view = py_obj.c_view
+ndim = w_obj.buf.getndim()
+if ndim >= Py_MAX_NDIMS:
+# XXX warn?
+return
+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_userdata)
+rffi.setintfield(view, 'c_readonly', w_obj.buf.readonly)
+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)
def memory_realize(space, py_obj):
"""
@@ -88,29 +104,13 @@
return ret
@cpython_api([PyObject], Py_bufferP, error=CANNOT_FAIL)
-def PyMemoryView_GET_BUFFER(space, w_obj):
+def PyMemoryView_GET_BUFFER(space, pyobj):
"""Return a pointer to the buffer-info structure wrapped by the given
object. The object must be a memoryview instance; this macro doesn't
check its type, you must do it yourself or you will risk crashes."""
-if not isinstance(w_obj, W_MemoryView):
-return lltype.nullptr(Py_buffer)
-py_memobj = rffi.cast(PyMemoryViewObject, as_pyobj(space, w_obj)) # no
inc_ref
-view = py_memobj.c_view
-ndim = w_obj.buf.getndim()
-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) # NO - this creates a ref cycle!
-rffi.setintfield(view, 'c_readonly', w_obj.buf.readonly)
-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)
-return view
+# XXX move to a c-macro
+py_memobj = rffi.cast(PyMemoryViewObject, pyobj)
+return py_memobj.c_view
def fill_Py_buffer(space, buf, view):
# c_buf, c_obj have been filled in
@@ -202,9 +202,11 @@
return (_IsCContiguous(view) or _IsFortranContiguous(view))
return 0
-@cpython_api([PyObject], PyObject)
+@cpython_api([PyObject], PyObject, result_is_ll=True)
def PyMemoryView_FromObject(space, w_obj):
-return space.call_method(space.builtin, "memoryview", w_obj)
+w_memview = space.call_method(space.builtin, "memoryview", w_obj)
+py_memview = make_ref(space, w_memview, w_obj)
+return py_memview
@cpython_api([Py_bufferP], PyObject)
def PyMemoryView_FromBuffer(space, view):
@@ -212,6 +214,7 @@
The memoryview object then owns the buffer, which means you shouldn't
try to release it yourself: it will be released on deallocation of the
memoryview object."""
+assert view.c_obj
w_obj = from_ref(space, view.c_obj)
if isinstance(w_obj, W_MemoryView):
return w_obj
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
@@ -4,6 +4,7 @@
from pypy.module.cpyext.test.test_api import BaseApiTest
from pypy.module.cpyext.test.test_cpyext import AppTestCpythonExtensionBase
from rpython.rlib.buffer import StringBuffer
+from pypy.module.cpyext.pyobject import from_ref
only_pypy ="config.option.runappdirect and '__pypy__' not in
sys.builtin_module_names"
@@ -11,7 +12,7 @@
def test_fromobject(self, space, api):
w_hello = space.newbytes("hello")
assert api.PyObject_CheckBuffer(w_hello)
-w_view = api.PyMemoryView_FromObject(w_hello)
+w_view = from_ref(space, api.PyMemoryView_FromObject(w_hello))
w_char = space.call_method(w_view, '__getitem__', space.wrap(0))
assert space.eq_w(w_char, space.wrap('h'))
w_bytes = space.call_method(w_view, "tobytes")
@@ -19,7 +20,7 @@
def test_frombuffer(self, space, api):
w_buf = space.newbuffer(StringBuffer("hello"))
-w_memoryview = api.PyMemoryView_FromObject(w_buf)
+w_memoryview = from_ref(space, api.PyMemoryView_FromObject(w_buf))
view = api.PyMemoryView_GET_BUFFER(w_memoryview)
assert view
[pypy-commit] pypy cpyext-from: close branch
Author: Richard Plangger Branch: cpyext-from Changeset: r89400:8e6bf680169d Date: 2017-01-06 14:59 +0100 http://bitbucket.org/pypy/pypy/changeset/8e6bf680169d/ Log:close branch 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 @@ -211,7 +211,7 @@ #_dup_Py_buffer(space, view, buf) view.c_buf = rffi.cast(rffi.VOIDP, buf.get_raw_address()) # the docs say that in PyMemoryView_FromBuffer (and thus FromObject) -# this object must be NULL +# this object must be NULL in Python 3.5 view.c_obj = make_ref(space, w_obj) # XXX what about w_mview.base = w_obj (see cpython 2.7 implementation) 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 @@ -36,6 +36,7 @@ str2 = w_other.as_str() return space.wrap(getattr(operator, name)(str1, str2)) +import pdb; pdb.set_trace() try: buf = space.buffer_w(w_other, space.BUF_CONTIG_RO) except OperationError as e: ___ pypy-commit mailing list [email protected] https://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy default: document branch
Author: Richard Plangger Branch: Changeset: r89402:61294de6f130 Date: 2017-01-06 17:22 +0100 http://bitbucket.org/pypy/pypy/changeset/61294de6f130/ Log:document branch 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 @@ -91,3 +91,8 @@ .. branch: cpyext-cleanup Refactor cpyext initialisation. + +.. branch: cpyext-from2 + +Fix a test failure introduced by strbuf-as-buffer + ___ pypy-commit mailing list [email protected] https://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy py3.5: Update the unraisable-exception output to include a full traceback
Author: Armin Rigo
Branch: py3.5
Changeset: r89403:671ae80283ca
Date: 2017-01-06 17:35 +0100
http://bitbucket.org/pypy/pypy/changeset/671ae80283ca/
Log:Update the unraisable-exception output to include a full traceback
diff --git a/pypy/interpreter/error.py b/pypy/interpreter/error.py
--- a/pypy/interpreter/error.py
+++ b/pypy/interpreter/error.py
@@ -248,6 +248,10 @@
def write_unraisable(self, space, where, w_object=None,
with_traceback=False, extra_line=''):
+# Note: since Python 3.5, unraisable exceptions are always
+# printed with a traceback. Setting 'with_traceback=False'
+# only asks for a different format, starting with the message
+# "Exception Xxx ignored".
if w_object is None:
objrepr = ''
else:
@@ -257,31 +261,32 @@
objrepr = ""
#
try:
-if with_traceback:
-try:
-self.normalize_exception(space)
-except OperationError:
-pass
-w_t = self.w_type
-w_v = self.get_w_value(space)
-w_tb = space.wrap(self.get_traceback())
-space.appexec([space.wrap(where),
- space.wrap(objrepr),
- space.wrap(extra_line),
- w_t, w_v, w_tb],
-"""(where, objrepr, extra_line, t, v, tb):
-import sys, traceback
-if where or objrepr:
-sys.stderr.write('From %s%s:\\n' % (where, objrepr))
-if extra_line:
-sys.stderr.write(extra_line)
-traceback.print_exception(t, v, tb)
-""")
+try:
+self.normalize_exception(space)
+except OperationError:
+pass
+w_t = self.w_type
+w_v = self.get_w_value(space)
+w_tb = space.wrap(self.get_traceback())
+if where or objrepr:
+if with_traceback:
+first_line = 'From %s%s:\n' % (where, objrepr)
+else:
+first_line = 'Exception ignored in: %s%s\n' % (
+where, objrepr)
else:
-msg = 'Exception %s in %s%s ignored\n' % (
-self.errorstr(space, use_repr=True), where, objrepr)
-space.call_method(space.sys.get('stderr'), 'write',
- space.wrap(msg))
+first_line = ''
+space.appexec([space.wrap(first_line),
+ space.wrap(extra_line),
+ w_t, w_v, w_tb],
+"""(first_line, extra_line, t, v, tb):
+import sys
+sys.stderr.write(first_line)
+if extra_line:
+sys.stderr.write(extra_line)
+import traceback
+traceback.print_exception(t, v, tb)
+""")
except OperationError:
pass # ignored
diff --git a/pypy/interpreter/executioncontext.py
b/pypy/interpreter/executioncontext.py
--- a/pypy/interpreter/executioncontext.py
+++ b/pypy/interpreter/executioncontext.py
@@ -574,9 +574,13 @@
if self.gc_disabled(w_obj):
return
try:
-space.get_and_call_function(w_del, w_obj)
+w_impl = space.get(w_del, w_obj)
except Exception as e:
report_error(space, e, "method __del__ of ", w_obj)
+try:
+space.call_function(w_impl)
+except Exception as e:
+report_error(space, e, '', w_impl)
# Call the RPython-level _finalize_() method.
try:
diff --git a/pypy/objspace/std/test/test_userobject.py
b/pypy/objspace/std/test/test_userobject.py
--- a/pypy/objspace/std/test/test_userobject.py
+++ b/pypy/objspace/std/test/test_userobject.py
@@ -163,29 +163,38 @@
from io import StringIO
class A(object):
def __del__(self):
-yaddadlaouti
+raise ValueError('foo bar')
prev = sys.stderr
try:
sys.stderr = StringIO()
A()
gc.collect()
res = sys.stderr.getvalue()
+sys.stderr = StringIO()
A()
gc.collect()
res2 = sys.stderr.getvalue()
+A.__del__ = lambda a, b, c: None # will get "not enough arguments"
+sys.stderr = StringIO()
+A()
+gc.collect()
+res3 = sys.stderr.getvalue()
finally:
sys.stderr = prev
-assert res.startswith('Exception')
-assert 'NameError' in res
-assert 'yaddadlaouti' in res
-assert 'ignored' in res
-assert res.count('\n') == 1# a sin
[pypy-commit] pypy py3.5: translation fix
Author: Armin Rigo Branch: py3.5 Changeset: r89404:593191898bc9 Date: 2017-01-06 17:22 + http://bitbucket.org/pypy/pypy/changeset/593191898bc9/ Log:translation fix diff --git a/pypy/interpreter/executioncontext.py b/pypy/interpreter/executioncontext.py --- a/pypy/interpreter/executioncontext.py +++ b/pypy/interpreter/executioncontext.py @@ -577,10 +577,11 @@ w_impl = space.get(w_del, w_obj) except Exception as e: report_error(space, e, "method __del__ of ", w_obj) -try: -space.call_function(w_impl) -except Exception as e: -report_error(space, e, '', w_impl) +else: +try: +space.call_function(w_impl) +except Exception as e: +report_error(space, e, '', w_impl) # Call the RPython-level _finalize_() method. try: ___ pypy-commit mailing list [email protected] https://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy api_func-refactor: Don't store 'api_function' on the hidden 'func', it's already on 'unwrapper'; kill dead code
Author: Ronan Lamy
Branch: api_func-refactor
Changeset: r89406:a004964c95d4
Date: 2017-01-06 17:54 +
http://bitbucket.org/pypy/pypy/changeset/a004964c95d4/
Log:Don't store 'api_function' on the hidden 'func', it's already on
'unwrapper'; kill dead code
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
@@ -411,11 +411,6 @@
c_name=c_name, gil=gil,
result_borrowed=result_borrowed,
result_is_ll=result_is_ll)
-func.api_func = api_function
-
-if error is _NOT_SPECIFIED:
-raise ValueError("function %s has no return value for exceptions"
-% func)
names = api_function.argnames
types_names_enum_ui = unrolling_iterable(enumerate(
zip(api_function.argtypes,
___
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy api_func-refactor: Don't pass the header to _create_api_func()
Author: Ronan Lamy
Branch: api_func-refactor
Changeset: r89405:4c1556231a40
Date: 2017-01-06 17:34 +
http://bitbucket.org/pypy/pypy/changeset/4c1556231a40/
Log:Don't pass the header to _create_api_func()
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
@@ -344,13 +344,54 @@
- set `gil` to "acquire", "release" or "around" to acquire the GIL,
release the GIL, or both
"""
+if isinstance(restype, lltype.Typedef):
+real_restype = restype.OF
+else:
+real_restype = restype
+expect_integer = (isinstance(real_restype, lltype.Primitive) and
+ rffi.cast(restype, 0) == 0)
def decorate(func):
-return _create_api_func(func, argtypes, restype, error, header, gil,
-result_borrowed, result_is_ll)
+if header is not None:
+if func.__name__ in FUNCTIONS_BY_HEADER[header]:
+raise ValueError("%s already registered" % func.__name__)
+if header is not None:
+c_name = None
+else:
+c_name = func.__name__
+
+unwrapper = _create_api_func(
+func, argtypes, restype, error, c_name, gil, result_borrowed,
+result_is_ll)
+
+# ZZZ is this whole logic really needed??? It seems to be only
+# for RPython code calling PyXxx() functions directly. I would
+# think that usually directly calling the function is clean
+# enough now
+def unwrapper_catch(space, *args):
+try:
+res = unwrapper(space, *args)
+except OperationError as e:
+if not hasattr(unwrapper.api_func, "error_value"):
+raise
+state = space.fromcache(State)
+state.set_exception(e)
+if is_PyObject(restype):
+return None
+else:
+return unwrapper.api_func.error_value
+got_integer = isinstance(res, (int, long, float))
+assert got_integer == expect_integer, (
+'got %r not integer' % (res,))
+return res
+
+if header is not None:
+FUNCTIONS_BY_HEADER[header][func.__name__] = unwrapper.api_func
+INTERPLEVEL_API[func.__name__] = unwrapper_catch # used in tests
+return unwrapper
return decorate
def _create_api_func(
-func, argtypes, restype, error=_NOT_SPECIFIED, header=DEFAULT_HEADER,
+func, argtypes, restype, error=_NOT_SPECIFIED, c_name=None,
gil=None, result_borrowed=False, result_is_ll=False):
if isinstance(restype, lltype.Typedef):
real_restype = restype.OF
@@ -364,17 +405,8 @@
error = CANNOT_FAIL
if type(error) is int:
error = rffi.cast(real_restype, error)
-expect_integer = (isinstance(real_restype, lltype.Primitive) and
- rffi.cast(restype, 0) == 0)
func._always_inline_ = 'try'
-func_name = func.func_name
-if header is not None:
-c_name = None
-if func_name in FUNCTIONS_BY_HEADER[header]:
-raise ValueError("%s already registered" % func_name)
-else:
-c_name = func_name
api_function = ApiFunction(argtypes, restype, func, error,
c_name=c_name, gil=gil,
result_borrowed=result_borrowed,
@@ -447,32 +479,7 @@
unwrapper.func = func
unwrapper.api_func = api_function
-
-# ZZZ is this whole logic really needed??? It seems to be only
-# for RPython code calling PyXxx() functions directly. I would
-# think that usually directly calling the function is clean
-# enough now
-def unwrapper_catch(space, *args):
-try:
-res = unwrapper(space, *args)
-except OperationError as e:
-if not hasattr(api_function, "error_value"):
-raise
-state = space.fromcache(State)
-state.set_exception(e)
-if is_PyObject(restype):
-return None
-else:
-return api_function.error_value
-got_integer = isinstance(res, (int, long, float))
-assert got_integer == expect_integer, (
-'got %r not integer' % (res,))
-return res
-
-if header is not None:
-FUNCTIONS_BY_HEADER[header][func_name] = api_function
-INTERPLEVEL_API[func_name] = unwrapper_catch # used in tests
-return unwrapper # used in 'normal' RPython code.
+return unwrapper
def cpython_struct(name, fields, forward=None, level=1):
___
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit
