[prev in list] [next in list] [prev in thread] [next in thread] 

List:       pypy-svn
Subject:    [pypy-commit] pypy py3.5: hg merge default
From:       rlamy <pypy.commits () gmail ! com>
Date:       2016-10-31 17:01:13
Message-ID: 581778d9.958c1c0a.c398c.0719 () mx ! google ! com
[Download RAW message or body]

Author: Ronan Lamy <ronan.lamy@gmail.com>
Branch: py3.5
Changeset: r88005:dd3f94d97955
Date: 2016-10-31 16:40 +0000
http://bitbucket.org/pypy/pypy/changeset/dd3f94d97955/

Log:	hg merge default

diff --git a/lib_pypy/cffi/cparser.py b/lib_pypy/cffi/cparser.py
--- a/lib_pypy/cffi/cparser.py
+++ b/lib_pypy/cffi/cparser.py
@@ -334,6 +334,8 @@
                         realtype, quals = self._get_type_and_quals(
                             decl.type, name=decl.name, partial_length_ok=True)
                     self._declare('typedef ' + decl.name, realtype, quals=quals)
+                elif decl.__class__.__name__ == 'Pragma':
+                    pass    # skip pragma, only in pycparser 2.15
                 else:
                     raise api.CDefError("unrecognized construct", decl)
         except api.FFIError as e:
diff --git a/lib_pypy/cffi/model.py b/lib_pypy/cffi/model.py
--- a/lib_pypy/cffi/model.py
+++ b/lib_pypy/cffi/model.py
@@ -519,10 +519,18 @@
             smallest_value = min(self.enumvalues)
             largest_value = max(self.enumvalues)
         else:
-            raise api.CDefError("%r has no values explicitly defined: "
-                                "refusing to guess which integer type it is "
-                                "meant to be (unsigned/signed, int/long)"
-                % self._get_c_name())
+            import warnings
+            try:
+                # XXX!  The goal is to ensure that the warnings.warn()
+                # will not suppress the warning.  We want to get it
+                # several times if we reach this point several times.
+                __warningregistry__.clear()
+            except NameError:
+                pass
+            warnings.warn("%r has no values explicitly defined; "
+                          "guessing that it is equivalent to 'unsigned int'"
+                          % self._get_c_name())
+            smallest_value = largest_value = 0
         if smallest_value < 0:   # needs a signed type
             sign = 1
             candidate1 = PrimitiveType("int")
diff --git a/lib_pypy/cffi/setuptools_ext.py b/lib_pypy/cffi/setuptools_ext.py
--- a/lib_pypy/cffi/setuptools_ext.py
+++ b/lib_pypy/cffi/setuptools_ext.py
@@ -1,4 +1,5 @@
 import os
+import sys
 
 try:
     basestring
@@ -74,8 +75,13 @@
     Add py_limited_api to kwds if setuptools >= 26 is in use.
     Do not alter the setting if it already exists.
     Setuptools takes care of ignoring the flag on Python 2 and PyPy.
+
+    CPython itself should ignore the flag in a debugging version
+    (by not listing .abi3.so in the extensions it supports), but
+    it doesn't so far, creating troubles.  That's why we check
+    for "not sys.flags.debug". (http://bugs.python.org/issue28401)
     """
-    if 'py_limited_api' not in kwds:
+    if 'py_limited_api' not in kwds and not sys.flags.debug:
         import setuptools
         try:
             setuptools_major_version = int(setuptools.__version__.partition('.')[0])
diff --git a/pypy/doc/release-pypy2.7-v5.6.0.rst \
b/pypy/doc/release-pypy2.7-v5.6.0.rst new file mode 100644
--- /dev/null
+++ b/pypy/doc/release-pypy2.7-v5.6.0.rst
@@ -0,0 +1,142 @@
+============
+PyPy2.7 v5.6
+============
+
+We have released PyPy2.7 v5.6, about two months after PyPy2.7 v5.4.
+This new PyPy2.7 release includes the upstream stdlib version 2.7.12.
+
+We continue to make incremental improvements to our C-API
+compatability layer (cpyext). We pass all but a few of the tests in the
+upstream numpy `test suite`_. 
+
+Work proceeds at a good pace on the PyPy3.5
+version due to a grant_ from the Mozilla Foundation, and some of those
+changes have been backported to PyPy2.7 where relevant
+
+We changed ``timeit`` to now report average +- standard deviation, which is
+better than the misleading minimum value reported in CPython.
+
+XXX
+
+As always, this release fixed many issues and bugs raised by the
+growing community of PyPy users. We strongly recommend updating.
+
+You can download the PyPy2.7 v5.6 release here:
+
+    http://pypy.org/download.html
+
+We would like to thank our donors for the continued support of the PyPy
+project.
+
+We would also like to thank our contributors and
+encourage new people to join the project. PyPy has many
+layers and we need help with all of them: `PyPy`_ and `RPython`_ documentation
+improvements, tweaking popular `modules`_ to run on pypy, or general `help`_
+with making RPython's JIT even better.
+
+.. _`test suite`: https://bitbucket.org/pypy/pypy/wiki/Adventures%20in%20cpyext%20compatibility
 +.. _cffi: https://cffi.readthedocs.org
+.. _grant: https://morepypy.blogspot.com/2016/08/pypy-gets-funding-from-mozilla-for.html
 +.. _`PyPy`: http://doc.pypy.org
+.. _`RPython`: https://rpython.readthedocs.org
+.. _`modules`: http://doc.pypy.org/en/latest/project-ideas.html#make-more-python-modules-pypy-friendly
 +.. _`help`: http://doc.pypy.org/en/latest/project-ideas.html
+
+What is PyPy?
+=============
+
+PyPy is a very compliant Python interpreter, almost a drop-in replacement for
+CPython 2.7. It's fast (`PyPy and CPython 2.7.x`_ performance comparison)
+due to its integrated tracing JIT compiler.
+
+We also welcome developers of other `dynamic languages`_ to see what RPython
+can do for them.
+
+This release supports: 
+
+  * **x86** machines on most common operating systems
+    (Linux 32/64 bits, Mac OS X 64 bits, Windows 32 bits, OpenBSD, FreeBSD)
+  
+  * newer **ARM** hardware (ARMv6 or ARMv7, with VFPv3) running Linux,
+  
+  * big- and little-endian variants of **PPC64** running Linux,
+
+  * **s390x** running Linux
+
+.. _`PyPy and CPython 2.7.x`: http://speed.pypy.org
+.. _`dynamic languages`: http://pypyjs.org
+
+Other Highlights (since 5.4 released Aug 31, 2016)
+=========================================================
+
+* New features
+  * Allow tests run with `-A` to find `libm.so` even if it is a script not a
+    dynamically loadable file
+  * Backport fixes to rposix on windows from py2.5
+  * Allow user-defined ``__getitem__`` on subclasses of ``str`` and ``unicode``
+  * Add ``inode`` to ``scandir()`` on posix systems
+  * Support more attributes on ``super``
+  * Issue #2386: non-latin1 unicode keys were ignored in ``unicode.format(**d)``
+  * Restore the ability to translate with CPython
+  * Update to CFFI 1.8.4
+  * Support the new buffer protocol in cpyext and numpypy
+  * Add ``rposix.sync()``
+  * Support full-precision nanosecond times in os.stat()
+  * Add documentation about the assembler backends to RPYthon
+  * Search for the stdlibs from the libpypy shared object rather than the pypy-c \
exe, +    changes downstream packaging requirments
+  * Add ``try_inline``, like ``always_inline`` and ``dont_inline`` to RPython
+  * Reject ``'a'.strip(buffer(' '))`` like cpython (the argument to strip must
+    be ``str`` or ``unicode``)
+  * Allow ``warning.warn(('something', 1), Warning)`` like on CPython
+  * Refactor ``rclock`` and add some more ``CLOCK_xxx`` constants on
+    relevant platforms
+  * Backport the ``'faulthandler`` module from py3.5
+  * Improve the error message when trying to call a method where the ``self``
+    parameter is missing in the definition
+  * Implement ``rposix.cpu_count``
+  * Support translation on FreeBSD running on PowerPC
+  * Implement ``__rmod__`` on ``str`` and ``unicode`` types
+  * Issue warnings for stricter handling of ``__new__``, ``__init__`` args
+
+* Bug Fixes
+  * Tweak a float comparison with 0 in `backendopt.inline` to avoid rounding errors
+  * Fix translation of the sandbox
+  * Fix for an issue where `unicode.decode('utf8', 'custom_replace')` messed up
+    the last byte of a unicode string sometimes
+  * fix some calls to functions through window's COM interface
+  * fix minor leak when the C call to socketpair() fails
+  * make sure (-1.0 + 0j).__hash__(), (-1.0).__hash__() returns -2
+  * Fix for an issue where PyBytesResize was called on a fresh pyobj
+  * Fix bug in codewriter about passing the ``exitswitch`` variable to a call
+  * Don't crash in ``merge_if_blocks`` if the values are symbolics
+  * Issue #2325/2361: __class__ assignment between two classes with the same
+    slots
+  * Issue #2409: don't leak the file descriptor when doing ``open('some-dir')``
+  * Windows fixes around vmprof
+  * Don't use ``sprintf()`` from inside a signal handler
+  * Test and fix bug from the ``guard_not_forced_2`` branch, which didn't
+    save the floating-point register
+  * ``_numpypy.add.reduce`` returns a scalar now
+
+* Performance improvements:
+  * Improve method calls on oldstyle classes
+  * Clean and refactor code for testing cpyext to allow sharing with py3.5
+  * Refactor a building the map of reflected ops in ``_numpypy``
+  * Improve merging of virtual states in the JIT in order to avoid jumping to the
+    preamble
+  * In JIT residual calls, if the called function starts with a fast-path like
+    ``if x.foo != 0: return x.foo``, then inline the check before doing the
+     ``CALL``.
+  * Ensure ``make_inputargs`` fails properly when given arguments with type 
+    information
+  * Makes ``optimiseopt`` iterative instead of recursive so it can be reasoned
+    about more easily and debugging is faster
+  * Refactor and remove dead code from ``optimizeopt``, ``resume``
+  
+
+.. _resolved: http://doc.pypy.org/en/latest/whatsnew-5.6.0.html
+
+Please update, and continue to help us make PyPy better.
+
+Cheers
diff --git a/pypy/module/_cffi_backend/cbuffer.py \
                b/pypy/module/_cffi_backend/cbuffer.py
--- a/pypy/module/_cffi_backend/cbuffer.py
+++ b/pypy/module/_cffi_backend/cbuffer.py
@@ -3,6 +3,7 @@
 from pypy.interpreter.gateway import unwrap_spec, interp2app
 from pypy.interpreter.typedef import TypeDef, make_weakref_descr
 from pypy.module._cffi_backend import cdataobj, ctypeptr, ctypearray
+from pypy.module._cffi_backend import ctypestruct
 
 from rpython.rlib.buffer import Buffer
 from rpython.rtyper.annlowlevel import llstr
@@ -89,7 +90,12 @@
     ctype = w_cdata.ctype
     if isinstance(ctype, ctypeptr.W_CTypePointer):
         if size < 0:
-            size = ctype.ctitem.size
+            structobj = w_cdata.get_structobj()
+            if (structobj is not None and
+                isinstance(structobj.ctype, ctypestruct.W_CTypeStructOrUnion)):
+                size = structobj._sizeof()
+            if size < 0:
+                size = ctype.ctitem.size
     elif isinstance(ctype, ctypearray.W_CTypeArray):
         if size < 0:
             size = w_cdata._sizeof()
diff --git a/pypy/module/_cffi_backend/cdataobj.py \
                b/pypy/module/_cffi_backend/cdataobj.py
--- a/pypy/module/_cffi_backend/cdataobj.py
+++ b/pypy/module/_cffi_backend/cdataobj.py
@@ -329,7 +329,7 @@
     def getattr(self, w_attr):
         cfield = self.getcfield(w_attr)
         with self as ptr:
-            w_res = cfield.read(ptr)
+            w_res = cfield.read(ptr, self)
         return w_res
 
     def setattr(self, w_attr, w_value):
@@ -432,6 +432,9 @@
         lst = ct.cdata_dir()
         return space.newlist([space.wrap(s) for s in lst])
 
+    def get_structobj(self):
+        return None
+
 
 class W_CDataMem(W_CData):
     """This is used only by the results of cffi.cast('int', x)
@@ -453,28 +456,36 @@
     by newp().  They create and free their own memory according to an
     allocator."""
 
-    # the 'length' is either >= 0 for arrays, or -1 for pointers.
-    _attrs_ = ['length']
-    _immutable_fields_ = ['length']
+    # the 'allocated_length' is >= 0 for arrays; for var-sized
+    # structures it is the total size in bytes; otherwise it is -1.
+    _attrs_ = ['allocated_length']
+    _immutable_fields_ = ['allocated_length']
 
     def __init__(self, space, cdata, ctype, length=-1):
         W_CData.__init__(self, space, cdata, ctype)
-        self.length = length
+        self.allocated_length = length
 
     def _repr_extra(self):
         return self._repr_extra_owning()
 
     def _sizeof(self):
         ctype = self.ctype
-        if self.length >= 0:
+        if self.allocated_length >= 0:
             from pypy.module._cffi_backend import ctypearray
-            assert isinstance(ctype, ctypearray.W_CTypeArray)
-            return self.length * ctype.ctitem.size
+            if isinstance(ctype, ctypearray.W_CTypeArray):
+                return self.allocated_length * ctype.ctitem.size
+            else:
+                return self.allocated_length    # var-sized struct size
         else:
             return ctype.size
 
     def get_array_length(self):
-        return self.length
+        from pypy.module._cffi_backend import ctypearray
+        assert isinstance(self.ctype, ctypearray.W_CTypeArray)
+        return self.allocated_length
+
+    def get_structobj(self):
+        return self
 
 
 class W_CDataNewStd(W_CDataNewOwning):
@@ -508,12 +519,19 @@
         self.structobj = structobj
 
     def _repr_extra(self):
-        return self._repr_extra_owning()
+        return self.structobj._repr_extra_owning()
 
     def _do_getitem(self, ctype, i):
         assert i == 0
         return self.structobj
 
+    def get_structobj(self):
+        structobj = self.structobj
+        if isinstance(structobj, W_CDataNewOwning):
+            return structobj
+        else:
+            return None
+
 
 class W_CDataSliced(W_CData):
     """Subclass with an explicit length, for slices."""
diff --git a/pypy/module/_cffi_backend/ctypeptr.py \
                b/pypy/module/_cffi_backend/ctypeptr.py
--- a/pypy/module/_cffi_backend/ctypeptr.py
+++ b/pypy/module/_cffi_backend/ctypeptr.py
@@ -213,13 +213,16 @@
             # a W_CDataPtrToStruct object which has a strong reference
             # to a W_CDataNewOwning that really contains the structure.
             #
-            if not space.is_w(w_init, space.w_None):
-                ctitem.force_lazy_struct()
-                if ctitem._with_var_array:
+            varsize_length = -1
+            ctitem.force_lazy_struct()
+            if ctitem._with_var_array:
+                if not space.is_w(w_init, space.w_None):
                     datasize = ctitem.convert_struct_from_object(
                         lltype.nullptr(rffi.CCHARP.TO), w_init, datasize)
+                varsize_length = datasize
             #
-            cdatastruct = allocator.allocate(space, datasize, ctitem)
+            cdatastruct = allocator.allocate(space, datasize, ctitem,
+                                             length=varsize_length)
             ptr = cdatastruct.unsafe_escaping_ptr()
             cdata = cdataobj.W_CDataPtrToStructOrUnion(space, ptr,
                                                        self, cdatastruct)
diff --git a/pypy/module/_cffi_backend/ctypestruct.py \
                b/pypy/module/_cffi_backend/ctypestruct.py
--- a/pypy/module/_cffi_backend/ctypestruct.py
+++ b/pypy/module/_cffi_backend/ctypestruct.py
@@ -210,7 +210,7 @@
         return W_CField(self.ctype, offset + self.offset,
                         self.bitshift, self.bitsize, self.flags | fflags)
 
-    def read(self, cdata):
+    def read(self, cdata, w_cdata):
         cdata = rffi.ptradd(cdata, self.offset)
         if self.bitshift == self.BS_REGULAR:
             return self.ctype.convert_to_object(cdata)
@@ -218,6 +218,14 @@
             from pypy.module._cffi_backend import ctypearray
             ctype = self.ctype
             assert isinstance(ctype, ctypearray.W_CTypeArray)
+            structobj = w_cdata.get_structobj()
+            if structobj is not None:
+                # variable-length array
+                size = structobj.allocated_length - self.offset
+                if size >= 0:
+                    arraylen = size // ctype.ctitem.size
+                    return cdataobj.W_CDataSliced(ctype.space, cdata, ctype,
+                                                  arraylen)
             return cdataobj.W_CData(ctype.space, cdata, ctype.ctptr)
         else:
             return self.convert_bitfield_to_object(cdata)
diff --git a/pypy/module/_cffi_backend/newtype.py \
                b/pypy/module/_cffi_backend/newtype.py
--- a/pypy/module/_cffi_backend/newtype.py
+++ b/pypy/module/_cffi_backend/newtype.py
@@ -353,7 +353,7 @@
         if fbitsize < 0:
             # not a bitfield: common case
 
-            if isinstance(ftype, ctypearray.W_CTypeArray) and ftype.length==0:
+            if isinstance(ftype, ctypearray.W_CTypeArray) and ftype.length<=0:
                 bs_flag = ctypestruct.W_CField.BS_EMPTY_ARRAY
             else:
                 bs_flag = ctypestruct.W_CField.BS_REGULAR
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
@@ -3161,17 +3161,19 @@
     assert d[1][0] == 'y'
     assert d[1][1].type is BArray
     assert d[1][1].offset == size_of_int()
-    assert d[1][1].bitshift == -1
+    assert d[1][1].bitshift == -2
     assert d[1][1].bitsize == -1
     #
     p = newp(new_pointer_type(BStruct))
     p.x = 42
     assert p.x == 42
-    assert typeof(p.y) is BIntP
+    assert typeof(p.y) is BArray
+    assert len(p.y) == 0
     assert p.y == cast(BIntP, p) + 1
     #
     p = newp(new_pointer_type(BStruct), [100])
     assert p.x == 100
+    assert len(p.y) == 0
     #
     # Tests for
     #    ffi.new("struct_with_var_array *", [field.., [the_array_items..]])
@@ -3186,6 +3188,10 @@
             p.y[0] = 200
             assert p.y[2] == 0
             p.y[2] = 400
+        assert len(p.y) == 3
+        assert len(p[0].y) == 3
+        assert len(buffer(p)) == sizeof(BInt) * 4
+        assert sizeof(p[0]) == sizeof(BInt) * 4
         plist.append(p)
     for i in range(20):
         p = plist[i]
@@ -3193,13 +3199,31 @@
         assert p.y[0] == 200
         assert p.y[1] == i
         assert p.y[2] == 400
-        assert list(p.y[0:3]) == [200, i, 400]
+        assert list(p.y) == [200, i, 400]
     #
     # the following assignment works, as it normally would, for any array field
-    p.y = [500, 600]
-    assert list(p.y[0:3]) == [500, 600, 400]
+    p.y = [501, 601]
+    assert list(p.y) == [501, 601, 400]
+    p[0].y = [500, 600]
+    assert list(p[0].y) == [500, 600, 400]
+    assert repr(p) == "<cdata 'foo *' owning %d bytes>" % (
+        sizeof(BStruct) + 3 * sizeof(BInt),)
+    assert repr(p[0]) == "<cdata 'foo' owning %d bytes>" % (
+        sizeof(BStruct) + 3 * sizeof(BInt),)
+    assert sizeof(p[0]) == sizeof(BStruct) + 3 * sizeof(BInt)
+    #
+    # from a non-owning pointer, we can't get the length
+    q = cast(new_pointer_type(BStruct), p)
+    assert q.y[0] == 500
+    assert q[0].y[0] == 500
+    py.test.raises(TypeError, len, q.y)
+    py.test.raises(TypeError, len, q[0].y)
+    assert typeof(q.y) is BIntP
+    assert typeof(q[0].y) is BIntP
+    assert sizeof(q[0]) == sizeof(BStruct)
     #
     # error cases
+    py.test.raises(IndexError, "p.y[4]")
     py.test.raises(TypeError, "p.y = cast(BIntP, 0)")
     py.test.raises(TypeError, "p.y = 15")
     py.test.raises(TypeError, "p.y = None")
@@ -3264,6 +3288,33 @@
         assert p.x[5] == 60
         assert p.x[6] == 70
 
+def test_struct_array_not_aligned():
+    # struct a { int x; char y; char z[]; };
+    # ends up of size 8, but 'z' is at offset 5
+    BChar = new_primitive_type("char")
+    BInt = new_primitive_type("int")
+    BCharP = new_pointer_type(BChar)
+    BArray = new_array_type(BCharP, None)
+    BStruct = new_struct_type("foo")
+    complete_struct_or_union(BStruct, [('x', BInt),
+                                       ('y', BChar),
+                                       ('z', BArray)])
+    assert sizeof(BStruct) == 2 * size_of_int()
+    def offsetof(BType, fieldname):
+        return typeoffsetof(BType, fieldname)[1]
+    base = offsetof(BStruct, 'z')
+    assert base == size_of_int() + 1
+    #
+    p = newp(new_pointer_type(BStruct), {'z': 3})
+    assert sizeof(p[0]) == base + 3
+    q = newp(new_pointer_type(BStruct), {'z': size_of_int()})
+    assert sizeof(q) == size_of_ptr()
+    assert sizeof(q[0]) == base + size_of_int()
+    assert len(p.z) == 3
+    assert len(p[0].z) == 3
+    assert len(q.z) == size_of_int()
+    assert len(q[0].z) == size_of_int()
+
 def test_ass_slice():
     BChar = new_primitive_type("char")
     BArray = new_array_type(new_pointer_type(BChar), None)
diff --git a/pypy/module/_cffi_backend/test/test_recompiler.py \
                b/pypy/module/_cffi_backend/test/test_recompiler.py
--- a/pypy/module/_cffi_backend/test/test_recompiler.py
+++ b/pypy/module/_cffi_backend/test/test_recompiler.py
@@ -408,11 +408,14 @@
             'test_misdeclared_field_1',
             "struct foo_s { int a[6]; };")
         assert ffi.sizeof("struct foo_s") == 24  # found by the actual C code
-        p = ffi.new("struct foo_s *")
-        # lazily build the fields and boom:
-        e = raises(ffi.error, getattr, p, "a")
-        assert str(e.value).startswith("struct foo_s: wrong size for field 'a' "
-                                       "(cdef says 20, but C compiler says 24)")
+        try:
+            # lazily build the fields and boom:
+            p = ffi.new("struct foo_s *")
+            p.a
+            assert False, "should have raised"
+        except ffi.error as e:
+            assert str(e).startswith("struct foo_s: wrong size for field 'a' "
+                                     "(cdef says 20, but C compiler says 24)")
 
     def test_open_array_in_struct(self):
         ffi, lib = self.prepare(
@@ -420,8 +423,10 @@
             'test_open_array_in_struct',
             "struct foo_s { int b; int a[]; };")
         assert ffi.sizeof("struct foo_s") == 4
-        p = ffi.new("struct foo_s *", [5, [10, 20, 30]])
+        p = ffi.new("struct foo_s *", [5, [10, 20, 30, 40]])
         assert p.a[2] == 30
+        assert ffi.sizeof(p) == ffi.sizeof("void *")
+        assert ffi.sizeof(p[0]) == 5 * ffi.sizeof("int")
 
     def test_math_sin_type(self):
         ffi, lib = self.prepare(
@@ -954,6 +959,7 @@
             "struct foo_s { int x; int a[5][8]; int y; };")
         assert ffi.sizeof('struct foo_s') == 42 * ffi.sizeof('int')
         s = ffi.new("struct foo_s *")
+        assert ffi.typeof(s.a) == ffi.typeof("int[5][8]")
         assert ffi.sizeof(s.a) == 40 * ffi.sizeof('int')
         assert s.a[4][7] == 0
         raises(IndexError, 's.a[4][8]')
@@ -961,6 +967,18 @@
         assert ffi.typeof(s.a) == ffi.typeof("int[5][8]")
         assert ffi.typeof(s.a[0]) == ffi.typeof("int[8]")
 
+    def test_struct_array_guess_length_3(self):
+        ffi, lib = self.prepare(
+            "struct foo_s { int a[][...]; };",
+            'test_struct_array_guess_length_3',
+            "struct foo_s { int x; int a[5][7]; int y; };")
+        assert ffi.sizeof('struct foo_s') == 37 * ffi.sizeof('int')
+        s = ffi.new("struct foo_s *")
+        assert ffi.typeof(s.a) == ffi.typeof("int[][7]")
+        assert s.a[4][6] == 0
+        raises(IndexError, 's.a[4][7]')
+        assert ffi.typeof(s.a[0]) == ffi.typeof("int[7]")
+
     def test_global_var_array_2(self):
         ffi, lib = self.prepare(
             "int a[...][...];",
diff --git a/pypy/module/cpyext/test/test_ztranslation.py \
b/pypy/module/cpyext/test/test_ztranslation.py deleted file mode 100644
--- a/pypy/module/cpyext/test/test_ztranslation.py
+++ /dev/null
@@ -1,10 +0,0 @@
-from pypy.objspace.fake.checkmodule import checkmodule
-from pypy.module.cpyext import pyobject
-
-def test_cpyext_translates(monkeypatch):
-    def from_ref(space, ref):
-        # XXX: avoid 'assert isinstance(w_type, W_TypeObject)' from the
-        # original from_ref, just return w_some_obj
-        return space.w_object
-    monkeypatch.setattr(pyobject, 'from_ref', from_ref)
-    checkmodule('cpyext', '_rawffi', translate_startup=False)
diff --git a/pypy/module/cpyext/typeobject.py b/pypy/module/cpyext/typeobject.py
--- a/pypy/module/cpyext/typeobject.py
+++ b/pypy/module/cpyext/typeobject.py
@@ -273,7 +273,7 @@
         if len(slot_names) == 1:
             if not getattr(pto, slot_names[0]):
                 setattr(pto, slot_names[0], slot_func_helper)
-        elif (w_type.getname(space) in ('list', 'tuple') and
+        elif ((w_type is space.w_list or w_type is space.w_tuple) and
               slot_names[0] == 'c_tp_as_number'):
             # XXX hack - hwo can we generalize this? The problem is method
             # names like __mul__ map to more than one slot, and we have no
diff --git a/pypy/module/micronumpy/test/test_ztranslation.py \
b/pypy/module/micronumpy/test/test_ztranslation.py deleted file mode 100644
--- a/pypy/module/micronumpy/test/test_ztranslation.py
+++ /dev/null
@@ -1,4 +0,0 @@
-from pypy.objspace.fake.checkmodule import checkmodule
-
-def test_numpy_translates():
-    checkmodule('micronumpy')
diff --git a/pypy/module/test_lib_pypy/cffi_tests/cffi0/backend_tests.py \
                b/pypy/module/test_lib_pypy/cffi_tests/cffi0/backend_tests.py
--- a/pypy/module/test_lib_pypy/cffi_tests/cffi0/backend_tests.py
+++ b/pypy/module/test_lib_pypy/cffi_tests/cffi0/backend_tests.py
@@ -1356,15 +1356,15 @@
         assert ffi.getctype("e1*") == 'e1 *'
 
     def test_opaque_enum(self):
+        import warnings
         ffi = FFI(backend=self.Backend())
         ffi.cdef("enum foo;")
-        from cffi import __version_info__
-        if __version_info__ < (1, 8):
-            py.test.skip("re-enable me in version 1.8")
-        e = py.test.raises(CDefError, ffi.cast, "enum foo", -1)
-        assert str(e.value) == (
-            "'enum foo' has no values explicitly defined: refusing to guess "
-            "which integer type it is meant to be (unsigned/signed, int/long)")
+        with warnings.catch_warnings(record=True) as log:
+            n = ffi.cast("enum foo", -1)
+            assert int(n) == 0xffffffff
+        assert str(log[0].message) == (
+            "'enum foo' has no values explicitly defined; "
+            "guessing that it is equivalent to 'unsigned int'")
 
     def test_new_ctype(self):
         ffi = FFI(backend=self.Backend())
diff --git a/pypy/module/test_lib_pypy/cffi_tests/cffi0/test_ffi_backend.py \
                b/pypy/module/test_lib_pypy/cffi_tests/cffi0/test_ffi_backend.py
--- a/pypy/module/test_lib_pypy/cffi_tests/cffi0/test_ffi_backend.py
+++ b/pypy/module/test_lib_pypy/cffi_tests/cffi0/test_ffi_backend.py
@@ -283,10 +283,20 @@
         ffi.cdef("struct foo_s { int x; int a[]; };")
         p = ffi.new("struct foo_s *", [100, [200, 300, 400]])
         assert p.x == 100
-        assert ffi.typeof(p.a) is ffi.typeof("int *")   # no length available
+        assert ffi.typeof(p.a) is ffi.typeof("int[]")
+        assert len(p.a) == 3                            # length recorded
         assert p.a[0] == 200
         assert p.a[1] == 300
         assert p.a[2] == 400
+        assert list(p.a) == [200, 300, 400]
+        q = ffi.cast("struct foo_s *", p)
+        assert q.x == 100
+        assert ffi.typeof(q.a) is ffi.typeof("int *")   # no length recorded
+        py.test.raises(TypeError, len, q.a)
+        assert q.a[0] == 200
+        assert q.a[1] == 300
+        assert q.a[2] == 400
+        py.test.raises(TypeError, list, q.a)
 
     @pytest.mark.skipif("sys.platform != 'win32'")
     def test_getwinerror(self):
diff --git a/pypy/module/test_lib_pypy/cffi_tests/cffi0/test_verify.py \
                b/pypy/module/test_lib_pypy/cffi_tests/cffi0/test_verify.py
--- a/pypy/module/test_lib_pypy/cffi_tests/cffi0/test_verify.py
+++ b/pypy/module/test_lib_pypy/cffi_tests/cffi0/test_verify.py
@@ -562,7 +562,8 @@
                      "int bar(struct foo_s *f) { return f->a[14]; }\n")
     assert ffi.sizeof('struct foo_s') == 19 * ffi.sizeof('int')
     s = ffi.new("struct foo_s *")
-    assert ffi.typeof(s.a) is ffi.typeof('int *')   # because no length
+    assert ffi.typeof(s.a) is ffi.typeof('int[]')   # implicit max length
+    assert len(s.a) == 18  # max length, computed from the size and start offset
     s.a[14] = 4242
     assert lib.bar(s) == 4242
     # with no declared length, out-of-bound accesses are not detected
@@ -592,10 +593,15 @@
     ffi.verify("struct foo_s { int x; int a[]; };")
     assert ffi.sizeof('struct foo_s') == 1 * ffi.sizeof('int')
     s = ffi.new("struct foo_s *", [424242, 4])
-    assert ffi.sizeof(s[0]) == 1 * ffi.sizeof('int')   # the same in C
+    assert ffi.sizeof(ffi.typeof(s[0])) == 1 * ffi.sizeof('int')
+    assert ffi.sizeof(s[0]) == 5 * ffi.sizeof('int')
+    # ^^^ explanation: if you write in C: "char x[5];", then
+    # "sizeof(x)" will evaluate to 5.  The behavior above is
+    # a generalization of that to "struct foo_s[len(a)=5] x;"
+    # if you could do that in C.
     assert s.a[3] == 0
     s = ffi.new("struct foo_s *", [424242, [-40, -30, -20, -10]])
-    assert ffi.sizeof(s[0]) == 1 * ffi.sizeof('int')
+    assert ffi.sizeof(s[0]) == 5 * ffi.sizeof('int')
     assert s.a[3] == -10
     s = ffi.new("struct foo_s *")
     assert ffi.sizeof(s[0]) == 1 * ffi.sizeof('int')
@@ -610,10 +616,10 @@
     ffi.verify("struct foo_s { int x, y; int a[]; };")
     assert ffi.sizeof('struct foo_s') == 2 * ffi.sizeof('int')
     s = ffi.new("struct foo_s *", [424242, 4])
-    assert ffi.sizeof(s[0]) == 2 * ffi.sizeof('int')
+    assert ffi.sizeof(s[0]) == 6 * ffi.sizeof('int')
     assert s.a[3] == 0
     s = ffi.new("struct foo_s *", [424242, [-40, -30, -20, -10]])
-    assert ffi.sizeof(s[0]) == 2 * ffi.sizeof('int')
+    assert ffi.sizeof(s[0]) == 6 * ffi.sizeof('int')
     assert s.a[3] == -10
     s = ffi.new("struct foo_s *")
     assert ffi.sizeof(s[0]) == 2 * ffi.sizeof('int')
diff --git a/pypy/module/test_lib_pypy/cffi_tests/cffi1/test_new_ffi_1.py \
                b/pypy/module/test_lib_pypy/cffi_tests/cffi1/test_new_ffi_1.py
--- a/pypy/module/test_lib_pypy/cffi_tests/cffi1/test_new_ffi_1.py
+++ b/pypy/module/test_lib_pypy/cffi_tests/cffi1/test_new_ffi_1.py
@@ -1634,10 +1634,19 @@
         # struct array_no_length { int x; int a[]; };
         p = ffi.new("struct array_no_length *", [100, [200, 300, 400]])
         assert p.x == 100
-        assert ffi.typeof(p.a) is ffi.typeof("int *")   # no length available
+        assert ffi.typeof(p.a) is ffi.typeof("int[]")   # length available
         assert p.a[0] == 200
         assert p.a[1] == 300
         assert p.a[2] == 400
+        assert len(p.a) == 3
+        assert list(p.a) == [200, 300, 400]
+        q = ffi.cast("struct array_no_length *", p)
+        assert ffi.typeof(q.a) is ffi.typeof("int *")   # no length available
+        assert q.a[0] == 200
+        assert q.a[1] == 300
+        assert q.a[2] == 400
+        py.test.raises(TypeError, len, q.a)
+        py.test.raises(TypeError, list, q.a)
 
     def test_from_buffer(self):
         import array
diff --git a/pypy/module/test_lib_pypy/cffi_tests/cffi1/test_recompiler.py \
                b/pypy/module/test_lib_pypy/cffi_tests/cffi1/test_recompiler.py
--- a/pypy/module/test_lib_pypy/cffi_tests/cffi1/test_recompiler.py
+++ b/pypy/module/test_lib_pypy/cffi_tests/cffi1/test_recompiler.py
@@ -400,11 +400,14 @@
         pass    # ok, fail during compilation already (e.g. C++)
     else:
         assert ffi.sizeof("struct foo_s") == 24  # found by the actual C code
-        p = ffi.new("struct foo_s *")
-        # lazily build the fields and boom:
-        e = py.test.raises(ffi.error, "p.a")
-        assert str(e.value).startswith("struct foo_s: wrong size for field 'a' "
-                                       "(cdef says 20, but C compiler says 24)")
+        try:
+            # lazily build the fields and boom:
+            p = ffi.new("struct foo_s *")
+            p.a
+            assert False, "should have raised"
+        except ffi.error as e:
+            assert str(e).startswith("struct foo_s: wrong size for field 'a' "
+                                     "(cdef says 20, but C compiler says 24)")
 
 def test_open_array_in_struct():
     ffi = FFI()
@@ -412,8 +415,10 @@
     verify(ffi, 'test_open_array_in_struct',
            "struct foo_s { int b; int a[]; };")
     assert ffi.sizeof("struct foo_s") == 4
-    p = ffi.new("struct foo_s *", [5, [10, 20, 30]])
+    p = ffi.new("struct foo_s *", [5, [10, 20, 30, 40]])
     assert p.a[2] == 30
+    assert ffi.sizeof(p) == ffi.sizeof("void *")
+    assert ffi.sizeof(p[0]) == 5 * ffi.sizeof("int")
 
 def test_math_sin_type():
     ffi = FFI()
@@ -999,6 +1004,7 @@
                  "struct foo_s { int x; int a[5][8]; int y; };")
     assert ffi.sizeof('struct foo_s') == 42 * ffi.sizeof('int')
     s = ffi.new("struct foo_s *")
+    assert ffi.typeof(s.a) == ffi.typeof("int[5][8]")
     assert ffi.sizeof(s.a) == 40 * ffi.sizeof('int')
     assert s.a[4][7] == 0
     py.test.raises(IndexError, 's.a[4][8]')
@@ -1013,7 +1019,7 @@
                  "struct foo_s { int x; int a[5][7]; int y; };")
     assert ffi.sizeof('struct foo_s') == 37 * ffi.sizeof('int')
     s = ffi.new("struct foo_s *")
-    assert ffi.typeof(s.a) == ffi.typeof("int(*)[7]")
+    assert ffi.typeof(s.a) == ffi.typeof("int[][7]")
     assert s.a[4][6] == 0
     py.test.raises(IndexError, 's.a[4][7]')
     assert ffi.typeof(s.a[0]) == ffi.typeof("int[7]")
diff --git a/pypy/module/test_lib_pypy/cffi_tests/cffi1/test_verify1.py \
                b/pypy/module/test_lib_pypy/cffi_tests/cffi1/test_verify1.py
--- a/pypy/module/test_lib_pypy/cffi_tests/cffi1/test_verify1.py
+++ b/pypy/module/test_lib_pypy/cffi_tests/cffi1/test_verify1.py
@@ -547,7 +547,8 @@
                      "int bar(struct foo_s *f) { return f->a[14]; }\n")
     assert ffi.sizeof('struct foo_s') == 19 * ffi.sizeof('int')
     s = ffi.new("struct foo_s *")
-    assert ffi.typeof(s.a) is ffi.typeof('int *')   # because no length
+    assert ffi.typeof(s.a) is ffi.typeof('int[]')   # implicit max length
+    assert len(s.a) == 18  # max length, computed from the size and start offset
     s.a[14] = 4242
     assert lib.bar(s) == 4242
     # with no declared length, out-of-bound accesses are not detected
@@ -577,10 +578,15 @@
     ffi.verify("struct foo_s { int x; int a[]; };")
     assert ffi.sizeof('struct foo_s') == 1 * ffi.sizeof('int')
     s = ffi.new("struct foo_s *", [424242, 4])
-    assert ffi.sizeof(s[0]) == 1 * ffi.sizeof('int')   # the same in C
+    assert ffi.sizeof(ffi.typeof(s[0])) == 1 * ffi.sizeof('int')
+    assert ffi.sizeof(s[0]) == 5 * ffi.sizeof('int')
+    # ^^^ explanation: if you write in C: "char x[5];", then
+    # "sizeof(x)" will evaluate to 5.  The behavior above is
+    # a generalization of that to "struct foo_s[len(a)=5] x;"
+    # if you could do that in C.
     assert s.a[3] == 0
     s = ffi.new("struct foo_s *", [424242, [-40, -30, -20, -10]])
-    assert ffi.sizeof(s[0]) == 1 * ffi.sizeof('int')
+    assert ffi.sizeof(s[0]) == 5 * ffi.sizeof('int')
     assert s.a[3] == -10
     s = ffi.new("struct foo_s *")
     assert ffi.sizeof(s[0]) == 1 * ffi.sizeof('int')
@@ -595,10 +601,10 @@
     ffi.verify("struct foo_s { int x, y; int a[]; };")
     assert ffi.sizeof('struct foo_s') == 2 * ffi.sizeof('int')
     s = ffi.new("struct foo_s *", [424242, 4])
-    assert ffi.sizeof(s[0]) == 2 * ffi.sizeof('int')
+    assert ffi.sizeof(s[0]) == 6 * ffi.sizeof('int')
     assert s.a[3] == 0
     s = ffi.new("struct foo_s *", [424242, [-40, -30, -20, -10]])
-    assert ffi.sizeof(s[0]) == 2 * ffi.sizeof('int')
+    assert ffi.sizeof(s[0]) == 6 * ffi.sizeof('int')
     assert s.a[3] == -10
     s = ffi.new("struct foo_s *")
     assert ffi.sizeof(s[0]) == 2 * ffi.sizeof('int')
diff --git a/rpython/jit/backend/test/runner_test.py \
                b/rpython/jit/backend/test/runner_test.py
--- a/rpython/jit/backend/test/runner_test.py
+++ b/rpython/jit/backend/test/runner_test.py
@@ -2662,7 +2662,8 @@
         """, namespace=locals())
         looptoken = JitCellToken()
         self.cpu.compile_loop(loop.inputargs, loop.operations, looptoken)
-        deadframe = self.cpu.execute_token(looptoken, 20.25)
+        x = longlong.getfloatstorage(20.25)
+        deadframe = self.cpu.execute_token(looptoken, x)
         fail = self.cpu.get_latest_descr(deadframe)
         assert fail.identifier == 0
         frame = self.cpu.get_ref_value(deadframe, 0)
@@ -2671,7 +2672,8 @@
         if not getattr(self.cpu, 'is_llgraph', False):
             assert frame == deadframe
         deadframe2 = self.cpu.force(frame)
-        assert self.cpu.get_float_value(deadframe2, 0) == 22.75
+        x = self.cpu.get_float_value(deadframe2, 0)
+        assert longlong.getrealfloat(x) == 22.75
 
     def test_call_to_c_function(self):
         from rpython.rlib.libffi import CDLL, types, ArgChain, FUNCFLAG_CDECL
_______________________________________________
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic