Skip to content

Commit 1735710

Browse files
authored
gh-77782: Py_FdIsInteractive() now uses PyConfig.interactive (#93916)
1 parent c5b750d commit 1735710

File tree

6 files changed

+29
-23
lines changed

6 files changed

+29
-23
lines changed

Doc/c-api/sys.rst

+3-1
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,12 @@ Operating System Utilities
2121
2222
Return true (nonzero) if the standard I/O file *fp* with name *filename* is
2323
deemed interactive. This is the case for files for which ``isatty(fileno(fp))``
24-
is true. If the global flag :c:data:`Py_InteractiveFlag` is true, this function
24+
is true. If the :c:member:`PyConfig.interactive` is non-zero, this function
2525
also returns true if the *filename* pointer is ``NULL`` or if the name is equal to
2626
one of the strings ``'<stdin>'`` or ``'???'``.
2727
28+
This function must not be called before Python is initialized.
29+
2830
2931
.. c:function:: void PyOS_BeforeFork()
3032

Lib/test/test_capi.py

+9-8
Original file line numberDiff line numberDiff line change
@@ -70,16 +70,17 @@ def test_no_FatalError_infinite_loop(self):
7070
'import _testcapi;'
7171
'_testcapi.crash_no_current_thread()'],
7272
stdout=subprocess.PIPE,
73-
stderr=subprocess.PIPE)
73+
stderr=subprocess.PIPE,
74+
text=True)
7475
(out, err) = p.communicate()
75-
self.assertEqual(out, b'')
76+
self.assertEqual(out, '')
7677
# This used to cause an infinite loop.
77-
self.assertTrue(err.rstrip().startswith(
78-
b'Fatal Python error: '
79-
b'PyThreadState_Get: '
80-
b'the function must be called with the GIL held, '
81-
b'but the GIL is released '
82-
b'(the current Python thread state is NULL)'),
78+
msg = ("Fatal Python error: PyThreadState_Get: "
79+
"the function must be called with the GIL held, "
80+
"after Python initialization and before Python finalization, "
81+
"but the GIL is released "
82+
"(the current Python thread state is NULL)")
83+
self.assertTrue(err.rstrip().startswith(msg),
8384
err)
8485

8586
def test_memoryview_from_NULL_pointer(self):

Python/ceval.c

+3-3
Original file line numberDiff line numberDiff line change
@@ -347,9 +347,9 @@ void _Py_NO_RETURN
347347
_Py_FatalError_TstateNULL(const char *func)
348348
{
349349
_Py_FatalErrorFunc(func,
350-
"the function must be called with the GIL held, "
351-
"but the GIL is released "
352-
"(the current Python thread state is NULL)");
350+
"the function must be called with the GIL held, "
351+
"after Python initialization and before Python finalization, "
352+
"but the GIL is released (the current Python thread state is NULL)");
353353
}
354354

355355
int

Python/initconfig.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -180,7 +180,7 @@ int Py_UTF8Mode = 0;
180180
int Py_DebugFlag = 0; /* Needed by parser.c */
181181
int Py_VerboseFlag = 0; /* Needed by import.c */
182182
int Py_QuietFlag = 0; /* Needed by sysmodule.c */
183-
int Py_InteractiveFlag = 0; /* Needed by Py_FdIsInteractive() below */
183+
int Py_InteractiveFlag = 0; /* Previously, was used by Py_FdIsInteractive() */
184184
int Py_InspectFlag = 0; /* Needed to determine whether to exit at SystemExit */
185185
int Py_OptimizeFlag = 0; /* Needed by compile.c */
186186
int Py_NoSiteFlag = 0; /* Suppress 'import site' */

Python/pylifecycle.c

+12-10
Original file line numberDiff line numberDiff line change
@@ -2938,28 +2938,30 @@ Py_Exit(int sts)
29382938
int
29392939
Py_FdIsInteractive(FILE *fp, const char *filename)
29402940
{
2941-
if (isatty((int)fileno(fp)))
2941+
if (isatty(fileno(fp))) {
29422942
return 1;
2943-
if (!Py_InteractiveFlag)
2943+
}
2944+
if (!_Py_GetConfig()->interactive) {
29442945
return 0;
2945-
return (filename == NULL) ||
2946-
(strcmp(filename, "<stdin>") == 0) ||
2947-
(strcmp(filename, "???") == 0);
2946+
}
2947+
return ((filename == NULL)
2948+
|| (strcmp(filename, "<stdin>") == 0)
2949+
|| (strcmp(filename, "???") == 0));
29482950
}
29492951

29502952

29512953
int
29522954
_Py_FdIsInteractive(FILE *fp, PyObject *filename)
29532955
{
2954-
if (isatty((int)fileno(fp))) {
2956+
if (isatty(fileno(fp))) {
29552957
return 1;
29562958
}
2957-
if (!Py_InteractiveFlag) {
2959+
if (!_Py_GetConfig()->interactive) {
29582960
return 0;
29592961
}
2960-
return (filename == NULL) ||
2961-
(PyUnicode_CompareWithASCIIString(filename, "<stdin>") == 0) ||
2962-
(PyUnicode_CompareWithASCIIString(filename, "???") == 0);
2962+
return ((filename == NULL)
2963+
|| (PyUnicode_CompareWithASCIIString(filename, "<stdin>") == 0)
2964+
|| (PyUnicode_CompareWithASCIIString(filename, "???") == 0));
29632965
}
29642966

29652967

Python/pystate.c

+1
Original file line numberDiff line numberDiff line change
@@ -2136,6 +2136,7 @@ _Py_GetConfig(void)
21362136
{
21372137
assert(PyGILState_Check());
21382138
PyThreadState *tstate = _PyThreadState_GET();
2139+
_Py_EnsureTstateNotNULL(tstate);
21392140
return _PyInterpreterState_GetConfig(tstate->interp);
21402141
}
21412142

0 commit comments

Comments
 (0)