Skip to content

Commit 5b99059

Browse files
authored
Merge branch 'python:main' into faster_test_pegen
2 parents c4457db + a0e55a5 commit 5b99059

31 files changed

+260
-103
lines changed

Doc/whatsnew/3.11.rst

Lines changed: 20 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -759,12 +759,19 @@ Porting to Python 3.11
759759
which are not available in the limited C API.
760760
(Contributed by Victor Stinner in :issue:`46007`.)
761761

762-
* Changes of the :c:type:`PyFrameObject` structure members:
762+
* Changes of the private :c:type:`PyFrameObject` structure members.
763+
764+
While the documentation notes that the fields of ``PyFrameObject`` are
765+
subject to change at any time, they have been stable for a long time
766+
and were used in several popular extensions.
767+
In Python 3.11, the frame struct was reorganized to allow performance
768+
optimizations. Rather than reading the fields directly, extensions should
769+
use functions:
763770

764771
* ``f_code``: removed, use :c:func:`PyFrame_GetCode` instead.
765772
Warning: the function returns a :term:`strong reference`, need to call
766773
:c:func:`Py_DECREF`.
767-
* ``f_back``: changed, use :c:func:`PyFrame_GetBack`.
774+
* ``f_back``: changed (see below), use :c:func:`PyFrame_GetBack`.
768775
* ``f_builtins``: removed,
769776
use ``PyObject_GetAttrString(frame, "f_builtins")``.
770777
* ``f_globals``: removed,
@@ -773,13 +780,17 @@ Porting to Python 3.11
773780
use ``PyObject_GetAttrString(frame, "f_locals")``.
774781
* ``f_lasti``: removed,
775782
use ``PyObject_GetAttrString(frame, "f_lasti")``.
776-
* ``f_valuesstack``: removed.
777-
* ``f_stackdepth``: removed.
778-
* ``f_gen``: removed.
779-
* ``f_iblock``: removed.
780-
* ``f_state``: removed.
781-
* ``f_blockstack``: removed.
782-
* ``f_localsplus``: removed.
783+
784+
The following fields were removed entirely, as they were details
785+
of the old implementation:
786+
787+
* ``f_valuesstack``
788+
* ``f_stackdepth``
789+
* ``f_gen``
790+
* ``f_iblock``
791+
* ``f_state``
792+
* ``f_blockstack``
793+
* ``f_localsplus``
783794

784795
The Python frame object is now created lazily. A side effect is that the
785796
``f_back`` member must not be accessed directly, since its value is now also

Include/cpython/pystate.h

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -187,16 +187,19 @@ struct _ts {
187187
/* The following fields are here to avoid allocation during init.
188188
The data is exposed through PyThreadState pointer fields.
189189
These fields should not be accessed directly outside of init.
190+
This is indicated by an underscore prefix on the field names.
190191
191192
All other PyInterpreterState pointer fields are populated when
192193
needed and default to NULL.
193194
*/
195+
// Note some fields do not have a leading underscore for backward
196+
// compatibility. See https://bugs.python.org/issue45953#msg412046.
194197

195198
/* The thread's exception stack entry. (Always the last entry.) */
196-
_PyErr_StackItem _exc_state;
199+
_PyErr_StackItem exc_state;
197200

198201
/* The bottom-most frame on the stack. */
199-
CFrame _root_cframe;
202+
CFrame root_cframe;
200203
};
201204

202205

Include/internal/pycore_code.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -305,9 +305,19 @@ typedef struct _call_stats {
305305
uint64_t pyeval_calls;
306306
} CallStats;
307307

308+
typedef struct _object_stats {
309+
uint64_t allocations;
310+
uint64_t frees;
311+
uint64_t new_values;
312+
uint64_t dict_materialized_on_request;
313+
uint64_t dict_materialized_new_key;
314+
uint64_t dict_materialized_too_big;
315+
} ObjectStats;
316+
308317
typedef struct _stats {
309318
OpcodeStats opcode_stats[256];
310319
CallStats call_stats;
320+
ObjectStats object_stats;
311321
} PyStats;
312322

313323
extern PyStats _py_stats;
@@ -316,6 +326,7 @@ extern PyStats _py_stats;
316326
#define STAT_DEC(opname, name) _py_stats.opcode_stats[opname].specialization.name--
317327
#define OPCODE_EXE_INC(opname) _py_stats.opcode_stats[opname].execution_count++
318328
#define CALL_STAT_INC(name) _py_stats.call_stats.name++
329+
#define OBJECT_STAT_INC(name) _py_stats.object_stats.name++
319330

320331
void _Py_PrintSpecializationStats(int to_file);
321332

@@ -326,6 +337,7 @@ PyAPI_FUNC(PyObject*) _Py_GetSpecializationStats(void);
326337
#define STAT_DEC(opname, name) ((void)0)
327338
#define OPCODE_EXE_INC(opname) ((void)0)
328339
#define CALL_STAT_INC(name) ((void)0)
340+
#define OBJECT_STAT_INC(name) ((void)0)
329341
#endif
330342

331343

Lib/asyncio/sslproto.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -367,6 +367,12 @@ def get_write_buffer_size(self):
367367
"""Return the current size of the write buffer."""
368368
return self._ssl_protocol._transport.get_write_buffer_size()
369369

370+
def get_write_buffer_limits(self):
371+
"""Get the high and low watermarks for write flow control.
372+
Return a tuple (low, high) where low and high are
373+
positive number of bytes."""
374+
return self._ssl_protocol._transport.get_write_buffer_limits()
375+
370376
@property
371377
def _protocol_paused(self):
372378
# Required for sendfile fallback pause_writing/resume_writing logic

Lib/asyncio/transports.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,12 @@ def get_write_buffer_size(self):
9999
"""Return the current size of the write buffer."""
100100
raise NotImplementedError
101101

102+
def get_write_buffer_limits(self):
103+
"""Get the high and low watermarks for write flow control.
104+
Return a tuple (low, high) where low and high are
105+
positive number of bytes."""
106+
raise NotImplementedError
107+
102108
def write(self, data):
103109
"""Write some data bytes to the transport.
104110

Lib/ctypes/test/test_python_api.py

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
from ctypes import *
2-
import unittest, sys
2+
import unittest
33
from test import support
44

55
################################################################
@@ -10,18 +10,14 @@
1010
################################################################
1111

1212
from sys import getrefcount as grc
13-
if sys.version_info > (2, 4):
14-
c_py_ssize_t = c_size_t
15-
else:
16-
c_py_ssize_t = c_int
1713

1814
class PythonAPITestCase(unittest.TestCase):
1915

2016
def test_PyBytes_FromStringAndSize(self):
2117
PyBytes_FromStringAndSize = pythonapi.PyBytes_FromStringAndSize
2218

2319
PyBytes_FromStringAndSize.restype = py_object
24-
PyBytes_FromStringAndSize.argtypes = c_char_p, c_py_ssize_t
20+
PyBytes_FromStringAndSize.argtypes = c_char_p, c_size_t
2521

2622
self.assertEqual(PyBytes_FromStringAndSize(b"abcdefghi", 3), b"abc")
2723

Lib/lib2to3/pytree.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -720,8 +720,8 @@ def generate_matches(self, nodes):
720720
r[self.name] = nodes[:count]
721721
yield count, r
722722
except RuntimeError:
723-
# We fall back to the iterative pattern matching scheme if the recursive
724-
# scheme hits the recursion limit.
723+
# Fall back to the iterative pattern matching scheme if the
724+
# recursive scheme hits the recursion limit (RecursionError).
725725
for count, r in self._iterative_matches(nodes):
726726
if self.name:
727727
r[self.name] = nodes[:count]

Lib/lib2to3/tests/data/infinite_recursion.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
# This file is used to verify that 2to3 falls back to a slower, iterative pattern matching
2-
# scheme in the event that the faster recursive system fails due to infinite recursion.
1+
# Verify that 2to3 falls back from the recursive pattern matching scheme to a
2+
# slower, iterative scheme in the event of a RecursionError.
33
from ctypes import *
44
STRING = c_char_p
55

Lib/lib2to3/tests/test_all_fixers.py

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,10 @@
66
# Author: Collin Winter
77

88
# Python imports
9-
import unittest
9+
import os.path
10+
import sys
1011
import test.support
12+
import unittest
1113

1214
# Local imports
1315
from . import support
@@ -19,9 +21,22 @@ class Test_all(support.TestCase):
1921
def setUp(self):
2022
self.refactor = support.get_refactorer()
2123

24+
def refactor_file(self, filepath):
25+
if test.support.verbose:
26+
print(f"Refactor file: {filepath}")
27+
if os.path.basename(filepath) == 'infinite_recursion.py':
28+
# bpo-46542: Processing infinite_recursion.py can crash Python
29+
# if Python is built in debug mode: lower the recursion limit
30+
# to prevent a crash.
31+
with test.support.infinite_recursion(150):
32+
self.refactor.refactor_file(filepath)
33+
else:
34+
self.refactor.refactor_file(filepath)
35+
2236
def test_all_project_files(self):
2337
for filepath in support.all_project_files():
24-
self.refactor.refactor_file(filepath)
38+
with self.subTest(filepath=filepath):
39+
self.refactor_file(filepath)
2540

2641
if __name__ == '__main__':
2742
unittest.main()

Lib/lib2to3/tests/test_parser.py

Lines changed: 24 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
import subprocess
2121
import sys
2222
import tempfile
23+
import test.support
2324
import unittest
2425

2526
# Local imports
@@ -589,25 +590,31 @@ class TestParserIdempotency(support.TestCase):
589590

590591
"""A cut-down version of pytree_idempotency.py."""
591592

593+
def parse_file(self, filepath):
594+
if test.support.verbose:
595+
print(f"Parse file: {filepath}")
596+
with open(filepath, "rb") as fp:
597+
encoding = tokenize.detect_encoding(fp.readline)[0]
598+
self.assertIsNotNone(encoding,
599+
"can't detect encoding for %s" % filepath)
600+
with open(filepath, "r", encoding=encoding) as fp:
601+
source = fp.read()
602+
try:
603+
tree = driver.parse_string(source)
604+
except ParseError:
605+
try:
606+
tree = driver_no_print_statement.parse_string(source)
607+
except ParseError as err:
608+
self.fail('ParseError on file %s (%s)' % (filepath, err))
609+
new = str(tree)
610+
if new != source:
611+
print(diff_texts(source, new, filepath))
612+
self.fail("Idempotency failed: %s" % filepath)
613+
592614
def test_all_project_files(self):
593615
for filepath in support.all_project_files():
594-
with open(filepath, "rb") as fp:
595-
encoding = tokenize.detect_encoding(fp.readline)[0]
596-
self.assertIsNotNone(encoding,
597-
"can't detect encoding for %s" % filepath)
598-
with open(filepath, "r", encoding=encoding) as fp:
599-
source = fp.read()
600-
try:
601-
tree = driver.parse_string(source)
602-
except ParseError:
603-
try:
604-
tree = driver_no_print_statement.parse_string(source)
605-
except ParseError as err:
606-
self.fail('ParseError on file %s (%s)' % (filepath, err))
607-
new = str(tree)
608-
if new != source:
609-
print(diff_texts(source, new, filepath))
610-
self.fail("Idempotency failed: %s" % filepath)
616+
with self.subTest(filepath=filepath):
617+
self.parse_file(filepath)
611618

612619
def test_extended_unpacking(self):
613620
driver.parse_string("a, *b, c = x\n")

Lib/test/test_gdb.py

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -897,15 +897,19 @@ def test_gc(self):
897897
# to suppress these. See also the comment in DebuggerTests.get_stack_trace
898898
def test_pycfunction(self):
899899
'Verify that "py-bt" displays invocations of PyCFunction instances'
900+
# bpo-46600: If the compiler inlines _null_to_none() in meth_varargs()
901+
# (ex: clang -Og), _null_to_none() is the frame #1. Otherwise,
902+
# meth_varargs() is the frame #1.
903+
expected_frame = r'#(1|2)'
900904
# Various optimizations multiply the code paths by which these are
901905
# called, so test a variety of calling conventions.
902-
for func_name, args, expected_frame in (
903-
('meth_varargs', '', 1),
904-
('meth_varargs_keywords', '', 1),
905-
('meth_o', '[]', 1),
906-
('meth_noargs', '', 1),
907-
('meth_fastcall', '', 1),
908-
('meth_fastcall_keywords', '', 1),
906+
for func_name, args in (
907+
('meth_varargs', ''),
908+
('meth_varargs_keywords', ''),
909+
('meth_o', '[]'),
910+
('meth_noargs', ''),
911+
('meth_fastcall', ''),
912+
('meth_fastcall_keywords', ''),
909913
):
910914
for obj in (
911915
'_testcapi',
@@ -945,10 +949,9 @@ def bar():
945949
# defined.' message in stderr.
946950
ignore_stderr=True,
947951
)
948-
self.assertIn(
949-
f'#{expected_frame} <built-in method {func_name}',
950-
gdb_output,
951-
)
952+
regex = expected_frame
953+
regex += re.escape(f' <built-in method {func_name}')
954+
self.assertRegex(gdb_output, regex)
952955

953956
@unittest.skipIf(python_is_optimized(),
954957
"Python was compiled with optimizations")

Lib/test/test_peepholer.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@ def test_pack_unpack(self):
126126
code = compile(line,'','single')
127127
self.assertInBytecode(code, elem)
128128
self.assertNotInBytecode(code, 'BUILD_TUPLE')
129-
self.assertNotInBytecode(code, 'UNPACK_TUPLE')
129+
self.assertNotInBytecode(code, 'UNPACK_SEQUENCE')
130130
self.check_lnotab(code)
131131

132132
def test_folding_of_tuples_of_constants(self):

Lib/test/test_tabnanny.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -293,8 +293,8 @@ def validate_cmd(self, *args, stdout="", stderr="", partial=False):
293293
_, out, err = script_helper.assert_python_ok('-m', 'tabnanny', *args)
294294
# Note: The `splitlines()` will solve the problem of CRLF(\r) added
295295
# by OS Windows.
296-
out = out.decode('ascii')
297-
err = err.decode('ascii')
296+
out = os.fsdecode(out)
297+
err = os.fsdecode(err)
298298
if partial:
299299
for std, output in ((stdout, out), (stderr, err)):
300300
_output = output.splitlines()

Lib/test/test_typing.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4643,6 +4643,13 @@ class A(typing.Match):
46434643

46444644
class AnnotatedTests(BaseTestCase):
46454645

4646+
def test_new(self):
4647+
with self.assertRaisesRegex(
4648+
TypeError,
4649+
'Type Annotated cannot be instantiated',
4650+
):
4651+
Annotated()
4652+
46464653
def test_repr(self):
46474654
self.assertEqual(
46484655
repr(Annotated[int, 4, 5]),

Mac/BuildScript/build-installer.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -358,9 +358,9 @@ def library_recipes():
358358
),
359359
),
360360
dict(
361-
name="SQLite 3.36.0",
362-
url="https://sqlite.org/2021/sqlite-autoconf-3360000.tar.gz",
363-
checksum='f5752052fc5b8e1b539af86a3671eac7',
361+
name="SQLite 3.37.2",
362+
url="https://sqlite.org/2022/sqlite-autoconf-3370200.tar.gz",
363+
checksum='683cc5312ee74e71079c14d24b7a6d27',
364364
extra_cflags=('-Os '
365365
'-DSQLITE_ENABLE_FTS5 '
366366
'-DSQLITE_ENABLE_FTS4 '
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
Fix the test checking if the C compiler supports ``-Og`` option in the
2+
``./configure`` script to also use ``-Og`` on clang which supports it. Patch
3+
by Victor Stinner.
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Do not create frame objects when creating :class:`super` object. Patch by Kumar Aditya.
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Add the ``get_write_buffer_limits`` method to :class:`asyncio.transports.WriteTransport` and to the SSL transport.
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Fix a Python crash in test_lib2to3 when using Python built in debug mode:
2+
limit the recursion limit. Patch by Victor Stinner.
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Fix test_gdb.test_pycfunction() for Python built with ``clang -Og``.
2+
Tolerate inlined functions in the gdb traceback. Patch by Victor Stinner.
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Update macOS installer to SQLite 3.37.2.

0 commit comments

Comments
 (0)