[pypy-commit] pypy multiphase: hg merge py3.5

rlamy pypy.commits at gmail.com
Fri Aug 11 12:06:47 EDT 2017


Author: Ronan Lamy <ronan.lamy at gmail.com>
Branch: multiphase
Changeset: r92125:dce989c3370d
Date: 2017-08-11 17:47 +0200
http://bitbucket.org/pypy/pypy/changeset/dce989c3370d/

Log:	hg merge py3.5

diff --git a/lib-python/2.7/distutils/sysconfig_pypy.py b/lib-python/2.7/distutils/sysconfig_pypy.py
--- a/lib-python/2.7/distutils/sysconfig_pypy.py
+++ b/lib-python/2.7/distutils/sysconfig_pypy.py
@@ -218,6 +218,10 @@
 
         compiler.shared_lib_extension = so_ext
 
+def get_config_h_filename():
+    """Returns the path of pyconfig.h."""
+    inc_dir = get_python_inc(plat_specific=1)
+    return os.path.join(inc_dir, 'pyconfig.h')
 
 from sysconfig_cpython import (
     parse_makefile, _variable_rx, expand_makefile_vars)
diff --git a/lib_pypy/_ctypes/structure.py b/lib_pypy/_ctypes/structure.py
--- a/lib_pypy/_ctypes/structure.py
+++ b/lib_pypy/_ctypes/structure.py
@@ -40,6 +40,22 @@
         else:
             rawfields.append((f[0], f[1]._ffishape_))
 
+    # hack for duplicate field names
+    already_seen = set()
+    names1 = names
+    names = []
+    for f in names1:
+        if f not in already_seen:
+            names.append(f)
+            already_seen.add(f)
+    already_seen = set()
+    for i in reversed(range(len(rawfields))):
+        if rawfields[i][0] in already_seen:
+            rawfields[i] = (('$DUP%d$%s' % (i, rawfields[i][0]),)
+                            + rawfields[i][1:])
+        already_seen.add(rawfields[i][0])
+    # /hack
+
     _set_shape(self, rawfields, self._is_union)
 
     fields = {}
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
@@ -62,7 +62,7 @@
 throwing away information about them less eagerly.
 
 
