Commit 59ace917 authored by Matti Picus's avatar Matti Picus
Browse files

merge py3.9 into release

--HG--
branch : release-pypy3.9-v7.x
Pipeline #60182 passed with stage
in 5 minutes and 22 seconds
......@@ -19,6 +19,18 @@ from site import USER_BASE
from site import USER_SITE
HAS_USER_SITE = True
# See also: site.py/sysconfig.py
def _get_implementation():
if '__pypy__' in sys.builtin_module_names:
return 'PyPy'
return 'Python'
IMPLEMENTATION = _get_implementation()
IMPLEMENTATION_LOWER = IMPLEMENTATION.lower()
WINDOWS_SCHEME = {
'purelib': '$base/Lib/site-packages',
'platlib': '$base/Lib/site-packages',
......@@ -29,16 +41,16 @@ WINDOWS_SCHEME = {
INSTALL_SCHEMES = {
'unix_prefix': {
'purelib': '$base/lib/$implementation_lower$py_version_short/site-packages',
'platlib': '$platbase/$platlibdir/$implementation_lower$py_version_short/site-packages',
'headers': '$base/include/$implementation_lower$py_version_short$abiflags/$dist_name',
'purelib': '$base/lib/' + IMPLEMENTATION_LOWER + '$py_version_short/site-packages',
'platlib': '$platbase/$platlibdir/' + IMPLEMENTATION_LOWER + '$py_version_short/site-packages',
'headers': '$base/include/' + IMPLEMENTATION_LOWER + '$py_version_short$abiflags/$dist_name',
'scripts': '$base/bin',
'data' : '$base',
},
'unix_home': {
'purelib': '$base/lib/$implementation_lower',
'platlib': '$base/$platlibdir/$implementation_lower',
'headers': '$base/include/$implementation_lower/$dist_name',
'purelib': '$base/lib/' + IMPLEMENTATION_LOWER,
'platlib': '$base/$platlibdir/' + IMPLEMENTATION_LOWER,
'headers': '$base/include/' + IMPLEMENTATION_LOWER + '/$dist_name',
'scripts': '$base/bin',
'data' : '$base',
},
......@@ -50,8 +62,8 @@ if HAS_USER_SITE:
INSTALL_SCHEMES['nt_user'] = {
'purelib': '$usersite',
'platlib': '$usersite',
'headers': '$userbase/$implementation$py_version_nodot/Include/$dist_name',
'scripts': '$userbase/$implementation$py_version_nodot/Scripts',
'headers': '$userbase/' + IMPLEMENTATION + '$py_version_nodot/Include/$dist_name',
'scripts': '$userbase/' + IMPLEMENTATION + '$py_version_nodot/Scripts',
'data' : '$userbase',
}
......@@ -59,7 +71,7 @@ if HAS_USER_SITE:
'purelib': '$usersite',
'platlib': '$usersite',
'headers':
'$userbase/include/$implementation_lower$py_version_short$abiflags/$dist_name',
'$userbase/include/' + IMPLEMENTATION_LOWER + '$py_version_short$abiflags/$dist_name',
'scripts': '$userbase/bin',
'data' : '$userbase',
}
......@@ -304,8 +316,6 @@ class install(Command):
'exec_prefix': exec_prefix,
'abiflags': abiflags,
'platlibdir': sys.platlibdir,
'implementation_lower': _get_implementation().lower(),
'implementation': _get_implementation(),
}
if HAS_USER_SITE:
......
......@@ -66,16 +66,16 @@ class Get_argspecTest(unittest.TestCase):
f'(iterable=(), /)'
f'\n{List.__doc__}')
tiptest(list.__new__,
'(*args, **kwargs)\n'
'(listtype, *args, **keywords)\n'
'Create and return a new object. '
'See help(type) for accurate signature.')
tiptest(list.__init__,
'(self, /, *args, **kwargs)\n'
'(self, *args, **keywords)\n'
'Initialize self. See help(type(self)) for accurate signature.')
append_doc = "\nAppend object to the end of the list."
tiptest(list.append, '(self, object, /)' + append_doc)
tiptest(List.append, '(self, object, /)' + append_doc)
tiptest([].append, '(object, /)' + append_doc)
tiptest(list.append, '(self, item)' + append_doc)
tiptest(List.append, '(self, item)' + append_doc)
tiptest([].append, '(item)' + append_doc)
tiptest(types.MethodType, "instancemethod(function, instance, class)")
tiptest(SB(), default_tip)
......
......@@ -393,9 +393,8 @@ def setcopyright():
builtins.copyright = _sitebuiltins._Printer("copyright", sys.copyright)
licenseargs = None
if is_pypy:
credits = "PyPy is maintained by the PyPy developers: http://pypy.org/"
credits = "PyPy is maintained by the PyPy developers\nhttp://pypy.org/"
license = "See https://foss.heptapod.net/pypy/pypy/src/default/LICENSE"
licenseargs = (license,)
elif sys.platform[:4] == 'java':
credits = ("Jython is maintained by the Jython developers "
"(www.jython.org).")
......
......@@ -66,7 +66,6 @@ ffi = build_ffi_for_binding(
"bignum",
"bio",
"cmac",
"conf",
"crypto",
"ct",
"dh",
......
......@@ -45,7 +45,7 @@ FUNCTIONS = """
void ASN1_OBJECT_free(ASN1_OBJECT *);
/* ASN1 STRING */
unsigned char *ASN1_STRING_data(ASN1_STRING *);
const unsigned char *ASN1_STRING_get0_data(ASN1_STRING *);
int ASN1_STRING_set(ASN1_STRING *, const void *, int);
/* ASN1 OCTET STRING */
......
# This file is dual licensed under the terms of the Apache License, Version
# 2.0, and the BSD License. See the LICENSE file in the root of this repository
# for complete details.
from __future__ import absolute_import, division, print_function
INCLUDES = """
#include <openssl/conf.h>
"""
TYPES = """
"""
FUNCTIONS = """
void OPENSSL_config(const char *);
/* This is a macro in 1.1.0 */
void OPENSSL_no_config(void);
"""
CUSTOMIZATIONS = """
"""
......@@ -225,8 +225,6 @@ int sk_X509_CRL_push(Cryptography_STACK_OF_X509_CRL *, X509_CRL *);
X509_CRL *sk_X509_CRL_value(Cryptography_STACK_OF_X509_CRL *, int);
long X509_CRL_get_version(X509_CRL *);
ASN1_TIME *X509_CRL_get_lastUpdate(X509_CRL *);
ASN1_TIME *X509_CRL_get_nextUpdate(X509_CRL *);
X509_NAME *X509_CRL_get_issuer(X509_CRL *);
Cryptography_STACK_OF_X509_REVOKED *X509_CRL_get_REVOKED(X509_CRL *);
......
......@@ -88,6 +88,9 @@ def extra_link_args(compiler_type):
# default on Python 3.3+ but not on 2.x.
return ['/NXCOMPAT', '/DYNAMICBASE']
else:
# The PyPy buildbots install OpenSSL to /usr/local/lib
if os.path.exists("/usr/local/lib"):
return["-L/usr/local/lib"]
return []
......
......@@ -432,7 +432,7 @@ class _SSLSocket(object):
raise ssl_error(None)
else:
if not lib.X509_VERIFY_PARAM_set1_ip(
param, lib.ASN1_STRING_data(ip), lib.ASN1_STRING_length(ip)):
param, lib.ASN1_STRING_get0_data(ip), lib.ASN1_STRING_length(ip)):
raise ssl_error(None)
@property
......
......@@ -3,9 +3,9 @@ from _pypy_openssl import ffi
from _pypy_openssl import lib
def _string_from_asn1(asn1):
data = lib.ASN1_STRING_data(asn1)
data = lib.ASN1_STRING_get0_data(asn1)
length = lib.ASN1_STRING_length(asn1)
return _str_with_len(ffi.cast("char*",data), length)
return _str_with_len(ffi.cast("const char*",data), length)
def _str_with_len(char_ptr, length):
return ffi.buffer(char_ptr, length)[:].decode('utf-8').strip('\n')
......
......@@ -25,7 +25,6 @@ ffi = build_ffi_for_binding(
"bignum",
"bio",
"cmac",
"conf",
"crypto",
"ct",
"dh",
......
......@@ -510,12 +510,11 @@ class TkApp(object):
def getboolean(self, s):
if isinstance(s, int):
return bool(s)
try:
s = s.encode('utf-8')
except AttributeError:
raise TypeError
if b'\x00' in s:
if isinstance(s, Tcl_Obj):
s = s.string
if '\x00' in s:
raise TypeError
s = s.encode('utf-8')
v = tkffi.new("int*")
res = tklib.Tcl_GetBoolean(self.interp, s, v)
if res == tklib.TCL_ERROR:
......@@ -525,12 +524,11 @@ class TkApp(object):
def getint(self, s):
if isinstance(s, int):
return s
try:
s = s.encode('utf-8')
except AttributeError:
raise TypeError
if b'\x00' in s:
if isinstance(s, Tcl_Obj):
s = s.string
if '\x00' in s:
raise TypeError
s = s.encode('utf-8')
if tklib.HAVE_LIBTOMMATH or tklib.HAVE_WIDE_INT_TYPE:
value = tklib.Tcl_NewStringObj(s, -1)
if not value:
......@@ -552,12 +550,11 @@ class TkApp(object):
def getdouble(self, s):
if isinstance(s, (float, int)):
return float(s)
try:
s = s.encode('utf-8')
except AttributeError:
raise TypeError
if b'\x00' in s:
if isinstance(s, Tcl_Obj):
s = s.string
if '\x00' in s:
raise TypeError
s = s.encode('utf-8')
v = tkffi.new("double*")
res = tklib.Tcl_GetDouble(self.interp, s, v)
if res == tklib.TCL_ERROR:
......
......@@ -3,7 +3,7 @@ PyPy v7.3.11: release of python 2.7, 3.8, and 3.9
=================================================
..
Changelog up to commit 46a7476ee4c3
Changelog up to commit 207858e40e63
.. note::
This is a pre-release announcement. When the release actually happens, it
......@@ -114,6 +114,9 @@ Bugfixes
- Package tkinter for macOS. Previously the portable builds did not include it
(issues 3760_, 3868_).
- Fix memory leak in certificate validation in ``_ssl`` (issue 3871_)
- Add ``__qualname__`` to some cpyext types (issue 3878_)
- Clean up some deprecated functions in OpenSSL wrapper ``_ssl``
Speedups and enhancements
~~~~~~~~~~~~~~~~~~~~~~~~~
......@@ -127,14 +130,24 @@ Python 3.8+
some security fixes, as documented in the `CPython release note`_
- Ensure that only valid values are passed from ``Py_UNICODE_*`` calls to
unicodedb lookups (issue 3870_)
- Fix ast ``lineno``, ``end_lineno``, ``end_col_number`` around decorators (issue 3876_)
- Re-apply fix for issue 3436_ since our ensurepip setuptools version is ``< 59.0``
- In ``_tkinter``, ``getboolean``, ``getint``, ``getdouble`` accepts a ``Tcl_Obj`` (bpo-23880_)
- Make builtin ``credits``, ``license()`` more like CPython
- Add docstrings to some builtin classes and methods
Python 3.9
----------
- Fix pure-python implmentation of ``functools`` (issue 3869_). see also cpython GH-100242_
- Remove ``type.__ne__``, the inherited behaviour from ``object.__ne__`` is the
correct one (issue 3879_)
- Fix invalid parsing rule for ``genexps`` as the non-singular argument in a call (issue 3873_)
.. _`using SMT solvers and fuzzing`: https://www.pypy.org/posts/2022/12/jit-bug-finding-smt-fuzzing.html
.. _`CPython release note`: https://www.python.org/downloads/release/python-3816
.. _bpo-23880: https://bugs.python.org/issue23880
.. _GH-100242: https://github.com/python/cpython/issues/100242
.. _3436: https://foss.heptapod.net/pypy/pypy/-/issues/3436
.. _3760: https://foss.heptapod.net/pypy/pypy/-/issues/3760
.. _3832: https://foss.heptapod.net/pypy/pypy/-/issues/3832
.. _3865: https://foss.heptapod.net/pypy/pypy/-/issues/3865
......@@ -142,3 +155,6 @@ Python 3.9
.. _3869: https://foss.heptapod.net/pypy/pypy/-/issues/3869
.. _3870: https://foss.heptapod.net/pypy/pypy/-/issues/3870
.. _3871: https://foss.heptapod.net/pypy/pypy/-/issues/3871
.. _3873: https://foss.heptapod.net/pypy/pypy/-/issues/3873
.. _3876: https://foss.heptapod.net/pypy/pypy/-/issues/3876
.. _3879: https://foss.heptapod.net/pypy/pypy/-/issues/3879
......@@ -2080,18 +2080,6 @@ x = [c for c in buggy_lnotab.__code__.co_lnotab]
"""
self.st(func, "x", [0, 1, 8, 8])
def test_lineno_funcdef(self):
func = '''def f():
@decorator
def my_function(
x=x
):
pass
x = [c for c in f.__code__.co_lnotab]
'''
# XXX: 3.7 value, CPython 3.8 has [0, 1, 2, 2, 2, 255]
self.st(func, 'x', [0, 1, 2, 2])
def test_lnotab_backwards_in_expr(self):
func = """
def expr_lines(x):
......
......@@ -874,6 +874,22 @@ class Parser:
'expression cannot contain assignment, perhaps you meant "=="?', a, b,
)
def get_last_comprehension_item(self, comp):
assert isinstance(comp, ast.comprehension)
if comp.ifs:
return comp.ifs[-1]
else:
return comp.iter
def check_nonparen_genexp_in_call(self, msg, a, b):
assert isinstance(a, ast.Call)
if len(a.args) > 1:
self.raise_syntax_error_known_range(
msg,
a.args[-1],
self.get_last_comprehension_item(b[-1]))
return None
def revdbmetavar(self, num, lineno, col_offset, end_lineno, end_col_offset):
if not self.space.config.translation.reverse_debugger:
self._raise_syntax_error("Unkown character", lineno, col_offset, end_lineno, end_col_offset)
......
......@@ -3586,9 +3586,9 @@ class PythonParser(Parser):
self._index = mark
a = self.args()
if a:
for_if_clauses = self.for_if_clauses()
if for_if_clauses:
return self . raise_syntax_error_starting_from ( "Generator expression must be parenthesized" , a . keywords [- 1] if a . keywords else a . args [- 1] )
b = self.for_if_clauses()
if b:
return self . check_nonparen_genexp_in_call ( "Generator expression must be parenthesized" , a , b )
self._index = mark
args = self.args()
if args:
......
......@@ -520,3 +520,20 @@ class TestPythonPegParser(TestPythonParser):
self.parse(
"if 1: \n pass", "exec",
flags=consts.PyCF_DONT_IMPLY_DEDENT)
def test_nonparen_genexp_in_call(self):
with py.test.raises(SyntaxError) as info:
self.parse("""\
f(x for x in l)
if 1:
pass
""")
assert info.value.msg == "expected an indented block after 'if' statement on line 2"
with py.test.raises(SyntaxError) as info:
self.parse("""f(1, x for x in y for z in a if
b)""")
assert info.value.msg == 'Generator expression must be parenthesized'
assert info.value.lineno == 1
assert info.value.offset == 6
assert info.value.lastlineno == 3
......@@ -1165,11 +1165,10 @@ invalid_arguments[NoReturn]:
"invalid syntax. Maybe you meant '==' or ':=' instead of '='?", a, b
)
}
| a=args for_if_clauses {
self.raise_syntax_error_starting_from(
| a=args b=for_if_clauses {
self.check_nonparen_genexp_in_call(
"Generator expression must be parenthesized",
a.keywords[-1] if a.keywords else a.args[-1]
)
a, b)
}
| args ',' a=expression b=for_if_clauses {
self.raise_syntax_error_known_range(
......
......@@ -326,10 +326,23 @@ def _make_enumerate(space, w_iter_or_list, w_index):
return W_Enumerate(w_iter_or_list, index, w_index)
W_Enumerate.typedef = TypeDef("enumerate",
__new__=interp2app(W_Enumerate.descr___new__),
__iter__=interp2app(W_Enumerate.descr___iter__),
__next__=interp2app(W_Enumerate.descr_next),
__reduce__=interp2app(W_Enumerate.descr___reduce__),
__doc__ = """\
Return an enumerate object.
iterable
an object supporting iteration
The enumerate object yields pairs containing a count (from start, which
defaults to zero) and a value yielded by the iterable argument.
enumerate is useful for obtaining an indexed list:
(0, seq[0]), (1, seq[1]), (2, seq[2]), ...""",
_text_signature_ = "(iterable, start=0)",
__new__ = interp2app(W_Enumerate.descr___new__),
__iter__ = interp2app(W_Enumerate.descr___iter__),
__next__ = interp2app(W_Enumerate.descr_next),
__reduce__ = interp2app(W_Enumerate.descr___reduce__),
__class_getitem__ = interp2app(
generic_alias_class_getitem, as_classmethod=True),
)
......@@ -412,6 +425,9 @@ class W_ReversedIterator(W_Root):
self.remaining = n - 1
W_ReversedIterator.typedef = TypeDef("reversed",
__doc__ = """\
Return a reverse iterator over the values of the given sequence.""",
_text_signature_ = "(sequence, /)",
__new__ = interp2app(W_ReversedIterator.descr___new__2),
__iter__ = interp2app(W_ReversedIterator.descr___iter__),
__length_hint__ = interp2app(W_ReversedIterator.descr_length_hint),
......@@ -607,6 +623,14 @@ class W_Range(W_Root):
return space.nonzero(self.w_length)
W_Range.typedef = TypeDef("range",
__doc__ = """range(stop) -> range object
range(start, stop[, step]) -> range object
Return an object that produces a sequence of integers from start (inclusive)
to stop (exclusive) by step. range(i, j) produces i, i+1, i+2, ..., j-1.
start defaults to 0, and stop is omitted! range(4) produces 0, 1, 2, 3.
These are exactly the valid indices for a list of 4 elements.
When step is given, it specifies the increment (or decrement).""",
__new__ = interp2app(W_Range.descr_new.im_func),
__repr__ = interp2app(W_Range.descr_repr),
__getitem__ = interp2app(W_Range.descr_getitem),
......@@ -877,6 +901,8 @@ W_Map.typedef = TypeDef(
__next__ = interp2app(W_Map.next_w),
__reduce__ = interp2app(W_Map.descr_reduce),
__doc__ = """\
map(func, *iterables) --> map object
Make an iterator that computes the function using arguments from
each of the iterables. Stops when the shortest iterable is exhausted.""")
......@@ -956,6 +982,8 @@ W_Filter.typedef = TypeDef(
__next__ = interp2app(W_Filter.next_w),
__reduce__ = interp2app(W_Filter.descr_reduce),
__doc__ = """\
filter(function or None, iterable) --> filter object
Return an iterator yielding those items of iterable for which function(item)
is true. If function is None, return the items that are true.""")
......@@ -1057,9 +1085,12 @@ W_Zip.typedef = TypeDef(
__next__ = interp2app(W_Zip.next_w),
__reduce__ = interp2app(W_Zip.descr_reduce),
__doc__ = """\
Return a zip object whose .__next__() method returns a tuple where
the i-th element comes from the i-th iterable argument. The .__next__()
method continues until the shortest iterable in the argument sequence
is exhausted and then it raises StopIteration.""")
zip(*iterables) --> A zip object yielding tuples until an input is exhausted.
>>> list(zip('abcdefg', range(3), range(4)))
[('a', 0, 0), ('b', 1, 1), ('c', 2, 2)]
The zip object yields n-length tuples, where n is the number of iterables
passed as positional arguments to zip(). The i-th element in every tuple
comes from the i-th iterable argument to zip(). This continues until the
shortest argument is exhausted.""")
......@@ -303,22 +303,28 @@ class W_SRE_Pattern(W_Root):
@unwrap_spec(pos=int, endpos=int)
def match_w(self, w_string, pos=0, endpos=sys.maxint):
"""Matches zero or more characters at the beginning of the string."""
ctx = self.make_ctx(w_string, pos, endpos)
return self.getmatch(ctx, matchcontext(self.space, ctx, self.code))
@unwrap_spec(pos=int, endpos=int)
def fullmatch_w(self, w_string, pos=0, endpos=sys.maxint):
"""Matches against all of the string."""
ctx = self.make_ctx(w_string, pos, endpos)
ctx.match_mode = rsre_core.MODE_FULL
return self.getmatch(ctx, matchcontext(self.space, ctx, self.code))
@unwrap_spec(pos=int, endpos=int)
def search_w(self, w_string, pos=0, endpos=sys.maxint):
"""Scan through string looking for a match, and return a corresponding match object instance.
Return None if no position in the string matches."""
ctx = self.make_ctx(w_string, pos, endpos)
return self.getmatch(ctx, searchcontext(self.space, ctx, self.code))
@unwrap_spec(pos=int, endpos=int)
def findall_w(self, w_string, pos=0, endpos=sys.maxint):
"""Return a list of all non-overlapping matches of pattern in string."""
space = self.space
matchlist_w = []
ctx = self.make_ctx(w_string, pos, endpos)
......@@ -344,6 +350,9 @@ class W_SRE_Pattern(W_Root):
@unwrap_spec(pos=int, endpos=int)
def finditer_w(self, w_string, pos=0, endpos=sys.maxint):
"""Return an iterator over all non-overlapping matches for the RE pattern in string.
For each match, the iterator returns a match object."""
# this also works as the implementation of the undocumented
# scanner() method.
ctx = self.make_ctx(w_string, pos, endpos)
......@@ -352,6 +361,7 @@ class W_SRE_Pattern(W_Root):
@unwrap_spec(maxsplit=int)
def split_w(self, w_string, maxsplit=0):
"""Split string by the occurrences of pattern."""
space = self.space
#
splitlist = []
......@@ -381,11 +391,13 @@ class W_SRE_Pattern(W_Root):
@unwrap_spec(count=int)
def sub_w(self, w_repl, w_string, count=0):
"""Return the string obtained by replacing the leftmost non-overlapping occurrences of pattern in string by the replacement repl."""
w_item, n = self.subx(w_repl, w_string, count)
return w_item
@unwrap_spec(count=int)
def subn_w(self, w_repl, w_string, count=0):
"""Return the tuple (new_string, number_of_subs_made) found by replacing the leftmost non-overlapping occurrences of pattern with the replacement repl."""
w_item, n = self.subx(w_repl, w_string, count)
space = self.space
return space.newtuple2(w_item, space.newint(n))
......@@ -612,6 +624,7 @@ def SRE_Pattern__new__(space, w_subtype, w_pattern, flags, w_code,
W_SRE_Pattern.typedef = TypeDef(
're.Pattern',
__doc__ = "Compiled regular expression object.",
__new__ = interp2app(SRE_Pattern__new__),
__copy__ = interp2app(W_SRE_Pattern.copy_identity_w),
__deepcopy__ = interp2app(W_SRE_Pattern.copy_identity_w),
......@@ -677,6 +690,9 @@ class W_SRE_Match(W_Root):
@jit.look_inside_iff(lambda self, args_w: jit.isconstant(len(args_w)))
def group_w(self, args_w):
"""group([group1, ...]) -> str or tuple.
Return subgroup(s) of the match by indices or names.
For 0 returns the entire match."""
space = self.space
ctx = self.ctx
if len(args_w) <= 1:
......@@ -847,6 +863,8 @@ class W_SRE_Match(W_Root):
W_SRE_Match.typedef = TypeDef(
're.Match',
__doc__ = """The result of re.match() and re.search().
Match objects always have a boolean value of True.""",
__copy__ = interp2app(W_SRE_Match.copy_identity_w),
__deepcopy__ = interp2app(W_SRE_Match.copy_identity_w),
__repr__ = interp2app(W_SRE_Match.repr_w),
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment