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

rlamy pypy.commits at gmail.com
Tue Sep 25 14:18:58 EDT 2018


Author: Ronan Lamy <ronan.lamy at gmail.com>
Branch: py3.6
Changeset: r95167:6ffaea666f35
Date: 2018-09-25 19:18 +0100
http://bitbucket.org/pypy/pypy/changeset/6ffaea666f35/

Log:	hg merge py3.5

diff --git a/README.rst b/README.rst
--- a/README.rst
+++ b/README.rst
@@ -4,7 +4,7 @@
 
 Welcome to PyPy!
 
-PyPy is an interperter that implements the Python programming language, based
+PyPy is an interpreter that implements the Python programming language, based
 on the RPython compiler framework for dynamic language implementations.
 
 The home page for the interpreter is:
@@ -15,29 +15,29 @@
 
     http://doc.pypy.org/
 
-More documentation about the RPython framework can be found here
+More documentation about the RPython framework can be found here:
 
-    http://rpython.readthedocs.io
+    http://rpython.readthedocs.io/
 
-The source for the documentation is in the pypy/doc directory 
+The source for the documentation is in the pypy/doc directory.
+
 
 Using PyPy instead of CPython
-=============================
+-----------------------------
 
-Please read the information at http://pypy.org to find the correct way to
+Please read the information at http://pypy.org/ to find the correct way to
 download and use PyPy as an alternative to CPython. 
 
+
 Building
-========
+--------
 
 Building PyPy is not the recommended way to obtain the PyPy alternative python
 interpreter. It is time-consuming and requires significant computing resources.
-More information can be found here
+More information can be found here:
 
     http://doc.pypy.org/en/latest/build.html
 
 Enjoy and send us feedback!
 
     the pypy-dev team <pypy-dev at python.org>
-
-
diff --git a/lib-python/3/test/test_inspect.py b/lib-python/3/test/test_inspect.py
--- a/lib-python/3/test/test_inspect.py
+++ b/lib-python/3/test/test_inspect.py
@@ -61,6 +61,9 @@
 
 git = mod.StupidGit()
 
