[pypy-commit] pypy unicode-utf8-py3: merge py3.5 into branch
mattip
pypy.commits at gmail.com
Sun Sep 23 09:20:43 EDT 2018
Author: Matti Picus <matti.picus at gmail.com>
Branch: unicode-utf8-py3
Changeset: r95158:5a2d488be5e6
Date: 2018-09-23 16:08 +0300
http://bitbucket.org/pypy/pypy/changeset/5a2d488be5e6/
Log: merge py3.5 into branch
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,
@@ -131,8 +134,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
@@ -36,7 +36,10 @@
Small refactorings in the Python parser.
+.. branch: fix-readme-typo
+
.. branch: unicode-utf8-re
+
.. branch: utf8-io
Utf8 handling for unicode
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/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
@@ -3957,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