Skip to content

Commit e7af412

Browse files
authored
Merge branch 'main' into run-test-suite-with-warnings-as-error
2 parents 5886785 + d05140f commit e7af412

25 files changed

+715
-412
lines changed

Doc/library/importlib.rst

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -380,13 +380,15 @@ ABC hierarchy::
380380

381381
.. class:: ResourceLoader
382382

383+
*Superseded by TraversableResources*
384+
383385
An abstract base class for a :term:`loader` which implements the optional
384386
:pep:`302` protocol for loading arbitrary resources from the storage
385387
back-end.
386388

387389
.. deprecated:: 3.7
388390
This ABC is deprecated in favour of supporting resource loading
389-
through :class:`importlib.resources.abc.ResourceReader`.
391+
through :class:`importlib.resources.abc.TraversableResources`.
390392

391393
.. abstractmethod:: get_data(path)
392394

Include/internal/pycore_gc.h

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -45,12 +45,13 @@ static inline PyObject* _Py_FROM_GC(PyGC_Head *gc) {
4545
* the per-object lock.
4646
*/
4747
#ifdef Py_GIL_DISABLED
48-
# define _PyGC_BITS_TRACKED (1) // Tracked by the GC
49-
# define _PyGC_BITS_FINALIZED (2) // tp_finalize was called
50-
# define _PyGC_BITS_UNREACHABLE (4)
51-
# define _PyGC_BITS_FROZEN (8)
52-
# define _PyGC_BITS_SHARED (16)
53-
# define _PyGC_BITS_DEFERRED (64) // Use deferred reference counting
48+
# define _PyGC_BITS_TRACKED (1<<0) // Tracked by the GC
49+
# define _PyGC_BITS_FINALIZED (1<<1) // tp_finalize was called
50+
# define _PyGC_BITS_UNREACHABLE (1<<2)
51+
# define _PyGC_BITS_FROZEN (1<<3)
52+
# define _PyGC_BITS_SHARED (1<<4)
53+
# define _PyGC_BITS_ALIVE (1<<5) // Reachable from a known root.
54+
# define _PyGC_BITS_DEFERRED (1<<6) // Use deferred reference counting
5455
#endif
5556

5657
#ifdef Py_GIL_DISABLED
@@ -330,6 +331,9 @@ struct _gc_runtime_state {
330331
collections, and are awaiting to undergo a full collection for
331332
the first time. */
332333
Py_ssize_t long_lived_pending;
334+
335+
/* True if gc.freeze() has been used. */
336+
int freeze_active;
333337
#endif
334338
};
335339

Include/internal/pycore_object.h

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -299,12 +299,6 @@ Py_ssize_t _Py_ExplicitMergeRefcount(PyObject *op, Py_ssize_t extra);
299299
extern int _PyType_CheckConsistency(PyTypeObject *type);
300300
extern int _PyDict_CheckConsistency(PyObject *mp, int check_content);
301301

302-
/* Update the Python traceback of an object. This function must be called
303-
when a memory block is reused from a free list.
304-
305-
Internal function called by _Py_NewReference(). */
306-
extern int _PyTraceMalloc_TraceRef(PyObject *op, PyRefTracerEvent event, void*);
307-
308302
// Fast inlined version of PyType_HasFeature()
309303
static inline int
310304
_PyType_HasFeature(PyTypeObject *type, unsigned long feature) {

Include/internal/pycore_tracemalloc.h

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ struct _PyTraceMalloc_Config {
2525
} initialized;
2626

2727
/* Is tracemalloc tracing memory allocations?
28-
Variable protected by the GIL */
28+
Variable protected by the TABLES_LOCK(). */
2929
int tracing;
3030

3131
/* limit of the number of frames in a traceback, 1 by default.
@@ -85,14 +85,14 @@ struct _tracemalloc_runtime_state {
8585
size_t peak_traced_memory;
8686
/* Hash table used as a set to intern filenames:
8787
PyObject* => PyObject*.
88-
Protected by the GIL */
88+
Protected by the TABLES_LOCK(). */
8989
_Py_hashtable_t *filenames;
9090
/* Buffer to store a new traceback in traceback_new().
91-
Protected by the GIL. */
91+
Protected by the TABLES_LOCK(). */
9292
struct tracemalloc_traceback *traceback;
9393
/* Hash table used as a set to intern tracebacks:
9494
traceback_t* => traceback_t*
95-
Protected by the GIL */
95+
Protected by the TABLES_LOCK(). */
9696
_Py_hashtable_t *tracebacks;
9797
/* pointer (void*) => trace (trace_t*).
9898
Protected by TABLES_LOCK(). */
@@ -144,7 +144,7 @@ extern PyObject* _PyTraceMalloc_GetTraces(void);
144144
extern PyObject* _PyTraceMalloc_GetObjectTraceback(PyObject *obj);
145145

146146
/* Initialize tracemalloc */
147-
extern int _PyTraceMalloc_Init(void);
147+
extern PyStatus _PyTraceMalloc_Init(void);
148148

149149
/* Start tracemalloc */
150150
extern int _PyTraceMalloc_Start(int max_nframe);

Lib/importlib/abc.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ def __init__(self):
7474
import warnings
7575
warnings.warn('importlib.abc.ResourceLoader is deprecated in '
7676
'favour of supporting resource loading through '
77-
'importlib.resources.abc.ResourceReader.',
77+
'importlib.resources.abc.TraversableResources.',
7878
DeprecationWarning, stacklevel=2)
7979
super().__init__()
8080

Lib/opcode.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,9 @@
1717
EXTENDED_ARG = opmap['EXTENDED_ARG']
1818

1919
opname = ['<%r>' % (op,) for op in range(max(opmap.values()) + 1)]
20-
for op, i in opmap.items():
21-
opname[i] = op
20+
for m in (opmap, _specialized_opmap):
21+
for op, i in m.items():
22+
opname[i] = op
2223

2324
cmp_op = ('<', '<=', '==', '!=', '>', '>=')
2425

Lib/test/test__opcode.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,13 @@ def test_is_valid(self):
3838
opcodes = [dis.opmap[opname] for opname in names]
3939
self.check_bool_function_result(_opcode.is_valid, opcodes, True)
4040

41+
def test_opmaps(self):
42+
def check_roundtrip(name, map):
43+
return self.assertEqual(opcode.opname[map[name]], name)
44+
45+
check_roundtrip('BINARY_OP', opcode.opmap)
46+
check_roundtrip('BINARY_OP_ADD_INT', opcode._specialized_opmap)
47+
4148
def test_oplists(self):
4249
def check_function(self, func, expected):
4350
for op in [-10, 520]:

Lib/test/test_cmd_line_script.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -659,7 +659,8 @@ def test_syntaxerror_invalid_escape_sequence_multi_line(self):
659659
stderr.splitlines()[-3:],
660660
[ b' foo = """\\q"""',
661661
b' ^^^^^^^^',
662-
b'SyntaxError: invalid escape sequence \'\\q\''
662+
b'SyntaxError: "\\q" is an invalid escape sequence. '
663+
b'Did you mean "\\\\q"? A raw string is also an option.'
663664
],
664665
)
665666

Lib/test/test_codeop.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -282,7 +282,7 @@ def test_warning(self):
282282
# Test that the warning is only returned once.
283283
with warnings_helper.check_warnings(
284284
('"is" with \'str\' literal', SyntaxWarning),
285-
("invalid escape sequence", SyntaxWarning),
285+
('"\\\\e" is an invalid escape sequence', SyntaxWarning),
286286
) as w:
287287
compile_command(r"'\e' is 0")
288288
self.assertEqual(len(w.warnings), 2)

Lib/test/test_dis.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -999,12 +999,14 @@ def test_boundaries(self):
999999
def test_widths(self):
10001000
long_opcodes = set(['JUMP_BACKWARD_NO_INTERRUPT',
10011001
'INSTRUMENTED_CALL_FUNCTION_EX'])
1002-
for opcode, opname in enumerate(dis.opname):
1002+
for op, opname in enumerate(dis.opname):
10031003
if opname in long_opcodes or opname.startswith("INSTRUMENTED"):
10041004
continue
1005+
if opname in opcode._specialized_opmap:
1006+
continue
10051007
with self.subTest(opname=opname):
10061008
width = dis._OPNAME_WIDTH
1007-
if opcode in dis.hasarg:
1009+
if op in dis.hasarg:
10081010
width += 1 + dis._OPARG_WIDTH
10091011
self.assertLessEqual(len(opname), width)
10101012

Lib/test/test_string_literals.py

Lines changed: 20 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,9 @@ def test_eval_str_invalid_escape(self):
116116
warnings.simplefilter('always', category=SyntaxWarning)
117117
eval("'''\n\\z'''")
118118
self.assertEqual(len(w), 1)
119-
self.assertEqual(str(w[0].message), r"invalid escape sequence '\z'")
119+
self.assertEqual(str(w[0].message), r'"\z" is an invalid escape sequence. '
120+
r'Such sequences will not work in the future. '
121+
r'Did you mean "\\z"? A raw string is also an option.')
120122
self.assertEqual(w[0].filename, '<string>')
121123
self.assertEqual(w[0].lineno, 1)
122124

@@ -126,7 +128,8 @@ def test_eval_str_invalid_escape(self):
126128
eval("'''\n\\z'''")
127129
exc = cm.exception
128130
self.assertEqual(w, [])
129-
self.assertEqual(exc.msg, r"invalid escape sequence '\z'")
131+
self.assertEqual(exc.msg, r'"\z" is an invalid escape sequence. '
132+
r'Did you mean "\\z"? A raw string is also an option.')
130133
self.assertEqual(exc.filename, '<string>')
131134
self.assertEqual(exc.lineno, 1)
132135
self.assertEqual(exc.offset, 1)
@@ -153,7 +156,9 @@ def test_eval_str_invalid_octal_escape(self):
153156
eval("'''\n\\407'''")
154157
self.assertEqual(len(w), 1)
155158
self.assertEqual(str(w[0].message),
156-
r"invalid octal escape sequence '\407'")
159+
r'"\407" is an invalid octal escape sequence. '
160+
r'Such sequences will not work in the future. '
161+
r'Did you mean "\\407"? A raw string is also an option.')
157162
self.assertEqual(w[0].filename, '<string>')
158163
self.assertEqual(w[0].lineno, 1)
159164

@@ -163,7 +168,8 @@ def test_eval_str_invalid_octal_escape(self):
163168
eval("'''\n\\407'''")
164169
exc = cm.exception
165170
self.assertEqual(w, [])
166-
self.assertEqual(exc.msg, r"invalid octal escape sequence '\407'")
171+
self.assertEqual(exc.msg, r'"\407" is an invalid octal escape sequence. '
172+
r'Did you mean "\\407"? A raw string is also an option.')
167173
self.assertEqual(exc.filename, '<string>')
168174
self.assertEqual(exc.lineno, 1)
169175
self.assertEqual(exc.offset, 1)
@@ -205,7 +211,9 @@ def test_eval_bytes_invalid_escape(self):
205211
warnings.simplefilter('always', category=SyntaxWarning)
206212
eval("b'''\n\\z'''")
207213
self.assertEqual(len(w), 1)
208-
self.assertEqual(str(w[0].message), r"invalid escape sequence '\z'")
214+
self.assertEqual(str(w[0].message), r'"\z" is an invalid escape sequence. '
215+
r'Such sequences will not work in the future. '
216+
r'Did you mean "\\z"? A raw string is also an option.')
209217
self.assertEqual(w[0].filename, '<string>')
210218
self.assertEqual(w[0].lineno, 1)
211219

