Skip to content

Commit 709ea3d

Browse files
generatedunixname1734921407115435meta-codesync[bot]
authored andcommitted
Sync pre-release CPython 3.15 branch from GitHub (2026-06-14)
Summary: Imported python/cpython `3.15.0b2+dev` from upstream rev [`1b457d3`](https://www.github.com/python/cpython/commit/1b457d3bbc528184f373bdcac47f0951052f90b7) (committed 2026-06-14 18:37:23+00:00). # Commit Info - Base: (`3.15.0b2+dev`) - [`75289a9`](https://www.github.com/python/cpython/commit/75289a92dfb460acde427b9f399881a108427b6c) (commit date: 2026-06-13 23:40:19+00:00) - Imported: (`3.15.0b2+dev`) - [`1b457d3`](https://www.github.com/python/cpython/commit/1b457d3bbc528184f373bdcac47f0951052f90b7) (commit date: 2026-06-14 18:37:23+00:00) # Noteworthy file changes - Low-signal files (2 added) (NEWS.d, docs, .github) Complete list of added/removed files: https://www.internalfb.com/intern/everpaste/?color=0&handle=GNqyAikz87RmOXwDAF8u6j_7PXktbr0LAAAz Differential Revision: D108576618 fbshipit-source-id: c2f883301985a9b22288493b76b1a765beceb74b
1 parent 76a88ba commit 709ea3d

12 files changed

Lines changed: 113 additions & 57 deletions

File tree

Doc/library/warnings.rst

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -626,9 +626,28 @@ Available Context Managers
626626
If the *record* argument is :const:`False` (the default) the context manager
627627
returns :class:`None` on entry. If *record* is :const:`True`, a list is
628628
returned that is progressively populated with objects as seen by a custom
629-
:func:`showwarning` function (which also suppresses output to ``sys.stdout``).
630-
Each object in the list has attributes with the same names as the arguments to
631-
:func:`showwarning`.
629+
:func:`showwarning` function (which also suppresses output to ``sys.stderr``).
630+
Each object in the list is guaranteed to have the following attributes:
631+
632+
- ``message``: the warning message (an instance of :exc:`Warning`)
633+
- ``category``: the warning category (a subclass of :exc:`Warning`)
634+
- ``filename``: the file name where the warning occurred (:class:`str`)
635+
- ``lineno``: the line number in the file (:class:`int`)
636+
- ``file``: the file object used for output (if any), or ``None``
637+
- ``line``: the line of source code (if available), or ``None``
638+
- ``source``: the original object that generated the warning (if
639+
available), or ``None``
640+
- ``module``: the module name where the warning occurred
641+
(:class:`str`), or ``None``
642+
643+
.. versionchanged:: 3.6
644+
The ``source`` attribute was added.
645+
646+
.. versionchanged:: 3.15
647+
The ``module`` attribute was added.
648+
649+
The type of these objects is not specified and may change; only the
650+
presence of these attributes is guaranteed.
632651

633652
The *module* argument takes a module that will be used instead of the
634653
module returned when you import :mod:`!warnings` whose filter will be

Lib/_pyrepl/utils.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -259,7 +259,7 @@ def is_soft_keyword_used(*tokens: TI | None) -> bool:
259259
None | TI(T.NEWLINE) | TI(T.INDENT) | TI(string=":"),
260260
TI(string="match"),
261261
TI(T.NUMBER | T.STRING | T.FSTRING_START | T.TSTRING_START)
262-
| TI(T.OP, string="(" | "*" | "[" | "{" | "~" | "...")
262+
| TI(T.OP, string="(" | "*" | "-" | "+" | "[" | "{" | "~" | "...")
263263
):
264264
return True
265265
case (

Lib/test/test_json/test_recursion.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ def default(self, o):
6868
self.fail("didn't raise ValueError on default recursion")
6969

7070

71+
@support.skip_if_pgo_task # fails during PGO training w/ some stack sizes
7172
@support.skip_if_unlimited_stack_size
7273
@support.skip_emscripten_stack_overflow()
7374
@support.skip_wasi_stack_overflow()

Lib/test/test_pyrepl/test_utils.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,22 @@ def test_gen_colors_keyword_highlighting(self):
125125
("import", "keyword"),
126126
],
127127
),
128+
(
129+
"match +1",
130+
[
131+
("match", "soft_keyword"),
132+
("+", "op"),
133+
("1", "number"),
134+
],
135+
),
136+
(
137+
"match -1",
138+
[
139+
("match", "soft_keyword"),
140+
("-", "op"),
141+
("1", "number"),
142+
],
143+
),
128144
]
129145
for code, expected_highlights in cases:
130146
with self.subTest(code=code):

Lib/test/test_source_encoding.py

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -387,8 +387,7 @@ def test_utf8_non_utf8_third_line_error(self):
387387
b'#third\xa4\n'
388388
b'raise RuntimeError\n')
389389
self.check_script_error(src,
390-
br"'utf-8' codec can't decode byte|"
391-
br"encoding problem: utf8")
390+
br"'utf-8' codec can't decode byte")
392391

