Skip to content

Commit 4b55d53

Browse files
authored
[3.13] gh-125268: Use static string for "1e309" in AST (GH-125272) (GH-125280)
When formatting the AST as a string, infinite values are replaced by 1e309, which evaluates to infinity. The initialization of this string replacement was not thread-safe in the free threading build. (cherry picked from commit 427dcf2)
1 parent f27ba61 commit 4b55d53

File tree

9 files changed

+4788
-4795
lines changed

9 files changed

+4788
-4795
lines changed

Doc/data/python3.13.abi

Lines changed: 4776 additions & 4765 deletions
Large diffs are not rendered by default.

Include/internal/pycore_global_objects.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ struct _Py_interp_cached_objects {
6767
PyObject *interned_strings;
6868

6969
/* AST */
70-
PyObject *str_replace_inf;
70+
PyObject *_unused_str_replace_inf; // kept in 3.13 for ABI compatibility
7171

7272
/* object.__reduce__ */
7373
PyObject *objreduce;

Include/internal/pycore_global_objects_fini_generated.h

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Include/internal/pycore_global_strings.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ struct _Py_global_strings {
4747
STRUCT_FOR_STR(json_decoder, "json.decoder")
4848
STRUCT_FOR_STR(kwdefaults, ".kwdefaults")
4949
STRUCT_FOR_STR(list_err, "list index out of range")
50+
STRUCT_FOR_STR(str_replace_inf, "1e309")
5051
STRUCT_FOR_STR(type_params, ".type_params")
5152
STRUCT_FOR_STR(utf_8, "utf-8")
5253
} literals;

Include/internal/pycore_runtime_init_generated.h

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Include/internal/pycore_unicodeobject_generated.h

Lines changed: 4 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Parser/asdl_c.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1740,8 +1740,6 @@ def generate_ast_fini(module_state, f):
17401740
for s in module_state:
17411741
f.write(" Py_CLEAR(state->" + s + ');\n')
17421742
f.write(textwrap.dedent("""
1743-
Py_CLEAR(_Py_INTERP_CACHED_OBJECT(interp, str_replace_inf));
1744-
17451743
state->finalized = 1;
17461744
state->once = (_PyOnceFlag){0};
17471745
}

Python/Python-ast.c

Lines changed: 0 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Python/ast_unparse.c

Lines changed: 4 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
#include "pycore_ast.h" // expr_ty
33
#include "pycore_pystate.h" // _PyInterpreterState_GET()
44
#include "pycore_runtime.h" // _Py_ID()
5-
#include <float.h> // DBL_MAX_10_EXP
65
#include <stdbool.h>
76

87
/* This limited unparser is used to convert annotations back to strings
@@ -13,10 +12,6 @@
1312
_Py_DECLARE_STR(dbl_open_br, "{{");
1413
_Py_DECLARE_STR(dbl_close_br, "}}");
1514

16-
/* We would statically initialize this if doing so were simple enough. */
17-
#define _str_replace_inf(interp) \
18-
_Py_INTERP_CACHED_OBJECT(interp, str_replace_inf)
19-
2015
/* Forward declarations for recursion via helper functions. */
2116
static PyObject *
2217
expr_as_unicode(expr_ty e, int level);
@@ -78,13 +73,13 @@ append_repr(_PyUnicodeWriter *writer, PyObject *obj)
7873
}
7974

8075
if ((PyFloat_CheckExact(obj) && Py_IS_INFINITY(PyFloat_AS_DOUBLE(obj))) ||
81-
PyComplex_CheckExact(obj))
76+
PyComplex_CheckExact(obj))
8277
{
83-
PyInterpreterState *interp = _PyInterpreterState_GET();
78+
_Py_DECLARE_STR(str_replace_inf, "1e309"); // evaluates to inf
8479
PyObject *new_repr = PyUnicode_Replace(
8580
repr,
8681
&_Py_ID(inf),
87-
_str_replace_inf(interp),
82+
&_Py_STR(str_replace_inf),
8883
-1
8984
);
9085
Py_DECREF(repr);
@@ -918,30 +913,14 @@ append_ast_expr(_PyUnicodeWriter *writer, expr_ty e, int level)
918913
return -1;
919914
}
920915

921-
static int
922-
maybe_init_static_strings(void)
923-
{
924-
PyInterpreterState *interp = _PyInterpreterState_GET();
925-
if (_str_replace_inf(interp) == NULL) {
926-
PyObject *tmp = PyUnicode_FromFormat("1e%d", 1 + DBL_MAX_10_EXP);
927-
if (tmp == NULL) {
928-
return -1;
929-
}
930-
_str_replace_inf(interp) = tmp;
931-
}
932-
return 0;
933-
}
934-
935916
static PyObject *
936917
expr_as_unicode(expr_ty e, int level)
937918
{
938919
_PyUnicodeWriter writer;
939920
_PyUnicodeWriter_Init(&writer);
940921
writer.min_length = 256;
941922
writer.overallocate = 1;
942-
if (-1 == maybe_init_static_strings() ||
943-
-1 == append_ast_expr(&writer, e, level))
944-
{
923+
if (-1 == append_ast_expr(&writer, e, level)) {
945924
_PyUnicodeWriter_Dealloc(&writer);
946925
return NULL;
947926
}

0 commit comments

Comments
 (0)