[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