+class ExampleClassWithSlot(object):
+    __slots__ = 'myslot'
+
 class IsTestBase(unittest.TestCase):
     predicates = set([inspect.isbuiltin, inspect.isclass, inspect.iscode,
                       inspect.isframe, inspect.isfunction, inspect.ismethod,
@@ -141,8 +144,11 @@
             self.istest(inspect.iscoroutinefunction, 'coroutine_function_example')
 
         if hasattr(types, 'MemberDescriptorType'):
-            self.istest(inspect.ismemberdescriptor,
-                        'type(lambda: None).__globals__')
+            # App-level slots are member descriptors on both PyPy and
+            # CPython, but the various built-in attributes are all
+            # getsetdescriptors on PyPy.  So check ismemberdescriptor()
+            # with an app-level slot.
+            self.istest(inspect.ismemberdescriptor, 'ExampleClassWithSlot.myslot')
         else:
             self.assertFalse(inspect.ismemberdescriptor(datetime.timedelta.days))
 
diff --git a/lib_pypy/_ctypes/function.py b/lib_pypy/_ctypes/function.py
--- a/lib_pypy/_ctypes/function.py
+++ b/lib_pypy/_ctypes/function.py
@@ -486,6 +486,8 @@
         return cobj, cobj._to_ffi_param(), type(cobj)
 
     def _convert_args_for_callback(self, argtypes, args):
+        from _ctypes.structure import StructOrUnion
+        #
         assert len(argtypes) == len(args)
         newargs = []
         for argtype, arg in zip(argtypes, args):
@@ -495,6 +497,10 @@
                 param = param._get_buffer_value()
             elif self._is_primitive(argtype):
                 param = param.value
+            elif isinstance(param, StructOrUnion):   # not a *pointer* to struct
+                newparam = StructOrUnion.__new__(type(param))
+                param._copy_to(newparam._buffer.buffer)
+                param = newparam
             newargs.append(param)
         return newargs
 
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
@@ -162,6 +162,17 @@
             module_path = module_name.split('.')
             module_path[-1] += '.py'
             generate_mod(os.path.join(self.build_lib, *module_path))
+        def get_source_files(self):
+            # This is called from 'setup.py sdist' only.  Exclude
+            # the generate .py module in this case.
+            saved_py_modules = self.py_modules
+            try:
+                if saved_py_modules:
+                    self.py_modules = [m for m in saved_py_modules
+                                         if m != module_name]
+                return base_class.get_source_files(self)
+            finally:
+                self.py_modules = saved_py_modules
     dist.cmdclass['build_py'] = build_py_make_mod
 
     # distutils and setuptools have no notion I could find of a
@@ -171,6 +182,7 @@
     # the module.  So we add it here, which gives a few apparently
     # harmless warnings about not finding the file outside the
     # build directory.
+    # Then we need to hack more in get_source_files(); see above.
     if dist.py_modules is None:
         dist.py_modules = []
     dist.py_modules.append(module_name)
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
@@ -37,6 +37,8 @@
 
 Small refactorings in the Python parser.
 
+.. branch: fix-readme-typo
+
 .. branch: py3.6-wordcode
 
 implement new wordcode instruction encoding on the 3.6 branch
diff --git a/pypy/module/__builtin__/functional.py b/pypy/module/__builtin__/functional.py
--- a/pypy/module/__builtin__/functional.py
+++ b/pypy/module/__builtin__/functional.py
@@ -108,101 +108,99 @@
 max_jitdriver = jit.JitDriver(name='max',
         greens=['has_key', 'has_item', 'w_type'], reds='auto')
 
-def make_min_max(unroll):
-    @specialize.arg(2)
-    def min_max_impl(space, args, implementation_of):
-        if implementation_of == "max":
-            compare = space.gt
-            jitdriver = max_jitdriver
+ at specialize.arg(4)
+def min_max_sequence(space, w_sequence, w_key, w_default, implementation_of):
+    if implementation_of == "max":
+        compare = space.gt
+        jitdriver = max_jitdriver
+    else:
+        compare = space.lt
+        jitdriver = min_jitdriver
+    w_iter = space.iter(w_sequence)
+    w_type = space.type(w_iter)
+    has_key = w_key is not None
+    has_item = False
+    w_max_item = w_default
+    w_max_val = None
+    while True:
+        jitdriver.jit_merge_point(has_key=has_key, has_item=has_item,
+                                  w_type=w_type)
+        try:
+            w_item = space.next(w_iter)
+        except OperationError as e:
+            if not e.match(space, space.w_StopIteration):
+                raise
+            break
+        if has_key:
+            w_compare_with = space.call_function(w_key, w_item)
         else:
-            compare = space.lt
-            jitdriver = min_jitdriver
-        any_kwds = bool(args.keywords)
-        args_w = args.arguments_w
-        if len(args_w) > 1:
-            if unroll and len(args_w) == 2 and not any_kwds:
-                # a fast path for the common case, useful for interpreted
-                # mode and to reduce the length of the jit trace
-                w0, w1 = args_w
-                if space.is_true(compare(w1, w0)):
-                    return w1
-                else:
-                    return w0
-            w_sequence = space.newtuple(args_w)
-        elif len(args_w):
-            w_sequence = args_w[0]
+            w_compare_with = w_item
+        if (not has_item or
+                space.is_true(compare(w_compare_with, w_max_val))):
+            has_item = True
+            w_max_item = w_item
+            w_max_val = w_compare_with
+    if w_max_item is None:
+        raise oefmt(space.w_ValueError, "arg is an empty sequence")
+    return w_max_item
+
+ at specialize.arg(3)
+ at jit.look_inside_iff(lambda space, args_w, w_key, implementation_of:
+        jit.loop_unrolling_heuristic(args_w, len(args_w), 3))
+def min_max_multiple_args(space, args_w, w_key, implementation_of):
+    # case of multiple arguments (at least two).  We unroll it if there
+    # are 2 or 3 arguments.
+    if implementation_of == "max":
+        compare = space.gt
+    else:
+        compare = space.lt
+    w_max_item = args_w[0]
+    if w_key is not None:
+        w_max_val = space.call_function(w_key, w_max_item)
+    else:
+        w_max_val = w_max_item
+    for i in range(1, len(args_w)):
+        w_item = args_w[i]
+        if w_key is not None:
+            w_compare_with = space.call_function(w_key, w_item)
         else:
-            raise oefmt(space.w_TypeError,
-                        "%s() expects at least one argument",
-                        implementation_of)
-        w_key = None
-        w_default = None
-        if any_kwds:
-            kwds = args.keywords
-            for n in range(len(kwds)):
-                if kwds[n] == "key":
-                    w_key = args.keywords_w[n]
-                elif kwds[n] == "default":
-                    w_default = args.keywords_w[n]
-                else:
-                    raise oefmt(space.w_TypeError,
-                                "%s() got unexpected keyword argument",
-                                implementation_of)
+            w_compare_with = w_item
+        if space.is_true(compare(w_compare_with, w_max_val)):
+            w_max_item = w_item
+            w_max_val = w_compare_with
+    return w_max_item
 
-        if w_default is not None and len(args_w) > 1:
-            raise oefmt(space.w_TypeError,
-                "Cannot specify a default for %s() with multiple positional arguments",
-                implementation_of)
-
-        w_iter = space.iter(w_sequence)
-        w_type = space.type(w_iter)
-        has_key = w_key is not None
-        has_item = False
-        w_max_item = None
-        w_max_val = None
-        while True:
-            if not unroll:
-                jitdriver.jit_merge_point(has_key=has_key, has_item=has_item, w_type=w_type)
-            try:
-                w_item = space.next(w_iter)
-            except OperationError as e:
-                if not e.match(space, space.w_StopIteration):
-                    raise
-                break
-            if has_key:
-                w_compare_with = space.call_function(w_key, w_item)
-            else:
-                w_compare_with = w_item
-            if not has_item or \
-                    space.is_true(compare(w_compare_with, w_max_val)):
-                has_item = True
-                w_max_item = w_item
-                w_max_val = w_compare_with
-        if w_max_item is None:
-            if w_default is not None:
-                w_max_item = w_default
-            else:
-                raise oefmt(space.w_ValueError, "arg is an empty sequence")
-        return w_max_item
-    if unroll:
-        min_max_impl = jit.unroll_safe(min_max_impl)
-    return min_max_impl
-
-min_max_unroll = make_min_max(True)
-min_max_normal = make_min_max(False)
-
+ at jit.unroll_safe     # the loop over kwds
 @specialize.arg(2)
 def min_max(space, args, implementation_of):
-    # the 'normal' version includes a JIT merge point, which will make a
-    # new loop (from the interpreter or from another JIT loop).  If we
-    # give exactly two arguments to the call to max(), or a JIT virtual
-    # list of arguments, then we pick the 'unroll' version with no JIT
-    # merge point.
-    if jit.isvirtual(args.arguments_w) or len(args.arguments_w) == 2:
-        return min_max_unroll(space, args, implementation_of)
+    w_key = None
+    w_default = None
+    if bool(args.keywords):
+        kwds = args.keywords
+        for n in range(len(kwds)):
+            if kwds[n] == "key":
+                w_key = args.keywords_w[n]
+            elif kwds[n] == "default":
+                w_default = args.keywords_w[n]
+            else:
+                raise oefmt(space.w_TypeError,
+                            "%s() got unexpected keyword argument",
+                            implementation_of)
+    #
+    args_w = args.arguments_w
+    if len(args_w) > 1:
+        if w_default is not None:
+            raise oefmt(space.w_TypeError,
+                "Cannot specify a default for %s() with multiple "
+                "positional arguments", implementation_of)
+        return min_max_multiple_args(space, args_w, w_key, implementation_of)
+    elif len(args_w):
+        return min_max_sequence(space, args_w[0], w_key, w_default,
+                                implementation_of)
     else:
-        return min_max_normal(space, args, implementation_of)
-min_max._always_inline = True
+        raise oefmt(space.w_TypeError,
+                    "%s() expects at least one argument",
+                    implementation_of)
 
 def max(space, __args__):
     """max(iterable[, key=func]) -> value
diff --git a/pypy/module/__builtin__/test/test_functional.py b/pypy/module/__builtin__/test/test_functional.py
--- a/pypy/module/__builtin__/test/test_functional.py
+++ b/pypy/module/__builtin__/test/test_functional.py
@@ -654,6 +654,10 @@
         raises(TypeError, max, 1, default=0)
         raises(TypeError, max, default=1)
 
+    def test_max_list_and_key(self):
+        assert max(["100", "50", "30", "-200"], key=int) == "100"
+        assert max("100", "50", "30", "-200", key=int) == "100"
+
 
 try:
     from hypothesis import given, strategies, example
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
@@ -317,9 +317,7 @@
             if isinstance(self.ctitem, ctypeprim.W_CTypePrimitiveBool):
                 self._must_be_string_of_zero_or_one(value)
             keepalives[i] = value
-            buf, buf_flag = rffi.get_nonmovingbuffer_final_null(value)
-            rffi.cast(rffi.CCHARPP, cdata)[0] = buf
-            return ord(buf_flag)    # 4, 5 or 6
+            return misc.write_string_as_charp(cdata, value)
         #
         if (space.isinstance_w(w_init, space.w_list) or
             space.isinstance_w(w_init, space.w_tuple)):
diff --git a/pypy/module/_cffi_backend/misc.py b/pypy/module/_cffi_backend/misc.py
--- a/pypy/module/_cffi_backend/misc.py
+++ b/pypy/module/_cffi_backend/misc.py
@@ -3,7 +3,7 @@
 from pypy.interpreter.error import OperationError, oefmt
 
 from rpython.rlib import jit
-from rpython.rlib.objectmodel import specialize
+from rpython.rlib.objectmodel import specialize, we_are_translated
 from rpython.rlib.rarithmetic import r_uint, r_ulonglong
 from rpython.rlib.unroll import unrolling_iterable
 from rpython.rtyper.lltypesystem import lltype, llmemory, rffi
@@ -102,6 +102,12 @@
 def write_raw_longdouble_data(target, source):
     rffi.cast(rffi.LONGDOUBLEP, target)[0] = source
 
+ at jit.dont_look_inside    # lets get_nonmovingbuffer_final_null be inlined
+def write_string_as_charp(target, string):
+    buf, buf_flag = rffi.get_nonmovingbuffer_final_null(string)
+    rffi.cast(rffi.CCHARPP, target)[0] = buf
+    return ord(buf_flag)    # 4, 5 or 6
+
 # ____________________________________________________________
 
 sprintf_longdouble = rffi.llexternal(
@@ -129,21 +135,14 @@
     # This version accepts a Python int too, and does convertions from
     # other types of objects.  It refuses floats.
     try:
-        value = space.int_w(w_ob)
+        return space.int_w(w_ob, allow_conversion=False)
     except OperationError as e:
         if not (e.match(space, space.w_OverflowError) or
                 e.match(space, space.w_TypeError)):
             raise
-    else:
-        return value
-    try:
-        bigint = space.bigint_w(w_ob, allow_conversion=False)
-    except OperationError as e:
-        if not e.match(space, space.w_TypeError):
-            raise
         if _is_a_float(space, w_ob):
             raise
-        bigint = space.bigint_w(space.int(w_ob), allow_conversion=False)
+    bigint = space.bigint_w(w_ob, allow_conversion=True)
     try:
         return bigint.tolonglong()
     except OverflowError:
@@ -151,20 +150,15 @@
 
 def as_long(space, w_ob):
     # Same as as_long_long(), but returning an int instead.
-    if space.is_w(space.type(w_ob), space.w_int):   # shortcut
-        return space.int_w(w_ob)
     try:
-        bigint = space.bigint_w(w_ob, allow_conversion=False)
+        return space.int_w(w_ob, allow_conversion=False)
     except OperationError as e:
-        if not e.match(space, space.w_TypeError):
+        if not (e.match(space, space.w_OverflowError) or
+                e.match(space, space.w_TypeError)):
             raise
         if _is_a_float(space, w_ob):
             raise
-        bigint = space.bigint_w(space.int(w_ob), allow_conversion=False)
-    try:
-        return bigint.toint()
-    except OverflowError:
-        raise OperationError(space.w_OverflowError, space.newtext(ovf_msg))
+    return space.int_w(w_ob, allow_conversion=True)
 
 def as_unsigned_long_long(space, w_ob, strict):
     # (possibly) convert and cast a Python object to an unsigned long long.
@@ -172,23 +166,19 @@
     # objects.  If 'strict', complains with OverflowError; if 'not strict',
     # mask the result and round floats.
     try:
-        value = space.int_w(w_ob)
+        value = space.int_w(w_ob, allow_conversion=False)
     except OperationError as e:
         if not (e.match(space, space.w_OverflowError) or
                 e.match(space, space.w_TypeError)):
             raise
+        if strict and _is_a_float(space, w_ob):
+            raise
     else:
         if strict and value < 0:
             raise OperationError(space.w_OverflowError, space.newtext(neg_msg))
         return r_ulonglong(value)
-    try:
-        bigint = space.bigint_w(w_ob, allow_conversion=False)
-    except OperationError as e:
-        if not e.match(space, space.w_TypeError):
-            raise
-        if strict and _is_a_float(space, w_ob):
-            raise
-        bigint = space.bigint_w(space.int(w_ob), allow_conversion=False)
+    # note that if not 'strict', then space.int() will round down floats
+    bigint = space.bigint_w(space.int(w_ob), allow_conversion=False)
     if strict:
         try:
             return bigint.toulonglong()
@@ -202,13 +192,19 @@
 def as_unsigned_long(space, w_ob, strict):
     # same as as_unsigned_long_long(), but returning just an Unsigned
     try:
-        bigint = space.bigint_w(w_ob, allow_conversion=False)
+        value = space.int_w(w_ob, allow_conversion=False)
     except OperationError as e:
-        if not e.match(space, space.w_TypeError):
+        if not (e.match(space, space.w_OverflowError) or
+                e.match(space, space.w_TypeError)):
             raise
         if strict and _is_a_float(space, w_ob):
             raise
-        bigint = space.bigint_w(space.int(w_ob), allow_conversion=False)
+    else:
+        if strict and value < 0:
+            raise OperationError(space.w_OverflowError, space.newtext(neg_msg))
+        return r_uint(value)
+    # note that if not 'strict', then space.int() will round down floats
+    bigint = space.bigint_w(space.int(w_ob), allow_conversion=False)
     if strict:
         try:
             return bigint.touint()
@@ -241,7 +237,12 @@
 
 def _standard_object_as_bool(space, w_ob):
     if space.isinstance_w(w_ob, space.w_int):
-        return space.bigint_w(w_ob).tobool()
+        try:
+            return space.int_w(w_ob) != 0
+        except OperationError as e:
+            if not e.match(space, space.w_OverflowError):
+                raise
+            return space.bigint_w(w_ob).tobool()
     if space.isinstance_w(w_ob, space.w_float):
         return space.float_w(w_ob) != 0.0
     raise _NotStandardObject
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
@@ -334,8 +334,18 @@
         max = (1 << (8*size-1)) - 1
         assert newp(pp, min)[0] == min
         assert newp(pp, max)[0] == max
+        py.test.raises(OverflowError, newp, pp, min - 2 ** 32)
+        py.test.raises(OverflowError, newp, pp, min - 2 ** 64)
+        py.test.raises(OverflowError, newp, pp, max + 2 ** 32)
+        py.test.raises(OverflowError, newp, pp, max + 2 ** 64)
         py.test.raises(OverflowError, newp, pp, min - 1)
         py.test.raises(OverflowError, newp, pp, max + 1)
+        py.test.raises(OverflowError, newp, pp, min - 1 - 2 ** 32)
+        py.test.raises(OverflowError, newp, pp, min - 1 - 2 ** 64)
+        py.test.raises(OverflowError, newp, pp, max + 1)
+        py.test.raises(OverflowError, newp, pp, max + 1 + 2 ** 32)
+        py.test.raises(OverflowError, newp, pp, max + 1 + 2 ** 64)
+        py.test.raises(TypeError, newp, pp, 1.0)
     for name in ['char', 'short', 'int', 'long', 'long long']:
         p = new_primitive_type('unsigned ' + name)
         pp = new_pointer_type(p)
@@ -3947,6 +3957,7 @@
     z3 = cast(BVoidP, 0)
     z4 = cast(BUCharP, 0)
     with warnings.catch_warnings(record=True) as w:
+        warnings.simplefilter("always")
         newp(new_pointer_type(BIntP), z1)    # warn
         assert len(w) == 1
         newp(new_pointer_type(BVoidP), z1)   # fine
diff --git a/pypy/module/pypyjit/test_pypy_c/test_min_max.py b/pypy/module/pypyjit/test_pypy_c/test_min_max.py
--- a/pypy/module/pypyjit/test_pypy_c/test_min_max.py
+++ b/pypy/module/pypyjit/test_pypy_c/test_min_max.py
@@ -30,37 +30,42 @@
             sa = 0
             while i < 30000:
                 lst = range(i % 1000 + 2)
-                sa += max(*lst) # ID: max
+                sa += max(*lst)  # ID: callmax
                 i += 1
             return sa
         log = self.run(main, [])
         assert log.result == main()
         loop, = log.loops_by_filename(self.filepath)
-        assert loop.match("""
+        assert loop.match_by_id('callmax', """
             ...
-            p76 = call_assembler_r(..., descr=...)
+            p76 = call_may_force_r(_, _, _, _, descr=...)
             ...
         """)
-        loop2 = log.loops[0]
-        loop2.match('''
-        ...
-        label(..., descr=...)
-        ...
-        label(..., descr=...)
-        guard_not_invalidated?
-        i17 = int_ge(i11, i7)
-        guard_false(i17, descr=...)
-        p18 = getarrayitem_gc_r(p5, i11, descr=...)
-        i19 = int_add(i11, 1)
-        setfield_gc(p2, i19, descr=...)
-        guard_nonnull_class(p18, ConstClass(W_IntObject), descr=...)
-        i20 = getfield_gc_i(p18, descr=...)
-        i21 = int_gt(i20, i14)
-        guard_true(i21, descr=...)
-        jump(..., descr=...)
-        ''')
-        # XXX could be "guard_class(p18)" instead; we lost somewhere
-        # the information that it cannot be null.
+        
+        #----- the following logic used to check the content of the assembly
+        #----- generated for the loop in max(), but now we no longer produce
+        #----- any custom assembly in this case.  It used to say
+        #----- 'call_assembler_r' above, and now it says 'call_may_force_r'.
+        #loop2 = log.loops[0]
+        #loop2.match('''
+        #...
+        #label(..., descr=...)
+        #...
+        #label(..., descr=...)
+        #guard_not_invalidated?
+        #i17 = int_ge(i11, i7)
+        #guard_false(i17, descr=...)
+        #p18 = getarrayitem_gc_r(p5, i11, descr=...)
+        #i19 = int_add(i11, 1)
+        #setfield_gc(p2, i19, descr=...)
+        #guard_nonnull_class(p18, ConstClass(W_IntObject), descr=...)
+        #i20 = getfield_gc_i(p18, descr=...)
+        #i21 = int_gt(i20, i14)
+        #guard_true(i21, descr=...)
+        #jump(..., descr=...)
+        #''')
+        ## XXX could be "guard_class(p18)" instead; we lost somewhere
+        ## the information that it cannot be null.
 
     def test_iter_max(self):
         def main():
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
@@ -1387,6 +1387,7 @@
         ffi = FFI(backend=self.Backend())
         ffi.cdef("enum foo;")
         with warnings.catch_warnings(record=True) as log:
+            warnings.simplefilter("always")
             n = ffi.cast("enum foo", -1)
             assert int(n) == 0xffffffff
         assert str(log[0].message) == (
diff --git a/pypy/module/test_lib_pypy/cffi_tests/cffi0/test_function.py b/pypy/module/test_lib_pypy/cffi_tests/cffi0/test_function.py
--- a/pypy/module/test_lib_pypy/cffi_tests/cffi0/test_function.py
+++ b/pypy/module/test_lib_pypy/cffi_tests/cffi0/test_function.py
@@ -46,14 +46,14 @@
         assert x != math.sin(1.23)    # rounding effects
         assert abs(x - math.sin(1.23)) < 1E-6
 
-    def test_sin_no_return_value(self):
+    def test_lround_no_return_value(self):
         # check that 'void'-returning functions work too
         ffi = FFI(backend=self.Backend())
         ffi.cdef("""
-            void sin(double x);
+            void lround(double x);
         """)
         m = ffi.dlopen(lib_m)
-        x = m.sin(1.23)
+        x = m.lround(1.23)
         assert x is None
 
     def test_dlopen_filename(self):
diff --git a/pypy/module/test_lib_pypy/ctypes_tests/test_callbacks.py b/pypy/module/test_lib_pypy/ctypes_tests/test_callbacks.py
--- a/pypy/module/test_lib_pypy/ctypes_tests/test_callbacks.py
+++ b/pypy/module/test_lib_pypy/ctypes_tests/test_callbacks.py
@@ -160,15 +160,17 @@
 
         proto = CFUNCTYPE(c_int, RECT)
         def callback(point):
+            point.left *= -1
             return point.left+point.top+point.right+point.bottom
 
         cbp = proto(callback)
 
-        rect = RECT(1000,100,10,1)
+        rect = RECT(-1000,100,10,1)
 
         res = cbp(rect)
 
         assert res == 1111
+        assert rect.left == -1000   # must not have been changed!
 
     def test_callback_from_c_with_struct_argument(self):
         import conftest
diff --git a/rpython/translator/platform/windows.py b/rpython/translator/platform/windows.py
--- a/rpython/translator/platform/windows.py
+++ b/rpython/translator/platform/windows.py
@@ -186,7 +186,7 @@
             self.cc = cc
 
         # detect version of current compiler
-        returncode, stdout, stderr = _run_subprocess(self.cc, '',
+        returncode, stdout, stderr = _run_subprocess(self.cc, [],
                                                      env=self.c_environ)
         r = re.search(r'Microsoft.+C/C\+\+.+\s([0-9]+)\.([0-9]+).*', stderr)
         if r is not None:
@@ -196,7 +196,7 @@
             self.version = 0
 
         # Try to find a masm assembler
-        returncode, stdout, stderr = _run_subprocess('ml.exe', '',
+        returncode, stdout, stderr = _run_subprocess('ml.exe', [],
                                                      env=self.c_environ)
         r = re.search('Macro Assembler', stderr)
         if r is None and os.path.exists('c:/masm32/bin/ml.exe'):


More information about the pypy-commit mailing list