393392
def test_crlf(self):
394393
src = (b'print(ascii("""\r\n"""))\n')
@@ -540,6 +539,20 @@ def check_script_error(self, src, expected, lineno=...):
540539
line = line.removeprefix('\ufeff')
541540
self.assertIn(line.encode(), err)
542541

542+
def test_coding_spec_unknown_encoding(self):
543+
src = (b'# coding: c1252\n'
544+
b'print("Hi!")\n')
545+
self.check_script_error(src, br"unknown encoding: c1252")
546+
547+
def test_coding_spec_decode_error(self):
548+
src = (b'# coding: shift-jis\n'
549+
b'print("\xc4\x85")\n')
550+
self.check_script_error(src, br"'shift_jis' codec can't decode byte")
551+
552+
def test_coding_spec_non_text_encoding(self):
553+
src = (b'# coding: hex_codec\n'
554+
b'print("eggs")\n')
555+
self.check_script_error(src, br"'hex_codec' is not a text encoding")
543556

544557

545558
if __name__ == "__main__":
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
Fix direct execution of files with invalid source encodings to report the
2+
underlying codec lookup or decoding error instead of the generic
3+
``SyntaxError: encoding problem`` message. Patch by Bartosz Sławecki.
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Colorize ``match`` in the :term:`REPL` when followed by a unary ``+`` or ``-`` operator. Patch by Bartosz Sławecki.

Parser/pegen.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99

1010
#include "lexer/lexer.h"
1111
#include "tokenizer/tokenizer.h"
12+
#include "tokenizer/helpers.h"
1213
#include "pegen.h"
1314

1415
// Internal parser functions
@@ -993,7 +994,7 @@ _PyPegen_run_parser_from_file_pointer(FILE *fp, int start_rule, PyObject *filena
993994
struct tok_state *tok = _PyTokenizer_FromFile(fp, enc, ps1, ps2);
994995
if (tok == NULL) {
995996
if (PyErr_Occurred()) {
996-
_PyPegen_raise_tokenizer_init_error(filename_ob);
997+
_PyTokenizer_raise_init_error(filename_ob);
997998
return NULL;
998999
}
9991000
return NULL;
@@ -1051,7 +1052,7 @@ _PyPegen_run_parser_from_string(const char *str, int start_rule, PyObject *filen
10511052
}
10521053
if (tok == NULL) {
10531054
if (PyErr_Occurred()) {
1054-
_PyPegen_raise_tokenizer_init_error(filename_ob);
1055+
_PyTokenizer_raise_init_error(filename_ob);
10551056
}
10561057
return NULL;
10571058
}

Parser/pegen.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -174,7 +174,6 @@ typedef enum {
174174
} TARGETS_TYPE;
175175

176176
int _Pypegen_raise_decode_error(Parser *p);
177-
void _PyPegen_raise_tokenizer_init_error(PyObject *filename);
178177
int _Pypegen_tokenizer_error(Parser *p);
179178
void *_PyPegen_raise_error(Parser *p, PyObject *errtype, int use_mark, const char *errmsg, ...);
180179
void *_PyPegen_raise_error_known_location(Parser *p, PyObject *errtype,

Parser/pegen_errors.c

Lines changed: 0 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -10,53 +10,6 @@
1010

1111
// TOKENIZER ERRORS
1212

13-
void
14-
_PyPegen_raise_tokenizer_init_error(PyObject *filename)
15-
{
16-
if (!(PyErr_ExceptionMatches(PyExc_LookupError)
17-
|| PyErr_ExceptionMatches(PyExc_SyntaxError)
18-
|| PyErr_ExceptionMatches(PyExc_ValueError)
19-
|| PyErr_ExceptionMatches(PyExc_UnicodeDecodeError))) {
20-
return;
21-
}
22-
PyObject *errstr = NULL;
23-
PyObject *tuple = NULL;
24-
PyObject *type;
25-
PyObject *value;
26-
PyObject *tback;
27-
PyErr_Fetch(&type, &value, &tback);
28-
if (PyErr_GivenExceptionMatches(value, PyExc_SyntaxError)) {
29-
if (PyObject_SetAttr(value, &_Py_ID(filename), filename)) {
30-
goto error;
31-
}
32-
PyErr_Restore(type, value, tback);
33-
return;
34-
}
35-
errstr = PyObject_Str(value);
36-
if (!errstr) {
37-
goto error;
38-
}
39-
40-
PyObject *tmp = Py_BuildValue("(OiiO)", filename, 0, -1, Py_None);
41-
if (!tmp) {
42-
goto error;
43-
}
44-
45-
tuple = _PyTuple_FromPair(errstr, tmp);
46-
Py_DECREF(tmp);
47-
if (!tuple) {
48-
goto error;
49-
}
50-
PyErr_SetObject(PyExc_SyntaxError, tuple);
51-
52-
error:
53-
Py_XDECREF(type);
54-
Py_XDECREF(value);
55-
Py_XDECREF(tback);
56-
Py_XDECREF(errstr);
57-
Py_XDECREF(tuple);
58-
}
59-
6013
static inline void
6114
raise_unclosed_parentheses_error(Parser *p) {
6215
int error_lineno = p->tok->parenlinenostack[p->tok->level-1];

0 commit comments

Comments
 (0)