Author: Carl Friedrich Bolz-Tereick <cfb...@gmx.de> Branch: py3.7 Changeset: r98357:53d92a0bd2cd Date: 2019-12-22 15:51 +0100 http://bitbucket.org/pypy/pypy/changeset/53d92a0bd2cd/
Log: merge py3.6 diff too long, truncating to 2000 out of 22776 lines diff --git a/.hgtags b/.hgtags --- a/.hgtags +++ b/.hgtags @@ -57,3 +57,7 @@ 4a68d8d3d2fc1faec2e83bcb4d28559099092574 release-pypy2.7-v7.2.0rc2 4a68d8d3d2fc1faec2e83bcb4d28559099092574 release-pypy2.7-v7.2.0 5da45ced70e515f94686be0df47c59abd1348ebc release-pypy3.6-v7.2.0 +e6471221abc16f4584a07fbfeece7ebcaeb7fc38 release-pypy2.7-v7.3.0rc1 +533398cfd64e5146a07c4824e90a1b629c8b6523 release-pypy3.6-v7.3.0rc1 +285307a0f5a77ffa46781b5c54c52eb1c385081d release-pypy2.7-v7.3.0rc2 +008914050baeedb6d3ca30fe26ef43b78bb63841 release-pypy3.6-v7.3.0rc2 diff --git a/LICENSE b/LICENSE --- a/LICENSE +++ b/LICENSE @@ -99,16 +99,16 @@ Spenser Bauman Michal Bendowski Jan de Mooij + Stefano Rivera Tyler Wade + Stefan Beyer Vincent Legoll Michael Foord Stephan Diehl - Stefano Rivera Jean-Paul Calderone Stefan Schwarzer Tomek Meka Valentino Volonghi - Stefan Beyer Patrick Maupin Devin Jeanpierre Bob Ippolito @@ -137,9 +137,10 @@ Jean-Philippe St. Pierre Guido van Rossum Pavel Vinogradov + Stian Andreassen + Julian Berman William Leslie Paweł Piotr Przeradowski - Stian Andreassen marky1991 Ilya Osadchiy Tobias Oberstein @@ -150,7 +151,7 @@ tav Georg Brandl Joannah Nanjekye - Julian Berman + Yannick Jadoul Bert Freudenberg Wanja Saatkamp Mike Blume @@ -275,6 +276,7 @@ Lutz Paelike Ian Foote Philipp Rustemeuer + Bernd Schoeller Logan Chien Catalin Gabriel Manciu Jacob Oscarson @@ -302,7 +304,6 @@ Laurens Van Houtven Bobby Impollonia Roberto De Ioris - Yannick Jadoul Jeong YunWon Christopher Armstrong Aaron Tubbs @@ -357,6 +358,7 @@ Daniil Yarancev Min RK OlivierBlanvillain + bernd.schoel...@inf.ethz.ch dakar...@gmail.com Jonas Pfannschmidt Zearin @@ -398,6 +400,7 @@ Jesdi Konrad Delong Dinu Gherman + Sam Edwards pizi Tomáš Pružina James Robert diff --git a/extra_tests/cffi_tests/cffi0/test_verify.py b/extra_tests/cffi_tests/cffi0/test_verify.py --- a/extra_tests/cffi_tests/cffi0/test_verify.py +++ b/extra_tests/cffi_tests/cffi0/test_verify.py @@ -4,6 +4,7 @@ import sys, os, math, weakref from cffi import FFI, VerificationError, VerificationMissing, model, FFIError from extra_tests.cffi_tests.support import * +from extra_tests.cffi_tests.support import extra_compile_args lib_m = ['m'] @@ -14,17 +15,6 @@ lib_m = ['msvcrt'] pass # no obvious -Werror equivalent on MSVC else: - if (sys.platform == 'darwin' and - [int(x) for x in os.uname()[2].split('.')] >= [11, 0, 0]): - # assume a standard clang or gcc - extra_compile_args = ['-Werror', '-Wall', '-Wextra', '-Wconversion'] - # special things for clang - extra_compile_args.append('-Qunused-arguments') - else: - # assume a standard gcc - extra_compile_args = ['-Werror', '-Wall', '-Wextra', '-Wconversion', - '-Wno-unused-parameter'] - class FFI(FFI): def verify(self, *args, **kwds): return super(FFI, self).verify( diff --git a/extra_tests/cffi_tests/cffi1/test_recompiler.py b/extra_tests/cffi_tests/cffi1/test_recompiler.py --- a/extra_tests/cffi_tests/cffi1/test_recompiler.py +++ b/extra_tests/cffi_tests/cffi1/test_recompiler.py @@ -35,8 +35,9 @@ source = 'extern "C" {\n%s\n}' % (source,) elif sys.platform != 'win32': # add '-Werror' to the existing 'extra_compile_args' flags + from extra_tests.cffi_tests.support import extra_compile_args kwds['extra_compile_args'] = (kwds.get('extra_compile_args', []) + - ['-Werror']) + extra_compile_args) return _verify(ffi, module_name, source, *args, **kwds) def test_set_source_no_slashes(): @@ -2039,7 +2040,7 @@ ffi.cdef("float _Complex f1(float a, float b);"); lib = verify(ffi, "test_function_returns_float_complex", """ #include <complex.h> - static float _Complex f1(float a, float b) { return a + I*2.0*b; } + static float _Complex f1(float a, float b) { return a + I*2.0f*b; } """, no_cpp=True) # <complex.h> fails on some systems with C++ result = lib.f1(1.25, 5.1) assert type(result) == complex diff --git a/extra_tests/cffi_tests/cffi1/test_verify1.py b/extra_tests/cffi_tests/cffi1/test_verify1.py --- a/extra_tests/cffi_tests/cffi1/test_verify1.py +++ b/extra_tests/cffi_tests/cffi1/test_verify1.py @@ -5,7 +5,7 @@ from cffi import CDefError from cffi import recompiler from extra_tests.cffi_tests.support import * -from extra_tests.cffi_tests.support import _verify +from extra_tests.cffi_tests.support import _verify, extra_compile_args import _cffi_backend lib_m = ['m'] @@ -14,18 +14,6 @@ import distutils.ccompiler if distutils.ccompiler.get_default_compiler() == 'msvc': lib_m = ['msvcrt'] - extra_compile_args = [] # no obvious -Werror equivalent on MSVC -else: - if (sys.platform == 'darwin' and - [int(x) for x in os.uname()[2].split('.')] >= [11, 0, 0]): - # assume a standard clang or gcc - extra_compile_args = ['-Werror', '-Wall', '-Wextra', '-Wconversion'] - # special things for clang - extra_compile_args.append('-Qunused-arguments') - else: - # assume a standard gcc - extra_compile_args = ['-Werror', '-Wall', '-Wextra', '-Wconversion', - '-Wno-unused-parameter'] class FFI(FFI): error = _cffi_backend.FFI.error diff --git a/extra_tests/cffi_tests/support.py b/extra_tests/cffi_tests/support.py --- a/extra_tests/cffi_tests/support.py +++ b/extra_tests/cffi_tests/support.py @@ -1,5 +1,5 @@ # Generated by pypy/tool/import_cffi.py -import sys +import sys, os if sys.version_info < (3,): __all__ = ['u'] @@ -87,3 +87,24 @@ if not name.startswith('_') and not hasattr(module.ffi, name): setattr(ffi, name, NotImplemented) return module.lib + + +# For testing, we call gcc with "-Werror". This is fragile because newer +# versions of gcc are always better at producing warnings, particularly for +# auto-generated code. We need here to adapt and silence them as needed. + +if sys.platform == 'win32': + extra_compile_args = [] # no obvious -Werror equivalent on MSVC +else: + if (sys.platform == 'darwin' and + [int(x) for x in os.uname()[2].split('.')] >= [11, 0, 0]): + # assume a standard clang or gcc + extra_compile_args = ['-Werror', '-Wall', '-Wextra', '-Wconversion', + '-Wno-unreachable-code'] + # special things for clang + extra_compile_args.append('-Qunused-arguments') + else: + # assume a standard gcc + extra_compile_args = ['-Werror', '-Wall', '-Wextra', '-Wconversion', + '-Wno-unused-parameter', + '-Wno-unreachable-code'] diff --git a/extra_tests/test_datetime.py b/extra_tests/test_datetime.py --- a/extra_tests/test_datetime.py +++ b/extra_tests/test_datetime.py @@ -350,3 +350,31 @@ d2 = d.replace(hour=7) assert type(d2) is MyDatetime assert d2 == datetime.datetime(2016, 4, 5, 7, 2, 3) + +def test_normalize_pair(): + normalize = datetime._normalize_pair + + assert normalize(1, 59, 60) == (1, 59) + assert normalize(1, 60, 60) == (2, 0) + assert normalize(1, 95, 60) == (2, 35) + +def test_normalize_date(): + normalize = datetime._normalize_date + + # Huge year is caught correctly + with pytest.raises(OverflowError): + normalize(1000 * 1000, 1, 1) + # Normal dates should be unchanged + assert normalize(3000, 1, 1) == (3000, 1, 1) + # Month overflows year boundary + assert normalize(2001, 24, 1) == (2002, 12, 1) + # Day overflows month boundary + assert normalize(2001, 14, 31) == (2002, 3, 3) + # Leap years? :S + assert normalize(2001, 1, 61) == (2001, 3, 2) + assert normalize(2000, 1, 61) == (2000, 3, 1) + +def test_normalize_datetime(): + normalize = datetime._normalize_datetime + abnormal = (2002, 13, 35, 30, 95, 75, 1000001) + assert normalize(*abnormal) == (2003, 2, 5, 7, 36, 16, 1) diff --git a/lib-python/3/datetime.py b/lib-python/3/datetime.py --- a/lib-python/3/datetime.py +++ b/lib-python/3/datetime.py @@ -1544,9 +1544,13 @@ self.__setstate(year, month) self._hashcode = -1 return self - year, month, day = _check_date_fields(year, month, day) - hour, minute, second, microsecond, fold = _check_time_fields( - hour, minute, second, microsecond, fold) + elif isinstance(year, tuple) and len(year) == 7: + # Internal operation - numbers guaranteed to be valid + year, month, day, hour, minute, second, microsecond = year + else: + year, month, day = _check_date_fields(year, month, day) + hour, minute, second, microsecond, fold = _check_time_fields( + hour, minute, second, microsecond, fold) _check_tzinfo_arg(tzinfo) self = dateinterop.__new__(cls) self._year = int(year) @@ -2035,20 +2039,18 @@ "Add a datetime and a timedelta." if not isinstance(other, timedelta): return NotImplemented - delta = timedelta(self.toordinal(), - hours=self._hour, - minutes=self._minute, - seconds=self._second, - microseconds=self._microsecond) - delta += other - hour, rem = divmod(delta.seconds, 3600) - minute, second = divmod(rem, 60) - if 0 < delta.days <= _MAXORDINAL: - return datetime.combine(date.fromordinal(delta.days), - time(hour, minute, second, - delta.microseconds, - tzinfo=self._tzinfo)) - raise OverflowError("result out of range") + + result = _normalize_datetime( + self._year, + self._month, + self._day + other.days, + self._hour, + self._minute, + self._second + other.seconds, + self._microsecond + other.microseconds, + ) + + return datetime(result, tzinfo=self._tzinfo) __radd__ = __add__ @@ -2145,6 +2147,65 @@ datetime.resolution = timedelta(microseconds=1) +def _normalize_pair(hi, lo, factor): + if not 0 <= lo <= factor-1: + inc, lo = divmod(lo, factor) + hi += inc + return hi, lo + + +def _normalize_datetime(y, m, d, hh, mm, ss, us): + # Normalize all the inputs, and store the normalized values. + ss, us = _normalize_pair(ss, us, 1000000) + mm, ss = _normalize_pair(mm, ss, 60) + hh, mm = _normalize_pair(hh, mm, 60) + d, hh = _normalize_pair(d, hh, 24) + y, m, d = _normalize_date(y, m, d) + return y, m, d, hh, mm, ss, us + + +def _normalize_date(year, month, day): + # That was easy. Now it gets muddy: the proper range for day + # can't be determined without knowing the correct month and year, + # but if day is, e.g., plus or minus a million, the current month + # and year values make no sense (and may also be out of bounds + # themselves). + # Saying 12 months == 1 year should be non-controversial. + if not 1 <= month <= 12: + year, month = _normalize_pair(year, month-1, 12) + month += 1 + assert 1 <= month <= 12 + + # Now only day can be out of bounds (year may also be out of bounds + # for a datetime object, but we don't care about that here). + # If day is out of bounds, what to do is arguable, but at least the + # method here is principled and explainable. + dim = _days_in_month(year, month) + if not 1 <= day <= dim: + # Move day-1 days from the first of the month. First try to + # get off cheap if we're only one day out of range (adjustments + # for timezone alone can't be worse than that). + if day == 0: # move back a day + month -= 1 + if month > 0: + day = _days_in_month(year, month) + else: + year, month, day = year-1, 12, 31 + elif day == dim + 1: # move forward a day + month += 1 + day = 1 + if month > 12: + month = 1 + year += 1 + else: + ordinal = _ymd2ord(year, month, 1) + (day - 1) + year, month, day = _ord2ymd(ordinal) + + if not MINYEAR <= year <= MAXYEAR: + raise OverflowError("date value out of range") + return year, month, day + + def _isoweek1monday(year): # Helper to calculate the day number of the Monday starting week 1 # XXX This could be done more efficiently diff --git a/lib-python/3/importlib/_bootstrap.py b/lib-python/3/importlib/_bootstrap.py --- a/lib-python/3/importlib/_bootstrap.py +++ b/lib-python/3/importlib/_bootstrap.py @@ -67,6 +67,7 @@ # Deadlock avoidance for concurrent circular imports. me = _thread.get_ident() tid = self.owner + count = 0 while True: lock = _blocking_on.get(tid) if lock is None: @@ -74,6 +75,14 @@ tid = lock.owner if tid == me: return True + # workaround for https://bugs.python.org/issue38091: + # instead of looping here forever, eventually return False. + # Unsure if this will cause real deadlocks to go undetected, + # but at least it doesn't cause *this* logic here to + # deadlock when there is otherwise no deadlock! + count += 1 + if count >= 100: + return False def acquire(self): """ diff --git a/lib-python/3/sysconfig.py b/lib-python/3/sysconfig.py --- a/lib-python/3/sysconfig.py +++ b/lib-python/3/sysconfig.py @@ -451,6 +451,10 @@ vars['EXE'] = '.exe' vars['VERSION'] = _PY_VERSION_SHORT_NO_DOT vars['BINDIR'] = os.path.dirname(_safe_realpath(sys.executable)) + # pypy: give us control over the ABI tag in a wheel name + import _imp + so_ext = _imp.extension_suffixes()[0] + vars['SOABI']= '-'.join(so_ext.split('.')[1].split('-')[:2]) # # public APIs diff --git a/lib-python/3/test/test_asyncio/test_events.py b/lib-python/3/test/test_asyncio/test_events.py --- a/lib-python/3/test/test_asyncio/test_events.py +++ b/lib-python/3/test/test_asyncio/test_events.py @@ -943,9 +943,14 @@ server = self.loop.run_until_complete(f) self.assertEqual(len(server.sockets), 1) sock = server.sockets[0] - self.assertFalse( - sock.getsockopt( - socket.SOL_SOCKET, socket.SO_REUSEPORT)) + try: + self.assertFalse( + sock.getsockopt( + socket.SOL_SOCKET, socket.SO_REUSEPORT)) + except OSError: + # SO_REUSEPORT is not actually supported, bail! + server.close() + return server.close() test_utils.run_briefly(self.loop) diff --git a/lib-python/3/test/test_dis.py b/lib-python/3/test/test_dis.py --- a/lib-python/3/test/test_dis.py +++ b/lib-python/3/test/test_dis.py @@ -272,7 +272,7 @@ 20 RETURN_VALUE """ -# XXX: change for PyPy? +# changed for PyPy dis_traceback = """\ %3d 0 SETUP_EXCEPT 12 (to 14) @@ -830,9 +830,9 @@ # End fodder for opinfo generation tests expected_outer_line = 1 _line_offset = outer.__code__.co_firstlineno - 1 -code_object_f = outer.__code__.co_consts[3] +code_object_f = outer.__code__.co_consts[2] expected_f_line = code_object_f.co_firstlineno - _line_offset -code_object_inner = code_object_f.co_consts[3] +code_object_inner = code_object_f.co_consts[2] expected_inner_line = code_object_inner.co_firstlineno - _line_offset expected_jumpy_line = 1 @@ -857,22 +857,22 @@ Instruction = dis.Instruction expected_opinfo_outer = [ - Instruction(opname='LOAD_CONST', opcode=100, arg=8, argval=(3, 4), argrepr='(3, 4)', offset=0, starts_line=2, is_jump_target=False), + Instruction(opname='LOAD_CONST', opcode=100, arg=1, argval=(3, 4), argrepr='(3, 4)', offset=0, starts_line=2, is_jump_target=False), Instruction(opname='LOAD_CLOSURE', opcode=135, arg=0, argval='a', argrepr='a', offset=2, starts_line=None, is_jump_target=False), Instruction(opname='LOAD_CLOSURE', opcode=135, arg=1, argval='b', argrepr='b', offset=4, starts_line=None, is_jump_target=False), Instruction(opname='BUILD_TUPLE', opcode=102, arg=2, argval=2, argrepr='', offset=6, starts_line=None, is_jump_target=False), - Instruction(opname='LOAD_CONST', opcode=100, arg=3, argval=code_object_f, argrepr=repr(code_object_f), offset=8, starts_line=None, is_jump_target=False), - Instruction(opname='LOAD_CONST', opcode=100, arg=4, argval='outer.<locals>.f', argrepr="'outer.<locals>.f'", offset=10, starts_line=None, is_jump_target=False), + Instruction(opname='LOAD_CONST', opcode=100, arg=2, argval=code_object_f, argrepr=repr(code_object_f), offset=8, starts_line=None, is_jump_target=False), + Instruction(opname='LOAD_CONST', opcode=100, arg=3, argval='outer.<locals>.f', argrepr="'outer.<locals>.f'", offset=10, starts_line=None, is_jump_target=False), Instruction(opname='MAKE_FUNCTION', opcode=132, arg=9, argval=9, argrepr='', offset=12, starts_line=None, is_jump_target=False), Instruction(opname='STORE_FAST', opcode=125, arg=2, argval='f', argrepr='f', offset=14, starts_line=None, is_jump_target=False), Instruction(opname='LOAD_GLOBAL', opcode=116, arg=0, argval='print', argrepr='print', offset=16, starts_line=7, is_jump_target=False), Instruction(opname='LOAD_DEREF', opcode=136, arg=0, argval='a', argrepr='a', offset=18, starts_line=None, is_jump_target=False), Instruction(opname='LOAD_DEREF', opcode=136, arg=1, argval='b', argrepr='b', offset=20, starts_line=None, is_jump_target=False), - Instruction(opname='LOAD_CONST', opcode=100, arg=5, argval='', argrepr="''", offset=22, starts_line=None, is_jump_target=False), - Instruction(opname='LOAD_CONST', opcode=100, arg=6, argval=1, argrepr='1', offset=24, starts_line=None, is_jump_target=False), + Instruction(opname='LOAD_CONST', opcode=100, arg=4, argval='', argrepr="''", offset=22, starts_line=None, is_jump_target=False), + Instruction(opname='LOAD_CONST', opcode=100, arg=5, argval=1, argrepr='1', offset=24, starts_line=None, is_jump_target=False), Instruction(opname='BUILD_LIST', opcode=103, arg=0, argval=0, argrepr='', offset=26, starts_line=None, is_jump_target=False), Instruction(opname='BUILD_MAP', opcode=105, arg=0, argval=0, argrepr='', offset=28, starts_line=None, is_jump_target=False), - Instruction(opname='LOAD_CONST', opcode=100, arg=7, argval='Hello world!', argrepr="'Hello world!'", offset=30, starts_line=None, is_jump_target=False), + Instruction(opname='LOAD_CONST', opcode=100, arg=6, argval='Hello world!', argrepr="'Hello world!'", offset=30, starts_line=None, is_jump_target=False), Instruction(opname='CALL_FUNCTION', opcode=131, arg=7, argval=7, argrepr='', offset=32, starts_line=None, is_jump_target=False), Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=34, starts_line=None, is_jump_target=False), Instruction(opname='LOAD_FAST', opcode=124, arg=2, argval='f', argrepr='f', offset=36, starts_line=8, is_jump_target=False), @@ -880,14 +880,14 @@ ] expected_opinfo_f = [ - Instruction(opname='LOAD_CONST', opcode=100, arg=5, argval=(5, 6), argrepr='(5, 6)', offset=0, starts_line=3, is_jump_target=False), + Instruction(opname='LOAD_CONST', opcode=100, arg=1, argval=(5, 6), argrepr='(5, 6)', offset=0, starts_line=3, is_jump_target=False), Instruction(opname='LOAD_CLOSURE', opcode=135, arg=2, argval='a', argrepr='a', offset=2, starts_line=None, is_jump_target=False), Instruction(opname='LOAD_CLOSURE', opcode=135, arg=3, argval='b', argrepr='b', offset=4, starts_line=None, is_jump_target=False), Instruction(opname='LOAD_CLOSURE', opcode=135, arg=0, argval='c', argrepr='c', offset=6, starts_line=None, is_jump_target=False), Instruction(opname='LOAD_CLOSURE', opcode=135, arg=1, argval='d', argrepr='d', offset=8, starts_line=None, is_jump_target=False), Instruction(opname='BUILD_TUPLE', opcode=102, arg=4, argval=4, argrepr='', offset=10, starts_line=None, is_jump_target=False), - Instruction(opname='LOAD_CONST', opcode=100, arg=3, argval=code_object_inner, argrepr=repr(code_object_inner), offset=12, starts_line=None, is_jump_target=False), - Instruction(opname='LOAD_CONST', opcode=100, arg=4, argval='outer.<locals>.f.<locals>.inner', argrepr="'outer.<locals>.f.<locals>.inner'", offset=14, starts_line=None, is_jump_target=False), + Instruction(opname='LOAD_CONST', opcode=100, arg=2, argval=code_object_inner, argrepr=repr(code_object_inner), offset=12, starts_line=None, is_jump_target=False), + Instruction(opname='LOAD_CONST', opcode=100, arg=3, argval='outer.<locals>.f.<locals>.inner', argrepr="'outer.<locals>.f.<locals>.inner'", offset=14, starts_line=None, is_jump_target=False), Instruction(opname='MAKE_FUNCTION', opcode=132, arg=9, argval=9, argrepr='', offset=16, starts_line=None, is_jump_target=False), Instruction(opname='STORE_FAST', opcode=125, arg=2, argval='inner', argrepr='inner', offset=18, starts_line=None, is_jump_target=False), Instruction(opname='LOAD_GLOBAL', opcode=116, arg=0, argval='print', argrepr='print', offset=20, starts_line=5, is_jump_target=False), diff --git a/lib-python/3/test/test_extcall.py b/lib-python/3/test/test_extcall.py --- a/lib-python/3/test/test_extcall.py +++ b/lib-python/3/test/test_extcall.py @@ -57,7 +57,7 @@ Traceback (most recent call last): ... TypeError: ...got multiple values for keyword argument 'a' - >>> f(1, 2, a=3, **{'a': 4}, **{'a': 5}) + >>> f(1, 2, a=3, **{'a': 4}, **{'a': 5}) #doctest: +ELLIPSIS Traceback (most recent call last): ... TypeError: ...got multiple values for keyword argument 'a' @@ -254,20 +254,21 @@ ... TypeError: h() argument after * must be an iterable, not function - >>> h(*[1], *h) + >>> h(*[1], *h) #doctest: +ELLIPSIS Traceback (most recent call last): ... - TypeError: h() argument after * must be an iterable, not function + TypeError: ... >>> dir(*h) Traceback (most recent call last): ... TypeError: dir() argument after * must be an iterable, not function - >>> None(*h) + >>> None(**h) #doctest: +ELLIPSIS Traceback (most recent call last): ... - TypeError: ...argument after * must be an iterable, not function + TypeError: ... object argument after ** must be a mapping, \ +not function >>> h(**h) Traceback (most recent call last): @@ -289,35 +290,20 @@ ... TypeError: h() argument after ** must be a mapping, not list - >>> h(**{'a': 1}, **h) + >>> h(**{'a': 1}, **h) #doctest: +ELLIPSIS Traceback (most recent call last): ... - TypeError: h() argument after ** must be a mapping, not function + TypeError: ...argument after ** must be a mapping, not function - >>> h(**{'a': 1}, **[]) + >>> h(**{'a': 1}, **[]) #doctest: +ELLIPSIS Traceback (most recent call last): ... - TypeError: h() argument after ** must be a mapping, not list + TypeError: ...argument after ** must be a mapping, not list >>> dir(**h) Traceback (most recent call last): ... - TypeError: ...argument after * must be an iterable, not function - - >>> None(*h) #doctest: +ELLIPSIS - Traceback (most recent call last): - ... - TypeError: ...argument after * must be an iterable, not function - - >>> h(**h) #doctest: +ELLIPSIS - Traceback (most recent call last): - ... - TypeError: ...argument after ** must be a mapping, not function - - >>> dir(**h) #doctest: +ELLIPSIS - Traceback (most recent call last): - ... - TypeError: ...argument after ** must be a mapping, not function + TypeError: dir() argument after ** must be a mapping, not function >>> None(**h) #doctest: +ELLIPSIS Traceback (most recent call last): diff --git a/lib-python/3/test/test_flufl.py b/lib-python/3/test/test_flufl.py --- a/lib-python/3/test/test_flufl.py +++ b/lib-python/3/test/test_flufl.py @@ -15,7 +15,7 @@ self.assertEqual(cm.exception.text, '2 != 3\n') self.assertEqual(cm.exception.filename, '<FLUFL test>') self.assertEqual(cm.exception.lineno, 2) - self.assertEqual(cm.exception.offset, 4) + self.assertEqual(cm.exception.offset, 2) # changed in PyPy def test_guido_as_bdfl(self): code = '2 {0} 3' @@ -26,7 +26,7 @@ self.assertEqual(cm.exception.text, '2 <> 3\n') self.assertEqual(cm.exception.filename, '<FLUFL test>') self.assertEqual(cm.exception.lineno, 1) - self.assertEqual(cm.exception.offset, 4) + self.assertEqual(cm.exception.offset, 2) # changed in PyPy if __name__ == '__main__': diff --git a/lib-python/3/test/test_import/__init__.py b/lib-python/3/test/test_import/__init__.py --- a/lib-python/3/test/test_import/__init__.py +++ b/lib-python/3/test/test_import/__init__.py @@ -414,16 +414,22 @@ os.does_not_exist def test_concurrency(self): + def delay_has_deadlock(frame, event, arg): + if event == 'call' and frame.f_code.co_name == 'has_deadlock': + time.sleep(0.05) + sys.path.insert(0, os.path.join(os.path.dirname(__file__), 'data')) try: exc = None def run(): + sys.settrace(delay_has_deadlock) event.wait() try: import package except BaseException as e: nonlocal exc exc = e + sys.settrace(None) for i in range(10): event = threading.Event() diff --git a/lib_pypy/_cffi_ssl/_stdssl/__init__.py b/lib_pypy/_cffi_ssl/_stdssl/__init__.py --- a/lib_pypy/_cffi_ssl/_stdssl/__init__.py +++ b/lib_pypy/_cffi_ssl/_stdssl/__init__.py @@ -1,4 +1,5 @@ import sys +import os import time import _thread import weakref @@ -10,7 +11,7 @@ import os msg = "\n\nThe _ssl cffi module either doesn't exist or is incompatible with your machine's shared libraries.\n" + \ "If you have a compiler installed, you can try to rebuild it by running:\n" + \ - "cd %s\n" % os.path.abspath(os.path.dirname(os.path.dirname(__file__))) + \ + "cd %s\n" % os.path.abspath(os.path.dirname(os.path.dirname(os.path.dirname(__file__)))) + \ "%s _ssl_build.py\n" % sys.executable raise ImportError(str(e) + msg) @@ -83,6 +84,11 @@ OP_NO_SSLv2 = lib.SSL_OP_NO_SSLv2 OP_NO_SSLv3 = lib.SSL_OP_NO_SSLv3 OP_NO_TLSv1_3 = lib.SSL_OP_NO_TLSv1_3 +if OPENSSL_VERSION_INFO > (1, 1, 0, 0, 0): + # OP_ENABLE_MIDDLEBOX_COMPAT = lib.SSL_OP_ENABLE_MIDDLEBOX_COMPAT + # XXX should be conditionally compiled into lib + OP_ENABLE_MIDDLEBOX_COMPAT = 0x00100000 + SSL_CLIENT = 0 @@ -289,6 +295,20 @@ mode |= lib.SSL_MODE_AUTO_RETRY lib.SSL_set_mode(ssl, mode) + if HAS_TLSv1_3: + if sslctx._post_handshake_auth: + if socket_type == SSL_SERVER: + # bpo-37428: OpenSSL does not ignore SSL_VERIFY_POST_HANDSHAKE. + # Set SSL_VERIFY_POST_HANDSHAKE flag only for server sockets and + # only in combination with SSL_VERIFY_PEER flag. + mode = lib.SSL_CTX_get_verify_mode(lib.SSL_get_SSL_CTX(self.ssl)) + if (mode & lib.SSL_VERIFY_PEER): + verify_cb = lib.SSL_get_verify_callback(self.ssl) + mode |= lib.SSL_VERIFY_POST_HANDSHAKE + lib.SSL_set_verify(ssl, mode, verify_cb) + else: + lib.SSL_set_post_handshake_auth(ssl, 1) + if HAS_SNI and self.server_hostname: name = _str_to_ffi_buffer(self.server_hostname) lib.SSL_set_tlsext_host_name(ssl, name) @@ -711,6 +731,15 @@ else: return None + def verify_client_post_handshake(self): + + if not HAS_TLSv1_3: + raise NotImplementedError("Post-handshake auth is not supported by " + "your OpenSSL version.") + err = lib.SSL_verify_client_post_handshake(self.ssl); + if err == 0: + raise pyssl_error(self, err) + def pending(self): count = lib.SSL_pending(self.ssl) if count < 0: @@ -767,6 +796,7 @@ return bool(lib.SSL_session_reused(self.ssl)) + def _fs_decode(name): return name.decode(sys.getfilesystemencoding()) def _fs_converter(name): @@ -822,13 +852,13 @@ if OPENSSL_VERSION_INFO > (1, 1, 0, 0, 0): aead = lib.SSL_CIPHER_is_aead(cipher) nid = lib.SSL_CIPHER_get_cipher_nid(cipher) - skcipher = OBJ_nid2ln(nid) if nid != NID_undef else None + skcipher = lib.OBJ_nid2ln(nid) if nid != lib.NID_undef else None nid = lib.SSL_CIPHER_get_digest_nid(cipher); - digest = OBJ_nid2ln(nid) if nid != NID_undef else None + digest = lib.OBJ_nid2ln(nid) if nid != lib.NID_undef else None nid = lib.SSL_CIPHER_get_kx_nid(cipher); - kx = OBJ_nid2ln(nid) if nid != NID_undef else None - nid = SSL_CIPHER_get_auth_nid(cipher); - auth = OBJ_nid2ln(nid) if nid != NID_undef else None + kx = lib.OBJ_nid2ln(nid) if nid != lib.NID_undef else None + nid = lib.SSL_CIPHER_get_auth_nid(cipher); + auth = lib.OBJ_nid2ln(nid) if nid != lib.NID_undef else None ret.update({'aead' : bool(aead), 'symmmetric' : skcipher, 'digest' : digest, @@ -888,9 +918,8 @@ class _SSLContext(object): __slots__ = ('ctx', '_check_hostname', 'servername_callback', 'alpn_protocols', '_alpn_protocols_handle', - 'npn_protocols', 'set_hostname', + 'npn_protocols', 'set_hostname', '_post_handshake_auth', '_set_hostname_handle', '_npn_protocols_handle') - def __new__(cls, protocol): self = object.__new__(cls) self.ctx = ffi.NULL @@ -967,6 +996,9 @@ if lib.Cryptography_HAS_X509_V_FLAG_TRUSTED_FIRST: store = lib.SSL_CTX_get_cert_store(self.ctx) lib.X509_STORE_set_flags(store, lib.X509_V_FLAG_TRUSTED_FIRST) + if HAS_TLSv1_3: + self.post_handshake_auth = 0; + lib.SSL_CTX_set_post_handshake_auth(self.ctx, self.post_handshake_auth) return self @property @@ -1052,6 +1084,7 @@ "CERT_OPTIONAL or CERT_REQUIRED") self._check_hostname = check_hostname + def set_ciphers(self, cipherlist): cipherlistbuf = _str_to_ffi_buffer(cipherlist) ret = lib.SSL_CTX_set_cipher_list(self.ctx, cipherlistbuf) @@ -1263,6 +1296,12 @@ return stats def set_default_verify_paths(self): + if (not os.environ.get('SSL_CERT_FILE') and + not os.environ.get('SSL_CERT_DIR') and + not sys.platform == 'win32'): + locations = get_default_verify_paths() + self.load_verify_locations(locations[1], locations[3]) + return if not lib.SSL_CTX_set_default_verify_paths(self.ctx): raise ssl_error("") @@ -1385,6 +1424,44 @@ outgoing) return sock + @property + def post_handshake_auth(self): + if HAS_TLSv1_3: + return bool(self._post_handshake_auth) + return None + + @post_handshake_auth.setter + def post_handshake_auth(self, arg): + if arg is None: + raise AttributeError("cannot delete attribute") + + pha = bool(arg) + self._post_handshake_auth = pha; + + # bpo-37428: newPySSLSocket() sets SSL_VERIFY_POST_HANDSHAKE flag for + # server sockets and SSL_set_post_handshake_auth() for client + + return 0; + + @property + def post_handshake_auth(self): + if HAS_TLSv1_3: + return bool(self._post_handshake_auth) + return None + + @post_handshake_auth.setter + def post_handshake_auth(self, arg): + if arg is None: + raise AttributeError("cannot delete attribute") + + pha = bool(arg) + self._post_handshake_auth = pha; + + # bpo-37428: newPySSLSocket() sets SSL_VERIFY_POST_HANDSHAKE flag for + # server sockets and SSL_set_post_handshake_auth() for client + + return 0; + # cryptography constraint: OPENSSL_NO_TLSEXT will never be set! @@ -1609,20 +1686,69 @@ lib.RAND_add(buf, len(buf), entropy) def get_default_verify_paths(): + ''' + Find a certificate store and associated values + Returns something like + `('SSL_CERT_FILE', '/usr/lib/ssl/cert.pem', 'SSL_CERT_DIR', '/usr/lib/ssl/certs')` + on Ubuntu and windows10 + + `('SSL_CERT_FILE', '/usr/local/cert.pem', 'SSL_CERT_DIR', '/usr/local/certs')` + on CentOS + + `('SSL_CERT_FILE', '/Library/Frameworks/Python.framework/Versions/2.7/etc/openssl/cert.pem', + 'SSL_CERT_DIR', '/Library/Frameworks/Python.framework/Versions/2.7/etc/openssl/certs')` + on Darwin + + For portable builds (based on CentOS, but could be running on any glibc + linux) we need to check other locations. The list of places to try was taken + from golang in Dec 2018: + https://golang.org/src/crypto/x509/root_unix.go (for the directories), + https://golang.org/src/crypto/x509/root_linux.go (for the files) + ''' + certFiles = [ + "/etc/ssl/certs/ca-certificates.crt", # Debian/Ubuntu/Gentoo etc. + "/etc/pki/tls/certs/ca-bundle.crt", # Fedora/RHEL 6 + "/etc/ssl/ca-bundle.pem", # OpenSUSE + "/etc/pki/tls/cacert.pem", # OpenELEC + "/etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pem", # CentOS/RHEL 7 + "/etc/ssl/cert.pem", # Alpine Linux + ] + certDirectories = [ + "/etc/ssl/certs", # SLES10/SLES11 + "/system/etc/security/cacerts", # Android + "/usr/local/share/certs", # FreeBSD + "/etc/pki/tls/certs", # Fedora/RHEL + "/etc/openssl/certs", # NetBSD + "/var/ssl/certs", # AIX + ] + + # optimization: reuse the values from a local varaible + if getattr(get_default_verify_paths, 'retval', None): + return get_default_verify_paths.retval + + # This should never fail, it should always return SSL_CERT_FILE and SSL_CERT_DIR ofile_env = _cstr_decode_fs(lib.X509_get_default_cert_file_env()) - if ofile_env is None: - return None + odir_env = _cstr_decode_fs(lib.X509_get_default_cert_dir_env()) + + # Platform depenedent ofile = _cstr_decode_fs(lib.X509_get_default_cert_file()) - if ofile is None: - return None - odir_env = _cstr_decode_fs(lib.X509_get_default_cert_dir_env()) - if odir_env is None: - return None odir = _cstr_decode_fs(lib.X509_get_default_cert_dir()) - if odir is None: - return odir - return (ofile_env, ofile, odir_env, odir); + + if os.path.exists(ofile) and os.path.exists(odir): + get_default_verify_paths.retval = (ofile_env, ofile, odir_env, odir) + return get_default_verify_paths.retval + + # OpenSSL didn't supply the goods. Try some other options + for f in certFiles: + if os.path.exists(f): + ofile = f + for f in certDirectories: + if os.path.exists(f): + odir = f + get_default_verify_paths.retval = (ofile_env, ofile, odir_env, odir) + return get_default_verify_paths.retval + @ffi.callback("int(SSL*,unsigned char **,unsigned char *,const unsigned char *,unsigned int,void *)") def select_alpn_callback(ssl, out, outlen, client_protocols, client_protocols_len, args): diff --git a/lib_pypy/_curses_build.py b/lib_pypy/_curses_build.py --- a/lib_pypy/_curses_build.py +++ b/lib_pypy/_curses_build.py @@ -1,12 +1,23 @@ -from cffi import FFI +from cffi import FFI, VerificationError import os +version_str = ''' + static const int NCURSES_VERSION_MAJOR; + static const int NCURSES_VERSION_MINOR; +''' + +version = (0, 0) def find_library(options): + global version for library in options: ffi = FFI() - ffi.set_source("_curses_cffi_check", "", libraries=[library]) + ffi.cdef(version_str) + ffi.set_source("_curses_cffi_check", version_str, libraries=[library]) try: ffi.compile() + import _curses_cffi_check + lib = _curses_cffi_check.lib + version = (lib.NCURSES_VERSION_MAJOR, lib.NCURSES_VERSION_MINOR) except VerificationError as e: e_last = e continue @@ -17,16 +28,27 @@ # error message raise e_last -def find_curses_include_dirs(): - if os.path.exists('/usr/include/ncurses'): - return ['/usr/include/ncurses'] - if os.path.exists('/usr/include/ncursesw'): - return ['/usr/include/ncursesw'] - return [] +def find_curses_dir_and_name(): + for base in ('/usr', '/usr/local'): + if os.path.exists(os.path.join(base, 'include', 'ncursesw')): + return base, 'ncursesw' + if os.path.exists(os.path.join(base, 'include', 'ncurses')): + return base, 'ncurses' + return '', None +base, name = find_curses_dir_and_name() +if base: + include_dirs = [os.path.join(base, 'include', name)] + library_dirs = [os.path.join(base, 'lib')] + libs = [name, name.replace('ncurses', 'panel')] +else: + include_dirs = [] + library_dirs = [] + libs = [find_library(['ncursesw', 'ncurses']), + find_library(['panelw', 'panel']), + ] ffi = FFI() - ffi.set_source("_curses_cffi", """ #ifdef __APPLE__ /* the following define is necessary for OS X 10.6+; without it, the @@ -73,9 +95,10 @@ void _m_getsyx(int *yx) { getsyx(yx[0], yx[1]); } -""", libraries=[find_library(['ncurses', 'ncursesw']), - find_library(['panel', 'panelw'])], - include_dirs=find_curses_include_dirs()) +""", libraries=libs, + library_dirs = library_dirs, + include_dirs=include_dirs, +) ffi.cdef(""" @@ -86,8 +109,6 @@ typedef unsigned long... chtype; typedef chtype attr_t; -typedef int... wint_t; - typedef struct { short id; /* ID to distinguish multiple devices */ @@ -159,11 +180,11 @@ int setupterm(char *, int, int *); -WINDOW *stdscr; -int COLORS; -int COLOR_PAIRS; -int COLS; -int LINES; +extern WINDOW *stdscr; +extern int COLORS; +extern int COLOR_PAIRS; +extern int COLS; +extern int LINES; int baudrate(void); int beep(void); @@ -186,8 +207,6 @@ void filter(void); int flash(void); int flushinp(void); -int wget_wch(WINDOW *, wint_t *); -int mvwget_wch(WINDOW *, int, int, wint_t *); chtype getbkgd(WINDOW *); WINDOW * getwin(FILE *); int halfdelay(int); @@ -263,7 +282,6 @@ int touchwin(WINDOW *); int typeahead(int); int ungetch(int); -int unget_wch(const wchar_t); int untouchwin(WINDOW *); void use_env(bool); int waddch(WINDOW *, const chtype); @@ -342,7 +360,7 @@ #define _m_NetBSD ... int _m_ispad(WINDOW *); -chtype acs_map[]; +extern chtype acs_map[]; // For _curses_panel: @@ -367,6 +385,14 @@ void _m_getsyx(int *yx); """) +if version > (5, 7): + ffi.cdef(""" +typedef int... wint_t; +int wget_wch(WINDOW *, wint_t *); +int mvwget_wch(WINDOW *, int, int, wint_t *); +int unget_wch(const wchar_t); +""") + if __name__ == "__main__": ffi.compile() diff --git a/lib_pypy/cffi.egg-info/PKG-INFO b/lib_pypy/cffi.egg-info/PKG-INFO --- a/lib_pypy/cffi.egg-info/PKG-INFO +++ b/lib_pypy/cffi.egg-info/PKG-INFO @@ -1,6 +1,6 @@ Metadata-Version: 1.1 Name: cffi -Version: 1.13.1 +Version: 1.13.2 Summary: Foreign Function Interface for Python calling C code. Home-page: http://cffi.readthedocs.org Author: Armin Rigo, Maciej Fijalkowski diff --git a/lib_pypy/cffi/__init__.py b/lib_pypy/cffi/__init__.py --- a/lib_pypy/cffi/__init__.py +++ b/lib_pypy/cffi/__init__.py @@ -5,8 +5,8 @@ from .error import CDefError, FFIError, VerificationError, VerificationMissing from .error import PkgConfigError -__version__ = "1.13.1" -__version_info__ = (1, 13, 1) +__version__ = "1.13.2" +__version_info__ = (1, 13, 2) # The verifier module file names are based on the CRC32 of a string that # contains the following version number. It may be older than __version__ diff --git a/lib_pypy/cffi/_cffi_include.h b/lib_pypy/cffi/_cffi_include.h --- a/lib_pypy/cffi/_cffi_include.h +++ b/lib_pypy/cffi/_cffi_include.h @@ -261,12 +261,12 @@ return (int)_cffi_to_c_wchar3216_t(o); } -_CFFI_UNUSED_FN static PyObject *_cffi_from_c_char32_t(int x) +_CFFI_UNUSED_FN static PyObject *_cffi_from_c_char32_t(unsigned int x) { if (sizeof(_cffi_wchar_t) == 4) return _cffi_from_c_wchar_t((_cffi_wchar_t)x); else - return _cffi_from_c_wchar3216_t(x); + return _cffi_from_c_wchar3216_t((int)x); } diff --git a/lib_pypy/cffi/_embedding.h b/lib_pypy/cffi/_embedding.h --- a/lib_pypy/cffi/_embedding.h +++ b/lib_pypy/cffi/_embedding.h @@ -224,7 +224,7 @@ if (f != NULL && f != Py_None) { PyFile_WriteString("\nFrom: " _CFFI_MODULE_NAME - "\ncompiled with cffi version: 1.13.1" + "\ncompiled with cffi version: 1.13.2" "\n_cffi_backend module: ", f); modules = PyImport_GetModuleDict(); mod = PyDict_GetItemString(modules, "_cffi_backend"); 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 @@ -159,9 +159,9 @@ def _warn_for_non_extern_non_static_global_variable(decl): if not decl.storage: import warnings - warnings.warn("Declaration of global variable '%s' in cdef() should " - "be marked 'extern' for consistency (or possibly " - "'static' in API mode)" % (decl.name,)) + warnings.warn("Global variable '%s' in cdef(): for consistency " + "with C it should have a storage class specifier " + "(usually 'extern')" % (decl.name,)) def _preprocess(csource): # Remove comments. NOTE: this only work because the cdef() section diff --git a/pypy/config/pypyoption.py b/pypy/config/pypyoption.py --- a/pypy/config/pypyoption.py +++ b/pypy/config/pypyoption.py @@ -219,11 +219,6 @@ BoolOption("newshortcut", "cache and shortcut calling __new__ from builtin types", default=False), - BoolOption("reinterpretasserts", - "Perform reinterpretation when an assert fails " - "(only relevant for tests)", - default=False), - ]), ]) diff --git a/pypy/config/test/test_pypyoption.py b/pypy/config/test/test_pypyoption.py --- a/pypy/config/test/test_pypyoption.py +++ b/pypy/config/test/test_pypyoption.py @@ -14,7 +14,7 @@ conf = get_pypy_config() conf.translation.gc = "boehm" with py.test.raises(ConfigError): - conf.translation.gcrootfinder = 'asmgcc' + conf.translation.gcrootfinder = 'shadowstack' def test_frameworkgc(): for name in ["minimark", "semispace"]: diff --git a/pypy/conftest.py b/pypy/conftest.py --- a/pypy/conftest.py +++ b/pypy/conftest.py @@ -135,8 +135,8 @@ return PyPyModule(path, parent) def is_applevel(item): - from pypy.tool.pytest.apptest import AppTestFunction - return isinstance(item, AppTestFunction) + from pypy.tool.pytest.apptest import AppTestMethod + return isinstance(item, AppTestMethod) def pytest_collection_modifyitems(config, items): if config.getoption('runappdirect') or config.getoption('direct_apptest'): @@ -166,8 +166,6 @@ def funcnamefilter(self, name): if name.startswith('test_'): return self.accept_regular_test() - if name.startswith('app_test_'): - return True return False def classnamefilter(self, name): @@ -182,13 +180,6 @@ if name.startswith('AppTest'): from pypy.tool.pytest.apptest import AppClassCollector return AppClassCollector(name, parent=self) - - elif hasattr(obj, 'func_code') and self.funcnamefilter(name): - if name.startswith('app_test_'): - assert not obj.func_code.co_flags & 32, \ - "generator app level functions? you must be joking" - from pypy.tool.pytest.apptest import AppTestFunction - return AppTestFunction(name, parent=self) return super(PyPyModule, self).makeitem(name, obj) def skip_on_missing_buildoption(**ropts): @@ -207,27 +198,15 @@ py.test.skip("need translated pypy3 with: %s, got %s" %(ropts,options)) -class LazyObjSpaceGetter(object): - def __get__(self, obj, cls=None): - from pypy.tool.pytest.objspace import gettestobjspace - space = gettestobjspace() - if cls: - cls.space = space - return space - - @pytest.hookimpl(tryfirst=True) def pytest_runtest_setup(item): if isinstance(item, py.test.collect.Function): appclass = item.getparent(py.test.Class) if appclass is not None: + from pypy.tool.pytest.objspace import gettestobjspace # Make cls.space and cls.runappdirect available in tests. - spaceconfig = getattr(appclass.obj, 'spaceconfig', None) - if spaceconfig is not None: - from pypy.tool.pytest.objspace import gettestobjspace - appclass.obj.space = gettestobjspace(**spaceconfig) - else: - appclass.obj.space = LazyObjSpaceGetter() + spaceconfig = getattr(appclass.obj, 'spaceconfig', {}) + appclass.obj.space = gettestobjspace(**spaceconfig) appclass.obj.runappdirect = option.runappdirect def pytest_ignore_collect(path, config): diff --git a/pypy/doc/build.rst b/pypy/doc/build.rst --- a/pypy/doc/build.rst +++ b/pypy/doc/build.rst @@ -60,12 +60,9 @@ Install build-time dependencies ------------------------------- (**Note**: for some hints on how to translate the Python interpreter under -Windows, see the `windows document`_ . For hints on how to cross-compile in -a chroot using scratchbox2, see the `arm document`_ in the -`RPython documentation`_) +Windows, see the `windows document`_ . .. _`windows document`: windows.html -.. _`arm document`: http://rpython.readthedocs.org/en/latest/arm.html .. _`RPython documentation`: http://rpython.readthedocs.org The host Python needs to have CFFI installed. If translating on PyPy, CFFI is @@ -88,9 +85,6 @@ pyexpat libexpat1 -_ssl - libssl - _vmprof libunwind (optional, loaded dynamically at runtime) @@ -104,6 +98,9 @@ sqlite3 libsqlite3 +_ssl, _hashlib + libssl + curses libncurses-dev (for PyPy2) libncursesw-dev (for PyPy3) @@ -115,11 +112,12 @@ tk-dev lzma (PyPy3 only) - liblzma + liblzma or libxz, version 5 and up -To run untranslated tests, you need the Boehm garbage collector libgc. +To run untranslated tests, you need the Boehm garbage collector libgc, version +7.4 and up -On recent Debian and Ubuntu (16.04 onwards), this is the command to install +On Debian and Ubuntu (16.04 onwards), this is the command to install all build-time dependencies:: apt-get install gcc make libffi-dev pkg-config zlib1g-dev libbz2-dev \ @@ -127,18 +125,11 @@ tk-dev libgc-dev python-cffi \ liblzma-dev libncursesw5-dev # these two only needed on PyPy3 -On older Debian and Ubuntu (12.04-14.04):: - - apt-get install gcc make libffi-dev pkg-config libz-dev libbz2-dev \ - libsqlite3-dev libncurses-dev libexpat1-dev libssl-dev libgdbm-dev \ - tk-dev libgc-dev python-cffi \ - liblzma-dev libncursesw-dev # these two only needed on PyPy3 - On Fedora:: dnf install gcc make libffi-devel pkgconfig zlib-devel bzip2-devel \ sqlite-devel ncurses-devel expat-devel openssl-devel tk-devel \ - gdbm-devel python-cffi\ + gdbm-devel python-cffi gc-devel\ xz-devel # For lzma on PyPy3. On SLES11:: diff --git a/pypy/doc/conf.py b/pypy/doc/conf.py --- a/pypy/doc/conf.py +++ b/pypy/doc/conf.py @@ -73,7 +73,7 @@ # The short X.Y version. version = '7.3' # The full version, including alpha/beta/rc tags. -release = '7.3.0' +release = '7.3.1' # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. diff --git a/pypy/doc/config/translation.gcrootfinder.txt b/pypy/doc/config/translation.gcrootfinder.txt --- a/pypy/doc/config/translation.gcrootfinder.txt +++ b/pypy/doc/config/translation.gcrootfinder.txt @@ -1,16 +1,7 @@ Choose the method used to find the roots in the GC. This only -applies to our framework GCs. You have a choice of two -alternatives: +applies to our framework GCs. - ``--gcrootfinder=shadowstack``: use a so-called "shadow stack", which is an explicitly maintained custom stack of - root pointers. This is the most portable solution. - -- ``--gcrootfinder=asmgcc``: use assembler hackery to find the - roots directly from the normal stack. This is a bit faster, - but platform specific. It works so far with GCC or MSVC, - on i386 and x86-64. It is tested only on Linux - so other platforms (as well as MSVC) may need - various fixes before they can be used. Note asmgcc will be deprecated - at some future date, and does not work with clang. - + root pointers. This is the most portable solution, and also + the only one available now. diff --git a/pypy/doc/contributing.rst b/pypy/doc/contributing.rst --- a/pypy/doc/contributing.rst +++ b/pypy/doc/contributing.rst @@ -311,16 +311,13 @@ directory or even the top level subdirectory ``pypy``. It takes hours and uses huge amounts of RAM and is not recommended. -To run CPython regression tests you can point to the ``lib-python`` -directory:: - - py.test lib-python/2.7/test/test_datetime.py - -This will usually take a long time because this will run -the PyPy Python interpreter on top of CPython. On the plus -side, it's usually still faster than doing a full translation -and running the regression test with the translated PyPy Python -interpreter. +To run CPython regression tests, you should start with a translated PyPy and +run the tests as you would with CPython (see below). You can, however, also +attempt to run the tests before translation, but be aware that it is done with +a hack that doesn't work in all cases and it is usually extremely slow: +``py.test lib-python/2.7/test/test_datetime.py``. Usually, a better idea is to +extract a minimal failing test of at most a few lines, and put it into one of +our own tests in ``pypy/*/test/``. .. _py.test testing tool: http://pytest.org .. _py.test usage and invocations: http://pytest.org/latest/usage.html#usage @@ -350,6 +347,11 @@ cpython2 pytest.py -A pypy/module/cpyext/test --python=path/to/pypy3 +To run a test from the standard CPython regression test suite, use the regular +Python way, i.e. (replace "pypy" with the exact binary name, if needed):: + + pypy -m test.test_datetime + Tooling & Utilities ^^^^^^^^^^^^^^^^^^^ diff --git a/pypy/doc/contributor.rst b/pypy/doc/contributor.rst --- a/pypy/doc/contributor.rst +++ b/pypy/doc/contributor.rst @@ -65,16 +65,16 @@ Spenser Bauman Michal Bendowski Jan de Mooij + Stefano Rivera Tyler Wade + Stefan Beyer Vincent Legoll Michael Foord Stephan Diehl - Stefano Rivera Jean-Paul Calderone Stefan Schwarzer Tomek Meka Valentino Volonghi - Stefan Beyer Patrick Maupin Devin Jeanpierre Bob Ippolito @@ -103,9 +103,10 @@ Jean-Philippe St. Pierre Guido van Rossum Pavel Vinogradov + Stian Andreassen + Julian Berman William Leslie Paweł Piotr Przeradowski - Stian Andreassen marky1991 Ilya Osadchiy Tobias Oberstein @@ -116,7 +117,7 @@ tav Georg Brandl Joannah Nanjekye - Julian Berman + Yannick Jadoul Bert Freudenberg Wanja Saatkamp Mike Blume @@ -241,6 +242,7 @@ Lutz Paelike Ian Foote Philipp Rustemeuer + Bernd Schoeller Logan Chien Catalin Gabriel Manciu Jacob Oscarson @@ -253,7 +255,6 @@ Lene Wagner Tomo Cocoa Miro Hrončok - Anthony Sottile David Lievens Neil Blakey-Milner Henrik Vendelbo @@ -269,7 +270,6 @@ Laurens Van Houtven Bobby Impollonia Roberto De Ioris - Yannick Jadoul Jeong YunWon Christopher Armstrong Aaron Tubbs @@ -324,6 +324,7 @@ Daniil Yarancev Min RK OlivierBlanvillain + bernd.schoel...@inf.ethz.ch dakar...@gmail.com Jonas Pfannschmidt Zearin @@ -365,6 +366,7 @@ Jesdi Konrad Delong Dinu Gherman + Sam Edwards pizi Tomáš Pružina James Robert diff --git a/pypy/doc/index-of-release-notes.rst b/pypy/doc/index-of-release-notes.rst --- a/pypy/doc/index-of-release-notes.rst +++ b/pypy/doc/index-of-release-notes.rst @@ -6,6 +6,7 @@ .. toctree:: + release-v7.3.0.rst release-v7.2.0.rst release-v7.1.1.rst release-v7.1.0.rst diff --git a/pypy/doc/index-of-whatsnew.rst b/pypy/doc/index-of-whatsnew.rst --- a/pypy/doc/index-of-whatsnew.rst +++ b/pypy/doc/index-of-whatsnew.rst @@ -7,6 +7,7 @@ .. toctree:: whatsnew-head.rst + whatsnew-pypy2-7.3.0.rst whatsnew-pypy2-7.2.0.rst whatsnew-pypy2-7.1.0.rst whatsnew-pypy2-7.0.0.rst @@ -43,6 +44,7 @@ .. toctree:: whatsnew-pypy3-head.rst + whatsnew-pypy3-7.3.0.rst whatsnew-pypy3-7.2.0.rst whatsnew-pypy3-7.1.0.rst diff --git a/pypy/doc/release-v7.3.0.rst b/pypy/doc/release-v7.3.0.rst new file mode 100644 --- /dev/null +++ b/pypy/doc/release-v7.3.0.rst @@ -0,0 +1,238 @@ +==================================== +PyPy v7.3.0: release of 2.7, and 3.6 +==================================== + +The PyPy team is proud to release the version 7.3.0 of PyPy, which includes +two different interpreters: + + - PyPy2.7, which is an interpreter supporting the syntax and the features of + Python 2.7 including the stdlib for CPython 2.7.13 + + - PyPy3.6: which is an interpreter supporting the syntax and the features of + Python 3.6, including the stdlib for CPython 3.6.9. + +The interpreters are based on much the same codebase, thus the double +release. + +We have worked with the python packaging group to support tooling around +building third party packages for python, so this release changes the ABI tag +for PyPy. + +Based on the great work done in `portable-pypy`_, the linux downloads we +provide are now built on top of the `manylinux2010`_ CentOS6 docker image. +The tarballs include the needed shared objects to run on any platform that +supports manylinux2010 wheels, which should include all supported versions of +debian- and RedHat-based distributions (including Ubuntu, CentOS, and Fedora). + +The `CFFI`_ backend has been updated to version 1.13.1. We recommend using CFFI +rather than c-extensions to interact with C. + +The built-in ``_cppyy`` module was upgraded to 1.10.6, which +provides, among others, better template resolution, stricter ``enum`` handling, +anonymous struct/unions, cmake fragments for distribution, optimizations for +PODs, and faster wrapper calls. We reccomend using cppyy_ for performant +wrapping of C++ code for Python. + +The vendored pyrepl package for interaction inside the REPL was updated. + +Support for codepage encoding and decoding was added for Windows. + +As always, this release fixed several issues and bugs raised by the growing +community of PyPy users. We strongly recommend updating. Many of the fixes are +the direct result of end-user bug reports, so please continue reporting issues +as they crop up. + +You can download the v7.3 releases here: + + http://pypy.org/download.html + +We would like to thank our donors for the continued support of the PyPy +project. If PyPy is not quite good enough for your needs, we are available for +direct consulting work. + +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. Since the +previous release, we have accepted contributions from 3 new contributors, +thanks for pitching in. + +.. _`PyPy`: index.html +.. _`RPython`: https://rpython.readthedocs.org +.. _`help`: project-ideas.html +.. _`CFFI`: http://cffi.readthedocs.io +.. _`cppyy`: https://cppyy.readthedocs.io +.. _`available as wheels`: https://github.com/antocuni/pypy-wheels +.. _`portable-pypy`: https://github.com/squeaky-pl/portable-pypy +.. _`manylinux2010`: https://github.com/pypa/manylinux + +What is PyPy? +============= + +PyPy is a very compliant Python interpreter, almost a drop-in replacement for +CPython 2.7, 3.6. 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 PyPy release supports: + + * **x86** machines on most common operating systems + (Linux 32/64 bits, Mac OS X 64 bits, Windows 32 bits, OpenBSD, FreeBSD) + + * big- and little-endian variants of **PPC64** running Linux, + + * **s390x** running Linux + + * 64-bit **ARM** machines running Linux. + +Unfortunately at the moment of writing our ARM buildbots are out of service, +so for now we are **not** releasing any binary for the ARM architecture (32 +bit), although PyPy does support ARM 32 bit processors. + +.. _`PyPy and CPython 2.7.x`: http://speed.pypy.org +.. _`dynamic languages`: http://rpython.readthedocs.io/en/latest/examples.html + + +Changelog +========= + +Changes shared across versions +------------------------------ + +* Fix segfault when calling descr-methods with no arguments +* Change the SOABI and subsequently change the reported ABI tag. +* Update the builtin ``_cppyy`` backend to 1.10.6 +* Performance improvements in string/unicode handling +* Fix compilation error when building `revdb`_ (`issue 3084`_, actually + released in PyPy 7.2 but not mentioned in the release notes) +* Add JIT options to documentation and an option for JIT help via ``pypy --jit + help`` +* Fix regex escapes in pyrepl (`issue 3097`_) +* Allow reloading of subclasses of module (`issue 3099`_) +* Work around a gcc bug, which was reported to them and fixed (`issue 3086`_) +* Fix (again) faulty logic when decoding invalid UTF-8 (`issue 2389`_) +* Fix up LICENSE file +* Turn all ``http`` links in the documentation to ``https`` +* Update the bndled pip and setuptools (used in ``pypy -mensurepip`` to version + that support `manylinux2010`_ wheels +* Link the ``DEFAULT_SOABI`` to the ``PYPY_VERSION`` +* Workaround for programs calling ``sys.setrecursionlimit(huge_value)`` (`issue + 3094`_) +* Set minimal ``MACOSX_DEPLOYMENT_TARGET`` to 10.7 on macOS; cpython uses 10.5 +* Fix a JIT bug causing rare register corruption on aarch64 +* Add discovery of ``ncursesw`` when building ``_minimal_curses`` and improve + handling of old curses versions (`issue 2970`_) +* Improve the error message for ``class X(random_object)`` (`issue 3109`_) +* Deal with json dicts containing repeated keys in the new map based parser + (`issue 3108`_) +* Port parts of the `portable pypy`_ repackaging scripts to add an option for + ``RPATH`` manipulation on linux +* Check for overflow in ctypes array creation +* Better support and report MSVC versions used to compile on windows +* Allow any kind of buffer in socket.setsockopt(), like CPython (`issue 3114`_) +* Fix importing a module with unicode in ``sys.path`` (`issue 3112`_) +* Support OpenSSL 1.1 and TLSv1_3 +* Remove the (deprecated since 5.7) asmgcc rootfinder from the GC +* Overflow in RPython when converting ``2<<32`` into a ``Signed`` on 32-bit + platforms rather than automatically using a ``SignedLongLong``, require an + explicit ``r_int64()`` call instead + +C-API (cpyext) and c-extensions +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +* Add ``_PySet_Next``, ``_PySet_NextEntry`` +* Correctly swallow exceptions happening inside ``PyDict_GetItem()`` (`issue + 3098`_) +* Respect tp_dict on PyType_Ready (`issue XXX`_) +* Allow calling ``PyType_Ready`` on a subclass with a partially built + ``tp_base`` (issue 3117`_) +* Rename ``tuple_new`` to ``_PyPy_tuple_new`` to follow the naming convention of + exported symbols in ``libpypy-c.so`` +* Actually restore the traceback in ``PyErr_Restore`` (`issue 3120`_) + +Python 3.6 only +--------------- + +* Don't grow the ``lzma.decompress()`` buffer past ``max_length`` (`issue 3088`_) +* Backport fix from CPython for failure of ``lzma`` to decompress a file + (`issue 3090`_) +* Fix ``asyncgen_hooks`` and refactor ``coroutine execution`` +* Fix range checking in GB18030 decoder (CPython issue `29990`_) +* Fix handling escape characters in HZ codec (CPython issue `30003`_) +* Reject null characters in a few more functions (CPython issue `13617`_) +* Fix build on macOS without ``clock_gettime`` (before 10.12 and xcode 8, + released 2016) +* Backport 3.7.5 changes to ``timedelta.__eq__`` and ``time.__eq__`` (CPython + issue `37579`_) +* Backport more fixes to comparisons in ``datetime.py`` (CPython issue `37985`_) +* Use the python tag in ``pyc`` file names, not the abi tag +* Handle string formatting with a single ``[`` in the format string (`issue + 3100`_) +* Backport some of the patches in `macports pypy`_ +* Add missing ``HAVE_FACCESSAT`` to ``posix._have_functions`` +* Update pyrepl from upstream package (`issue 2971`_) +* Fix ``PyFrame._guess_function_name_parens()`` +* Fix range of allowed years in ``time.mktime`` to match CPython `13312`_ +* Generators need to store the old current ``exc_info`` in a place that is + visible, because in one corner case a call to ``sys.exc_info()`` might need + it. (`issue 3096`_) +* Remove incorrect clobbering of the ``locals`` after running ``exec()`` +* Adds encoding, decoding codepages on win32 +* Remove socket error attributes from ``_ssl`` (`issue 3119`_) +* Add missing ``os.getgrouplist`` (part of `issue 2375`_) +* Back-port the tentative fix from cpython: "Import deadlock detection causes + deadlock" (part of `issue 3111`_) +* Fix handling of ``sys.exc_info()`` in generators +* Return ``W_IntObject`` when converting from ``float`` to ``int`` when + possible, which speeds up many code paths. + +Python 3.6 C-API +~~~~~~~~~~~~~~~~ + +* Add ``PyObject_GenericGetDict``, ``PyObject_GenericSetDict``, ``_Py_strhex``, + ``_Py_strhex_bytes``, ``PyUnicodeNew``, ``_PyFinalizing``, + ``PySlice_Unpack``, ``PySlice_AdjustIndices``, ``PyOS_FSPath`` +* Implement ``pystrhex.h`` (`issue 2687`_) +* Make ``PyUnicodeObject`` slightly more compact +* Fix memory leak when releasing a ``PyUnicodeObject`` + +.. _`revdb`: fix broken link +.. _`portable pypy`: fix broken link +.. _`manylinux2010`: fix broken link +.. _`macports pypy`: https://github.com/macports/macports-ports/blob/master/lang/pypy/files/darwin.py.diff + +.. _`issue 2375`: https://bitbucket.com/pypy/pypy/issues/2375 +.. _`issue 2389`: https://bitbucket.com/pypy/pypy/issues/2389 +.. _`issue 2687`: https://bitbucket.com/pypy/pypy/issues/2687 +.. _`issue 2970`: https://bitbucket.com/pypy/pypy/issues/2970 +.. _`issue 2971`: https://bitbucket.com/pypy/pypy/issues/2971 +.. _`issue 3084`: https://bitbucket.com/pypy/pypy/issues/3084 +.. _`issue 3086`: https://bitbucket.com/pypy/pypy/issues/3086 +.. _`issue 3088`: https://bitbucket.com/pypy/pypy/issues/3088 +.. _`issue 3090`: https://bitbucket.com/pypy/pypy/issues/3090 +.. _`issue 3094`: https://bitbucket.com/pypy/pypy/issues/3094 +.. _`issue 3096`: https://bitbucket.com/pypy/pypy/issues/3096 +.. _`issue 3097`: https://bitbucket.com/pypy/pypy/issues/3097 +.. _`issue 3098`: https://bitbucket.com/pypy/pypy/issues/3098 +.. _`issue 3099`: https://bitbucket.com/pypy/pypy/issues/3099 +.. _`issue 3100`: https://bitbucket.com/pypy/pypy/issues/3100 +.. _`issue 3108`: https://bitbucket.com/pypy/pypy/issues/3108 +.. _`issue 3109`: https://bitbucket.com/pypy/pypy/issues/3109 +.. _`issue 3111`: https://bitbucket.com/pypy/pypy/issues/3111 +.. _`issue 3112`: https://bitbucket.com/pypy/pypy/issues/3112 +.. _`issue 3114`: https://bitbucket.com/pypy/pypy/issues/3114 +.. _`issue 3117`: https://bitbucket.com/pypy/pypy/issues/3117 +.. _`issue 3119`: https://bitbucket.com/pypy/pypy/issues/3119 +.. _`issue 3120`: https://bitbucket.com/pypy/pypy/issues/3120 + +.. _13312: https://bugs.python.org/issue13312 +.. _13617: https://bugs.python.org/issue13617 +.. _29990: https://bugs.python.org/issue29990 +.. _30003: https://bugs.python.org/issue30003 +.. _37579: https://bugs.python.org/issue37579 +.. _37985: https://bugs.python.org/issue37985 +.. _37985: https://bugs.python.org/issue37985 + + 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 @@ -1,22 +1,7 @@ -========================== -What's new in PyPy2.7 7.3+ -========================== +============================ +What's new in PyPy2.7 7.3.0+ +============================ -.. this is a revision shortly after release-pypy-7.2.0 -.. startrev: a511d86377d6 +.. this is a revision shortly after release-pypy-7.3.0 +.. startrev: 994c42529580 -.. branch: fix-descrmismatch-crash - -Fix segfault when calling descr-methods with no arguments - -.. branch: https-readme - -Convert http -> https in README.rst - -.. branch: license-update - -Update list directories in LICENSE - -.. branch: allow-forcing-no-embed - -When packaging, allow suppressing embedded dependencies via PYPY_NO_EMBED_DEPENDENCIES diff --git a/pypy/doc/whatsnew-head.rst b/pypy/doc/whatsnew-pypy2-7.3.0.rst copy from pypy/doc/whatsnew-head.rst copy to pypy/doc/whatsnew-pypy2-7.3.0.rst --- a/pypy/doc/whatsnew-head.rst +++ b/pypy/doc/whatsnew-pypy2-7.3.0.rst @@ -1,6 +1,6 @@ -========================== -What's new in PyPy2.7 7.3+ -========================== +=========================== +What's new in PyPy2.7 7.3.0 +=========================== .. this is a revision shortly after release-pypy-7.2.0 .. startrev: a511d86377d6 @@ -19,4 +19,23 @@ .. branch: allow-forcing-no-embed -When packaging, allow suppressing embedded dependencies via PYPY_NO_EMBED_DEPENDENCIES +When packaging, allow suppressing embedded dependencies via +PYPY_NO_EMBED_DEPENDENCIES + +.. branch: int-test-is-zero + +.. branch: cppyy-dev + +Upgraded the built-in ``_cppyy`` module to ``cppyy-backend 1.10.6``, which +provides, among others, better template resolution, stricter ``enum`` handling, +anonymous struct/unions, cmake fragments for distribution, optimizations for +PODs, and faster wrapper calls. + +.. branch: backport-decode_timeval_ns-py3.7 + +Backport ``rtime.decode_timeval_ns`` from py3.7 to rpython + +.. branch: kill-asmgcc + +Completely remove the deprecated translation option ``--gcrootfinder=asmgcc`` +because it no longer works with a recent enough ``gcc``. diff --git a/pypy/doc/whatsnew-pypy3-head.rst b/pypy/doc/whatsnew-pypy3-7.3.0.rst copy from pypy/doc/whatsnew-pypy3-head.rst copy to pypy/doc/whatsnew-pypy3-7.3.0.rst --- a/pypy/doc/whatsnew-pypy3-head.rst +++ b/pypy/doc/whatsnew-pypy3-7.3.0.rst @@ -1,6 +1,6 @@ -======================== -What's new in PyPy3 7.2+ -======================== +========================= +What's new in PyPy3 7.3.0 +========================= .. this is the revision after release-pypy3.6-v7.2 .. startrev: 6d2f8470165b @@ -9,3 +9,16 @@ .. branch: py3.6-asyncgen Fix asyncgen_hooks and refactor coroutine execution + +.. branch: py3.6-exc-info + +Follow CPython's use of exc_info more closely (issue 3096) + +.. branch: code_page-utf8 + +Add encoding, decoding of codepages on windows + +.. branch: py3.6-exc-info-2 + +Fix handling of sys.exc_info() in generators + diff --git a/pypy/doc/whatsnew-pypy3-head.rst b/pypy/doc/whatsnew-pypy3-head.rst --- a/pypy/doc/whatsnew-pypy3-head.rst +++ b/pypy/doc/whatsnew-pypy3-head.rst @@ -1,11 +1,7 @@ -======================== -What's new in PyPy3 7.2+ -======================== +========================== +What's new in PyPy3 7.3.0+ +========================== -.. this is the revision after release-pypy3.6-v7.2 -.. startrev: 6d2f8470165b +.. this is the revision after release-pypy3.6-v7.3.0 +.. startrev: a56889d5df88 - -.. branch: py3.6-asyncgen - -Fix asyncgen_hooks and refactor coroutine execution diff --git a/pypy/doc/windows.rst b/pypy/doc/windows.rst --- a/pypy/doc/windows.rst +++ b/pypy/doc/windows.rst @@ -155,7 +155,7 @@ the `get_externals.py` utility to checkout the proper branch for your platform and PyPy version. -.. _subrepository: https://bitbucket.org/pypy/external +.. _subrepository: https://bitbucket.org/pypy/externals Using the mingw compiler ------------------------ diff --git a/pypy/interpreter/app_main.py b/pypy/interpreter/app_main.py --- a/pypy/interpreter/app_main.py +++ b/pypy/interpreter/app_main.py @@ -736,7 +736,15 @@ filename = sys.argv[0] mainmodule.__file__ = filename mainmodule.__cached__ = None - if not isolated: + for hook in sys.path_hooks: + try: + importer = hook(filename) + break + except ImportError: + continue + else: + importer = None + if importer is None and not isolated: sys.path.insert(0, sys.pypy_resolvedirof(filename)) # assume it's a pyc file only if its name says so. # CPython goes to great lengths to detect other cases @@ -772,18 +780,13 @@ args = (execfile, filename, mainmodule.__dict__) else: filename = sys.argv[0] - for hook in sys.path_hooks: - try: - importer = hook(filename) - except ImportError: - continue + if importer is not None: # It's the name of a directory or a zip file. # put the filename in sys.path[0] and import # the module __main__ import runpy sys.path.insert(0, filename) args = (runpy._run_module_as_main, '__main__', False) - break else: # That's the normal path, "pypy3 stuff.py". # We don't actually load via SourceFileLoader diff --git a/pypy/interpreter/astcompiler/astbuilder.py b/pypy/interpreter/astcompiler/astbuilder.py --- a/pypy/interpreter/astcompiler/astbuilder.py +++ b/pypy/interpreter/astcompiler/astbuilder.py @@ -497,10 +497,10 @@ def handle_async_funcdef(self, node, decorators=None): return self.handle_funcdef_impl(node.get_child(1), 1, decorators) - + def handle_funcdef(self, node, decorators=None): return self.handle_funcdef_impl(node, 0, decorators) - + def handle_async_stmt(self, node): ch = node.get_child(1) if ch.type == syms.funcdef: @@ -942,7 +942,7 @@ if flufl and comp_node.get_value() == '!=': self.error("with Barry as BDFL, use '<>' instead of '!='", comp_node) elif not flufl and comp_node.get_value() == '<>': - self.error('invalid comparison', comp_node) + self.error('invalid syntax', comp_node) return ast.NotEq elif comp_type == tokens.NAME: if comp_node.get_value() == "is": @@ -1014,7 +1014,7 @@ atom_node.get_column()) else: return atom_expr - + def handle_power(self, power_node): atom_expr = self.handle_atom_expr(power_node.get_child(0)) if power_node.num_children() == 1: @@ -1092,7 +1092,7 @@ def handle_call(self, args_node, callable_expr): arg_count = 0 # position args + iterable args unpackings keyword_count = 0 # keyword args + keyword args unpackings - generator_count = 0 + generator_count = 0 for i in range(args_node.num_children()): argument = args_node.get_child(i) if argument.type == syms.argument: @@ -1300,7 +1300,6 @@ if is_dict: raise self.error("dict unpacking cannot be used in " "dict comprehension", atom_node) - return self.handle_dictcomp(maker, atom_node) else: # a dictionary display @@ -1423,7 +1422,7 @@ comps = self.comprehension_helper(dict_maker.get_child(i)) return ast.DictComp(key, value, comps, atom_node.get_lineno(), atom_node.get_column()) - + def handle_dictdisplay(self, node, atom_node): keys = [] values = [] @@ -1435,7 +1434,7 @@ i += 1 return ast.Dict(keys, values, atom_node.get_lineno(), atom_node.get_column()) - + def handle_setdisplay(self, node, atom_node): elts = [] i = 0 diff --git a/pypy/interpreter/astcompiler/codegen.py b/pypy/interpreter/astcompiler/codegen.py --- a/pypy/interpreter/astcompiler/codegen.py +++ b/pypy/interpreter/astcompiler/codegen.py @@ -393,6 +393,14 @@ self.emit_op_arg(ops.BUILD_CONST_KEY_MAP, l) return l + def _visit_defaults(self, defaults): + w_tup = self._tuple_of_consts(defaults) + if w_tup: + self.load_const(w_tup) + else: + self.visit_sequence(defaults) + self.emit_op_arg(ops.BUILD_TUPLE, len(defaults)) + @specialize.arg(2) def _visit_function(self, func, function_code_generator): self.update_position(func.lineno, True) @@ -403,11 +411,10 @@ assert isinstance(args, ast.arguments) oparg = 0 - self.visit_sequence(args.defaults) if args.defaults is not None and len(args.defaults): oparg = oparg | 0x01 - self.emit_op_arg(ops.BUILD_TUPLE, len(args.defaults)) + self._visit_defaults(args.defaults) if args.kwonlyargs: kw_default_count = self._visit_kwonlydefaults(args) @@ -438,12 +445,10 @@ args = lam.args assert isinstance(args, ast.arguments) - self.visit_sequence(args.defaults) - oparg = 0 if args.defaults is not None and len(args.defaults): oparg = oparg | 0x01 - self.emit_op_arg(ops.BUILD_TUPLE, len(args.defaults)) + self._visit_defaults(args.defaults) if args.kwonlyargs: kw_default_count = self._visit_kwonlydefaults(args) @@ -1003,11 +1008,12 @@ attr = target.value self._annotation_evaluate(attr) elif isinstance(target, ast.Subscript): - # similar to the above, `a[0:5]: int` evaluates the name and the slice argument - # and if not in a function, also evaluates the annotation - sl = target.slice - self._annotation_evaluate(target.value) - self._annotation_eval_slice(sl) + if not assign.value: + # similar to the above, `a[0:5]: int` evaluates the name and the slice argument + # and if not in a function, also evaluates the annotation + sl = target.slice + self._annotation_evaluate(target.value) + self._annotation_eval_slice(sl) else: self.error("can't handle annotation with %s" % (target,), target) # if this is not in a function, evaluate the annotation diff --git a/pypy/interpreter/astcompiler/test/apptest_misc.py b/pypy/interpreter/astcompiler/test/apptest_misc.py new file mode 100644 _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit