Skip to content

Commit 9679c08

Browse files
Merge branch 'main' into gh-130052-test-external-inspection-setexception
2 parents 23fdc5f + 140e69c commit 9679c08

29 files changed

+1210
-778
lines changed

.github/workflows/build.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -621,6 +621,7 @@ jobs:
621621
- build_wasi
622622
- build_windows
623623
- build_windows_msi
624+
- cross-build-linux
624625
- test_hypothesis
625626
- build_asan
626627
- build_tsan

Doc/c-api/typeobj.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1830,7 +1830,7 @@ and :c:data:`PyType_Type` effectively act as defaults.)
18301830
dictionary, so it is may be more efficient to call :c:func:`PyObject_GetAttr`
18311831
when accessing an attribute on the object.
18321832

1833-
It is an error to set both the :c:macro:`Py_TPFLAGS_MANAGED_WEAKREF` bit and
1833+
It is an error to set both the :c:macro:`Py_TPFLAGS_MANAGED_DICT` bit and
18341834
:c:member:`~PyTypeObject.tp_dictoffset`.
18351835

18361836
**Inheritance:**

Doc/library/traceback.rst

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -257,6 +257,11 @@ Module-Level Functions
257257

258258
.. versionadded:: 3.5
259259

260+
.. versionchanged:: 3.14
261+
This function previously returned a generator that would walk the stack
262+
when first iterated over. The generator returned now is the state of the
263+
stack when ``walk_stack`` is called.
264+
260265
.. function:: walk_tb(tb)
261266

262267
Walk a traceback following :attr:`~traceback.tb_next` yielding the frame and

Doc/whatsnew/3.14.rst

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,7 @@ Improved error messages
165165
error message prints the received number of values in more cases than before.
166166
(Contributed by Tushar Sadhwani in :gh:`122239`.)
167167

168-
.. code-block:: pycon
168+
.. code-block:: python
169169
170170
>>> x, y, z = 1, 2, 3, 4
171171
Traceback (most recent call last):
@@ -175,6 +175,17 @@ Improved error messages
175175
ValueError: too many values to unpack (expected 3, got 4)
176176
177177
178+
* When incorrectly closed strings are detected, the error message suggests
179+
that the string may be intended to be part of the string. (Contributed by
180+
Pablo Galindo in :gh:`88535`.)
181+
182+
.. code-block:: python
183+
184+
>>> "The interesting object "The important object" is very important"
185+
Traceback (most recent call last):
186+
SyntaxError: invalid syntax. Is this intended to be part of the string?
187+
188+
178189
.. _whatsnew314-pep741:
179190

180191
PEP 741: Python Configuration C API

Grammar/python.gram

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1178,6 +1178,9 @@ invalid_type_param:
11781178
}
11791179

11801180
invalid_expression:
1181+
| STRING a=(!STRING expression_without_invalid)+ STRING {
1182+
RAISE_SYNTAX_ERROR_KNOWN_RANGE( PyPegen_first_item(a, expr_ty), PyPegen_last_item(a, expr_ty),
1183+
"invalid syntax. Is this intended to be part of the string?") }
11811184
# !(NAME STRING) is not matched so we don't show this error with some invalid string prefixes like: kf"dsfsdf"
11821185
# Soft keywords need to also be ignored because they can be parsed as NAME NAME
11831186
| !(NAME STRING | SOFT_KEYWORD) a=disjunction b=expression_without_invalid {

Lib/test/test_ast/test_ast.py

Lines changed: 0 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -3239,46 +3239,6 @@ def test_folding_tuple(self):
32393239

32403240
self.assert_ast(code, non_optimized_target, optimized_target)
32413241

3242-
def test_folding_comparator(self):
3243-
code = "1 %s %s1%s"
3244-
operators = [("in", ast.In()), ("not in", ast.NotIn())]
3245-
braces = [
3246-
("[", "]", ast.List, (1,)),
3247-
("{", "}", ast.Set, frozenset({1})),
3248-
]
3249-
for left, right, non_optimized_comparator, optimized_comparator in braces:
3250-
for op, node in operators:
3251-
non_optimized_target = self.wrap_expr(ast.Compare(
3252-
left=ast.Constant(1), ops=[node],
3253-
comparators=[non_optimized_comparator(elts=[ast.Constant(1)])]
3254-
))
3255-
optimized_target = self.wrap_expr(ast.Compare(
3256-
left=ast.Constant(1), ops=[node],
3257-
comparators=[ast.Constant(value=optimized_comparator)]
3258-
))
3259-
self.assert_ast(code % (op, left, right), non_optimized_target, optimized_target)
3260-
3261-
def test_folding_iter(self):
3262-
code = "for _ in %s1%s: pass"
3263-
braces = [
3264-
("[", "]", ast.List, (1,)),
3265-
("{", "}", ast.Set, frozenset({1})),
3266-
]
3267-
3268-
for left, right, ast_cls, optimized_iter in braces:
3269-
non_optimized_target = self.wrap_statement(ast.For(
3270-
target=ast.Name(id="_", ctx=ast.Store()),
3271-
iter=ast_cls(elts=[ast.Constant(1)]),
3272-
body=[ast.Pass()]
3273-
))
3274-
optimized_target = self.wrap_statement(ast.For(
3275-
target=ast.Name(id="_", ctx=ast.Store()),
3276-
iter=ast.Constant(value=optimized_iter),
3277-
body=[ast.Pass()]
3278-
))
3279-
3280-
self.assert_ast(code % (left, right), non_optimized_target, optimized_target)
3281-
32823242
def test_folding_type_param_in_function_def(self):
32833243
code = "def foo[%s = 1 + 1](): pass"
32843244

Lib/test/test_cmd_line_script.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -660,7 +660,7 @@ def test_syntaxerror_invalid_escape_sequence_multi_line(self):
660660
self.assertEqual(
661661
stderr.splitlines()[-3:],
662662
[ b' foo = """\\q"""',
663-
b' ^^^^^^^^',
663+
b' ^^',
664664
b'SyntaxError: "\\q" is an invalid escape sequence. '
665665
b'Did you mean "\\\\q"? A raw string is also an option.'
666666
],

Lib/test/test_compile.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -798,7 +798,7 @@ def check_same_constant(const):
798798
f3 = lambda x: x in {("not a name",)}
799799
self.assertIs(f1.__code__.co_consts[0],
800800
f2.__code__.co_consts[0][0])
801-
self.assertIs(next(iter(f3.__code__.co_consts[0])),
801+
self.assertIs(next(iter(f3.__code__.co_consts[1])),
802802
f2.__code__.co_consts[0])
803803

804804
# {0} is converted to a constant frozenset({0}) by the peephole

Lib/test/test_exceptions.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2303,7 +2303,7 @@ def test_encodings(self):
23032303
)
23042304
err = run_script(source.encode('cp437'))
23052305
self.assertEqual(err[-3], ' "¢¢¢¢¢¢" + f(4, x for x in range(1))')
2306-
self.assertEqual(err[-2], ' ^^^^^^^^^^^^^^^^^^^')
2306+
self.assertEqual(err[-2], ' ^^^')
23072307

23082308
# Check backwards tokenizer errors
23092309
source = '# -*- coding: ascii -*-\n\n(\n'

Lib/test/test_fstring.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
import types
1616
import decimal
1717
import unittest
18+
import warnings
1819
from test import support
1920
from test.support.os_helper import temp_cwd
2021
from test.support.script_helper import assert_python_failure, assert_python_ok
@@ -1650,8 +1651,9 @@ def __repr__(self):
16501651
#self.assertEqual(f'X{x = }Y', 'Xx\t=\t'+repr(x)+'Y')
16511652

16521653
def test_debug_expressions_are_raw_strings(self):
1653-
1654-
self.assertEqual(f'{b"\N{OX}"=}', 'b"\\N{OX}"=b\'\\\\N{OX}\'')
1654+
with warnings.catch_warnings():
1655+
warnings.simplefilter('ignore', SyntaxWarning)
1656+
self.assertEqual(eval("""f'{b"\\N{OX}"=}'"""), 'b"\\N{OX}"=b\'\\\\N{OX}\'')
16551657
self.assertEqual(f'{r"\xff"=}', 'r"\\xff"=\'\\\\xff\'')
16561658
self.assertEqual(f'{r"\n"=}', 'r"\\n"=\'\\\\n\'')
16571659
self.assertEqual(f"{'\''=}", "'\\''=\"'\"")

0 commit comments

Comments
 (0)