-.. branch: getarrayitem-into-bridges:
+.. branch: getarrayitem-into-bridges
 
 More information is retained into a bridge: knowledge about the content of
 arrays (at fixed indices) is stored in guards (and thus available at the
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
@@ -1645,6 +1645,7 @@
         assert cpyext_glob_tid_ptr[0] == 0
         cpyext_glob_tid_ptr[0] = tid
 
+        preexist_error = PyErr_Occurred(space) is not None
         try:
             # Call the function
             result = call_external_function(func, *boxed_args)
@@ -1669,15 +1670,15 @@
 
             # Check for exception consistency
             has_error = PyErr_Occurred(space) is not None
-            if has_error and has_result:
-                raise oefmt(space.w_SystemError,
-                            "An exception was set, but function returned a "
-                            "value")
-            elif not expect_null and not has_error and not has_result:
-                raise oefmt(space.w_SystemError,
-                            "Function returned a NULL result without setting "
-                            "an exception")
-
+            if not preexist_error:
+                if has_error and has_result:
+                    raise oefmt(space.w_SystemError,
+                                "An exception was set, but function returned a "
+                                "value")
+                elif not expect_null and not has_error and not has_result:
+                    raise oefmt(space.w_SystemError,
+                                "Function returned a NULL result without setting "
+                                "an exception")
             if has_error:
                 state = space.fromcache(State)
                 state.check_and_raise_exception()
diff --git a/pypy/module/cpyext/methodobject.py b/pypy/module/cpyext/methodobject.py
--- a/pypy/module/cpyext/methodobject.py
+++ b/pypy/module/cpyext/methodobject.py
@@ -203,6 +203,10 @@
 def cmethod_descr_call(space, w_self, __args__):
     self = space.interp_w(W_PyCFunctionObject, w_self)
     args_w, kw_w = __args__.unpack()
+    if len(args_w) < 1:
+        raise oefmt(space.w_TypeError,
+            "descriptor '%s' of '%s' object needs an argument",
+            self.name, self.w_objclass.getname(space))
     w_instance = args_w[0] # XXX typecheck missing
     w_args = space.newtuple(args_w[1:])
     w_kw = space.newdict()
diff --git a/pypy/module/cpyext/object.py b/pypy/module/cpyext/object.py
--- a/pypy/module/cpyext/object.py
+++ b/pypy/module/cpyext/object.py
@@ -311,7 +311,7 @@
     PyErr_BadInternalCall(space)
 
 @cpython_api([PyObject, PyObject, rffi.INT_real], rffi.INT_real, error=-1)
-def PyObject_RichCompareBool(space, ref1, ref2, opid):
+def PyObject_RichCompareBool(space, ref1, ref2, opid_int):
     """Compare the values of o1 and o2 using the operation specified by opid,
     which must be one of Py_LT, Py_LE, Py_EQ,
     Py_NE, Py_GT, or Py_GE, corresponding to <,
@@ -319,7 +319,15 @@
     0 if the result is false, 1 otherwise. This is the equivalent of the
     Python expression o1 op o2, where op is the operator corresponding to
     opid."""
-    w_res = PyObject_RichCompare(space, ref1, ref2, opid)
+    # Quick result when objects are the same.
+    # Guarantees that identity implies equality.
+    if ref1 is ref2:
+        opid = rffi.cast(lltype.Signed, opid_int)
+        if opid == Py_EQ:
+            return 1
+        if opid == Py_NE:
+            return 0 
+    w_res = PyObject_RichCompare(space, ref1, ref2, opid_int)
     return int(space.is_true(w_res))
 
 @cpython_api([PyObject], PyObject, result_is_ll=True)
diff --git a/pypy/module/cpyext/test/test_arraymodule.py b/pypy/module/cpyext/test/test_arraymodule.py
--- a/pypy/module/cpyext/test/test_arraymodule.py
+++ b/pypy/module/cpyext/test/test_arraymodule.py
@@ -12,6 +12,9 @@
         assert arr.itemsize == 4
         assert arr[2] == 3
         assert len(arr.buffer_info()) == 2
+        exc = raises(TypeError, module.array.append)
+        errstr = str(exc.value)
+        assert errstr.startswith("descriptor 'append' of")
         arr.append(4)
         assert arr.tolist() == [1, 2, 3, 4]
         assert len(arr) == 4
diff --git a/pypy/module/cpyext/test/test_object.py b/pypy/module/cpyext/test/test_object.py
--- a/pypy/module/cpyext/test/test_object.py
+++ b/pypy/module/cpyext/test/test_object.py
@@ -8,7 +8,7 @@
 from pypy.module.cpyext.object import (
     PyObject_IsTrue, PyObject_Not, PyObject_GetAttrString,
     PyObject_DelAttrString, PyObject_GetAttr, PyObject_DelAttr,
-    PyObject_GetItem, PyObject_RichCompareBool,
+    PyObject_GetItem, 
     PyObject_IsInstance, PyObject_IsSubclass, PyObject_AsFileDescriptor,
     PyObject_Hash)
 
@@ -135,7 +135,18 @@
 
         w_i = space.wrap(1)
         with raises_w(space, SystemError):
-            PyObject_RichCompareBool(space, w_i, w_i, 123456)
+            api.PyObject_RichCompareBool(w_i, w_i, 123456)
+
+    def test_RichCompareNanlike(self, space,api):
+        w_obj = space.appexec([], """():
+            class Nanlike(object):
+                def __eq__(self, other):
+                    raise RuntimeError('unreachable')
+            return Nanlike()""")
+        res = api.PyObject_RichCompareBool(w_obj, w_obj, Py_EQ)
+        assert res == 1
+        res = api.PyObject_RichCompareBool(w_obj, w_obj, Py_NE)
+        assert res == 0
 
     def test_IsInstance(self, space, api):
         assert api.PyObject_IsInstance(space.wrap(1), space.w_int) == 1
diff --git a/pypy/module/cpyext/unicodeobject.py b/pypy/module/cpyext/unicodeobject.py
--- a/pypy/module/cpyext/unicodeobject.py
+++ b/pypy/module/cpyext/unicodeobject.py
@@ -730,7 +730,7 @@
 if sys.platform == 'win32':
     make_conversion_functions('MBCS', 'mbcs')
 
- at cpython_api([rffi.CCHARP, Py_ssize_t, CONST_STRING, rffi.INTP], PyObject)
+ at cpython_api([CONST_STRING, Py_ssize_t, CONST_STRING, rffi.INTP], PyObject)
 def PyUnicode_DecodeUTF16(space, s, size, llerrors, pbyteorder):
     """Decode length bytes from a UTF-16 encoded buffer string and return the
     corresponding Unicode object.  errors (if non-NULL) defines the error
@@ -784,7 +784,7 @@
 
     return space.newunicode(result)
 
- at cpython_api([rffi.CCHARP, Py_ssize_t, rffi.CCHARP, rffi.INTP], PyObject)
+ at cpython_api([CONST_STRING, Py_ssize_t, CONST_STRING, rffi.INTP], PyObject)
 def PyUnicode_DecodeUTF32(space, s, size, llerrors, pbyteorder):
     """Decode length bytes from a UTF-32 encoded buffer string and
     return the corresponding Unicode object.  errors (if non-NULL)
@@ -840,7 +840,7 @@
 
     return space.newunicode(result)
 
- at cpython_api([rffi.CWCHARP, Py_ssize_t, rffi.CCHARP, rffi.CCHARP],
+ at cpython_api([rffi.CWCHARP, Py_ssize_t, rffi.CCHARP, CONST_STRING],
              rffi.INT_real, error=-1)
 def PyUnicode_EncodeDecimal(space, s, length, output, llerrors):
     """Takes a Unicode string holding a decimal value and writes it
diff --git a/pypy/module/sys/vm.py b/pypy/module/sys/vm.py
--- a/pypy/module/sys/vm.py
+++ b/pypy/module/sys/vm.py
@@ -279,7 +279,13 @@
     from rpython.rtyper.lltypesystem import lltype, rffi
     return space.newint(rffi.cast(lltype.Signed, handle))
 
-getsizeof_missing = """sys.getsizeof() is not implemented on PyPy.
+getsizeof_missing = """getsizeof(...)
+    getsizeof(object, default) -> int
+    
+    Return the size of object in bytes.
+
+sys.getsizeof(object, default) will always return default on PyPy, and
+raise a TypeError if default is not provided.
 
 First note that the CPython documentation says that this function may
 raise a TypeError, so if you are seeing it, it means that the program
diff --git a/pypy/module/test_lib_pypy/ctypes_tests/test_structures.py b/pypy/module/test_lib_pypy/ctypes_tests/test_structures.py
--- a/pypy/module/test_lib_pypy/ctypes_tests/test_structures.py
+++ b/pypy/module/test_lib_pypy/ctypes_tests/test_structures.py
@@ -556,3 +556,13 @@
 
         x = X()
         assert x.x == 0
+
+    def test_duplicate_names(self):
+        class S(Structure):
+            _fields_ = [('a', c_int),
+                        ('b', c_int),
+                        ('a', c_byte)]
+        s = S(260, -123)
+        assert sizeof(s) == 3 * sizeof(c_int)
+        assert s.a == 4     # 256 + 4
+        assert s.b == -123
diff --git a/rpython/annotator/binaryop.py b/rpython/annotator/binaryop.py
--- a/rpython/annotator/binaryop.py
+++ b/rpython/annotator/binaryop.py
@@ -529,6 +529,8 @@
         assert dic1.__class__ == dic2.__class__
         return dic1.__class__(dic1.dictdef.union(dic2.dictdef))
 
+    def ne((dic1, dic2)):
+        raise AnnotatorError("dict != dict not implemented")
 
 def _dict_can_only_throw_keyerror(s_dct, *ignore):
     if s_dct.dictdef.dictkey.custom_eq_hash:
diff --git a/rpython/jit/metainterp/optimizeopt/bridgeopt.py b/rpython/jit/metainterp/optimizeopt/bridgeopt.py
--- a/rpython/jit/metainterp/optimizeopt/bridgeopt.py
+++ b/rpython/jit/metainterp/optimizeopt/bridgeopt.py
@@ -84,7 +84,6 @@
 
     # heap knowledge: we store triples of known heap fields in non-virtual
     # structs
-    # XXX could be extended to arrays
     if optimizer.optheap:
         triples_struct, triples_array = optimizer.optheap.serialize_optheap(available_boxes)
         # can only encode descrs that have a known index into
diff --git a/rpython/tool/version.py b/rpython/tool/version.py
--- a/rpython/tool/version.py
+++ b/rpython/tool/version.py
@@ -59,15 +59,15 @@
     p = Popen([str(hgexe), 'id', '-i', root],
               stdout=PIPE, stderr=PIPE, env=env)
     hgid = p.stdout.read().strip()
-    maywarn(p.stderr.read())
     if p.wait() != 0:
+        maywarn(p.stderr.read())
         hgid = '?'
 
     p = Popen([str(hgexe), 'id', '-t', root],
               stdout=PIPE, stderr=PIPE, env=env)
     hgtags = [t for t in p.stdout.read().strip().split() if t != 'tip']
-    maywarn(p.stderr.read())
     if p.wait() != 0:
+        maywarn(p.stderr.read())
         hgtags = ['?']
 
     if hgtags:
@@ -77,7 +77,8 @@
         p = Popen([str(hgexe), 'id', '-b', root],
                   stdout=PIPE, stderr=PIPE, env=env)
         hgbranch = p.stdout.read().strip()
-        maywarn(p.stderr.read())
+        if p.wait() != 0:
+            maywarn(p.stderr.read())
 
         return hgbranch, hgid
 
diff --git a/rpython/translator/c/src/precommondefs.h b/rpython/translator/c/src/precommondefs.h
--- a/rpython/translator/c/src/precommondefs.h
+++ b/rpython/translator/c/src/precommondefs.h
@@ -63,9 +63,11 @@
 #ifdef __GNUC__
 #  define RPY_EXPORTED extern __attribute__((visibility("default")))
 #  define _RPY_HIDDEN  __attribute__((visibility("hidden")))
+#  define RPY_UNUSED __attribute__ ((__unused__))
 #else
 #  define RPY_EXPORTED extern __declspec(dllexport)
 #  define _RPY_HIDDEN  /* nothing */
+#  define RPY_UNUSED   /*nothing */
 #endif
 #ifndef RPY_EXTERN
 #  define RPY_EXTERN   extern _RPY_HIDDEN
diff --git a/rpython/translator/c/src/signals.c b/rpython/translator/c/src/signals.c
--- a/rpython/translator/c/src/signals.c
+++ b/rpython/translator/c/src/signals.c
@@ -102,9 +102,10 @@
 static void write_str(int fd, const char *p)
 {
     int i = 0;
+    int res RPY_UNUSED;
     while (p[i] != '\x00')
         i++;
-    (void)write(fd, p, i);
+    res = write(fd, p, i);
 }
 
 static void signal_setflag_handler(int signum)


More information about the pypy-commit mailing list