[pypy-commit] pypy cpyext-from: extend the new Py_bufferBuffer object to expose every field from Py_buffer

2017-01-06 Thread plan_rich
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

2017-01-06 Thread mattip
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

2017-01-06 Thread mattip
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

2017-01-06 Thread arigo
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

2017-01-06 Thread mattip
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

2017-01-06 Thread rlamy
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

2017-01-06 Thread rlamy
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

2017-01-06 Thread mattip
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

2017-01-06 Thread mattip
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

2017-01-06 Thread mattip
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

2017-01-06 Thread rlamy
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

2017-01-06 Thread rlamy
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

2017-01-06 Thread rlamy
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

2017-01-06 Thread plan_rich
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

2017-01-06 Thread plan_rich
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

2017-01-06 Thread plan_rich
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

2017-01-06 Thread arigo
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

2017-01-06 Thread arigo
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

2017-01-06 Thread rlamy
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()

2017-01-06 Thread rlamy
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