@@ -215,7 +223,8 @@ def test_eval_bytes_invalid_escape(self):
215223
eval("b'''\n\\z'''")
216224
exc = cm.exception
217225
self.assertEqual(w, [])
218-
self.assertEqual(exc.msg, r"invalid escape sequence '\z'")
226+
self.assertEqual(exc.msg, r'"\z" is an invalid escape sequence. '
227+
r'Did you mean "\\z"? A raw string is also an option.')
219228
self.assertEqual(exc.filename, '<string>')
220229
self.assertEqual(exc.lineno, 1)
221230

@@ -228,8 +237,9 @@ def test_eval_bytes_invalid_octal_escape(self):
228237
warnings.simplefilter('always', category=SyntaxWarning)
229238
eval("b'''\n\\407'''")
230239
self.assertEqual(len(w), 1)
231-
self.assertEqual(str(w[0].message),
232-
r"invalid octal escape sequence '\407'")
240+
self.assertEqual(str(w[0].message), r'"\407" is an invalid octal escape sequence. '
241+
r'Such sequences will not work in the future. '
242+
r'Did you mean "\\407"? A raw string is also an option.')
233243
self.assertEqual(w[0].filename, '<string>')
234244
self.assertEqual(w[0].lineno, 1)
235245

@@ -239,7 +249,8 @@ def test_eval_bytes_invalid_octal_escape(self):
239249
eval("b'''\n\\407'''")
240250
exc = cm.exception
241251
self.assertEqual(w, [])
242-
self.assertEqual(exc.msg, r"invalid octal escape sequence '\407'")
252+
self.assertEqual(exc.msg, r'"\407" is an invalid octal escape sequence. '
253+
r'Did you mean "\\407"? A raw string is also an option.')
243254
self.assertEqual(exc.filename, '<string>')
244255
self.assertEqual(exc.lineno, 1)
245256

Lib/test/test_unparse.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -651,7 +651,9 @@ def test_multiquote_joined_string(self):
651651

652652
def test_backslash_in_format_spec(self):
653653
import re
654-
msg = re.escape("invalid escape sequence '\\ '")
654+
msg = re.escape('"\\ " is an invalid escape sequence. '
655+
'Such sequences will not work in the future. '
656+
'Did you mean "\\\\ "? A raw string is also an option.')
655657
with self.assertWarnsRegex(SyntaxWarning, msg):
656658
self.check_ast_roundtrip("""f"{x:\\ }" """)
657659
self.check_ast_roundtrip("""f"{x:\\n}" """)

Misc/NEWS.d/3.10.0b1.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -941,7 +941,7 @@ result from ``entry_points()`` as deprecated.
941941

942942
..
943943
944-
.. gh: 47383
944+
.. gh-issue: 47383
945945
.. date: 2021-04-08-19-32-26
946946
.. nonce: YI1hdL
947947
.. section: Library

Misc/NEWS.d/3.11.0b1.rst

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -570,7 +570,7 @@ planned). Patch by Alex Waygood.
570570

571571
..
572572
573-
.. gh: 78157
573+
.. gh-issue: 78157
574574
.. date: 2022-05-05-20-40-45
575575
.. nonce: IA_9na
576576
.. section: Library
@@ -1289,7 +1289,7 @@ Deprecate the chunk module.
12891289

12901290
..
12911291
1292-
.. gh: 91498
1292+
.. gh-issue: 91498
12931293
.. date: 2022-04-10-08-39-44
12941294
.. nonce: 8oII92
12951295
.. section: Library
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Improved the ``SyntaxWarning`` message for invalid escape sequences to clarify that such sequences will raise a ``SyntaxError`` in future Python releases. The new message also suggests a potential fix, i.e., ``Did you mean "\\e"?``.
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
Add a marking phase to the free-threaded GC. This is similar to what was
2+
done in GH-126491. Since the free-threaded GC does not have generations and
3+
is not incremental, the marking phase looks for all objects reachable from
4+
known roots. The roots are objects known to not be garbage, like the module
5+
dictionary for :mod:`sys`. For most programs, this marking phase should
6+
make the GC a bit faster since typically less work is done per object.
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Add specialized opcodes to ``opcode.opname``.

Modules/_tracemalloc.c

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -215,18 +215,14 @@ static struct PyModuleDef module_def = {
215215
PyMODINIT_FUNC
216216
PyInit__tracemalloc(void)
217217
{
218-
PyObject *m;
219-
m = PyModule_Create(&module_def);
220-
if (m == NULL)
218+
PyObject *mod = PyModule_Create(&module_def);
219+
if (mod == NULL) {
221220
return NULL;
221+
}
222+
222223
#ifdef Py_GIL_DISABLED
223-
PyUnstable_Module_SetGIL(m, Py_MOD_GIL_NOT_USED);
224+
PyUnstable_Module_SetGIL(mod, Py_MOD_GIL_NOT_USED);
224225
#endif
225226

226-
if (_PyTraceMalloc_Init() < 0) {
227-
Py_DECREF(m);
228-
return NULL;
229-
}
230-
231-
return m;
227+
return mod;
232228
}

Objects/bytesobject.c

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1205,7 +1205,8 @@ PyObject *PyBytes_DecodeEscape(const char *s,
12051205
unsigned char c = *first_invalid_escape;
12061206
if ('4' <= c && c <= '7') {
12071207
if (PyErr_WarnFormat(PyExc_DeprecationWarning, 1,
1208-
"invalid octal escape sequence '\\%.3s'",
1208+
"b\"\\%.3s\" is an invalid octal escape sequence. "
1209+
"Such sequences will not work in the future. ",
12091210
first_invalid_escape) < 0)
12101211
{
12111212
Py_DECREF(result);
@@ -1214,7 +1215,8 @@ PyObject *PyBytes_DecodeEscape(const char *s,
12141215
}
12151216
else {
12161217
if (PyErr_WarnFormat(PyExc_DeprecationWarning, 1,
1217-
"invalid escape sequence '\\%c'",
1218+
"b\"\\%c\" is an invalid escape sequence. "
1219+
"Such sequences will not work in the future. ",
12181220
c) < 0)
12191221
{
12201222
Py_DECREF(result);
@@ -1223,7 +1225,6 @@ PyObject *PyBytes_DecodeEscape(const char *s,
12231225
}
12241226
}
12251227
return result;
1226-
12271228
}
12281229
/* -------------------------------------------------------------------- */
12291230
/* object api */

Objects/unicodeobject.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6853,7 +6853,8 @@ _PyUnicode_DecodeUnicodeEscapeStateful(const char *s,
68536853
unsigned char c = *first_invalid_escape;
68546854
if ('4' <= c && c <= '7') {
68556855
if (PyErr_WarnFormat(PyExc_DeprecationWarning, 1,
6856-
"invalid octal escape sequence '\\%.3s'",
6856+
"\"\\%.3s\" is an invalid octal escape sequence. "
6857+
"Such sequences will not work in the future. ",
68576858
first_invalid_escape) < 0)
68586859
{
68596860
Py_DECREF(result);
@@ -6862,7 +6863,8 @@ _PyUnicode_DecodeUnicodeEscapeStateful(const char *s,
68626863
}
68636864
else {
68646865
if (PyErr_WarnFormat(PyExc_DeprecationWarning, 1,
6865-
"invalid escape sequence '\\%c'",
6866+
"\"\\%c\" is an invalid escape sequence. "
6867+
"Such sequences will not work in the future. ",
68666868
c) < 0)
68676869
{
68686870
Py_DECREF(result);

0 commit comments

Comments
 (0)