[3.13] gh-130163: Fix crashes related to PySys_GetObject() (GH-130503) (GH-130556)

The use of PySys_GetObject() and _PySys_GetAttr(), which return a borrowed
reference, has been replaced by using one of the following functions, which
return a strong reference and distinguish a missing attribute from an error:
_PySys_GetOptionalAttr(), _PySys_GetOptionalAttrString(),
_PySys_GetRequiredAttr(), and _PySys_GetRequiredAttrString().
(cherry picked from commit 0ef4ffeefd)
This commit is contained in:
Serhiy Storchaka 2025-02-26 00:50:26 +02:00 committed by GitHub
parent b0d3f49195
commit 7c1b76fce8
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
23 changed files with 505 additions and 180 deletions

View File

@ -8,8 +8,11 @@ extern "C" {
# error "this header requires Py_BUILD_CORE define" # error "this header requires Py_BUILD_CORE define"
#endif #endif
// Export for '_pickle' shared extension PyAPI_FUNC(PyObject *) _PySys_GetAttr(PyThreadState *, PyObject *); /* unused */
PyAPI_FUNC(PyObject*) _PySys_GetAttr(PyThreadState *tstate, PyObject *name); PyAPI_FUNC(int) _PySys_GetOptionalAttr(PyObject *, PyObject **);
PyAPI_FUNC(int) _PySys_GetOptionalAttrString(const char *, PyObject **);
PyAPI_FUNC(PyObject *) _PySys_GetRequiredAttr(PyObject *);
PyAPI_FUNC(PyObject *) _PySys_GetRequiredAttrString(const char *);
// Export for '_pickle' shared extension // Export for '_pickle' shared extension
PyAPI_FUNC(size_t) _PySys_GetSizeOf(PyObject *); PyAPI_FUNC(size_t) _PySys_GetSizeOf(PyObject *);

View File

@ -1576,6 +1576,29 @@ def test_input(self):
sys.stdout = savestdout sys.stdout = savestdout
fp.close() fp.close()
def test_input_gh130163(self):
class X(io.StringIO):
def __getattribute__(self, name):
nonlocal patch
if patch:
patch = False
sys.stdout = X()
sys.stderr = X()
sys.stdin = X('input\n')
support.gc_collect()
return io.StringIO.__getattribute__(self, name)
with (support.swap_attr(sys, 'stdout', None),
support.swap_attr(sys, 'stderr', None),
support.swap_attr(sys, 'stdin', None)):
patch = False
# the only references:
sys.stdout = X()
sys.stderr = X()
sys.stdin = X('input\n')
patch = True
input() # should not crash
# test_int(): see test_int.py for tests of built-in function int(). # test_int(): see test_int.py for tests of built-in function int().
def test_repr(self): def test_repr(self):

View File

@ -129,6 +129,17 @@ def flush(self):
raise RuntimeError raise RuntimeError
self.assertRaises(RuntimeError, print, 1, file=noflush(), flush=True) self.assertRaises(RuntimeError, print, 1, file=noflush(), flush=True)
def test_gh130163(self):
class X:
def __str__(self):
sys.stdout = StringIO()
support.gc_collect()
return 'foo'
with support.swap_attr(sys, 'stdout', None):
sys.stdout = StringIO() # the only reference
print(X()) # should not crash
class TestPy2MigrationHint(unittest.TestCase): class TestPy2MigrationHint(unittest.TestCase):
"""Test that correct hint is produced analogous to Python3 syntax, """Test that correct hint is produced analogous to Python3 syntax,

View File

@ -2,6 +2,7 @@
import codecs import codecs
import _datetime import _datetime
import gc import gc
import io
import locale import locale
import operator import operator
import os import os
@ -80,6 +81,18 @@ def baddisplayhook(obj):
code = compile("42", "<string>", "single") code = compile("42", "<string>", "single")
self.assertRaises(ValueError, eval, code) self.assertRaises(ValueError, eval, code)
def test_gh130163(self):
class X:
def __repr__(self):
sys.stdout = io.StringIO()
support.gc_collect()
return 'foo'
with support.swap_attr(sys, 'stdout', None):
sys.stdout = io.StringIO() # the only reference
sys.displayhook(X()) # should not crash
class ActiveExceptionTests(unittest.TestCase): class ActiveExceptionTests(unittest.TestCase):
def test_exc_info_no_exception(self): def test_exc_info_no_exception(self):
self.assertEqual(sys.exc_info(), (None, None, None)) self.assertEqual(sys.exc_info(), (None, None, None))

View File

@ -0,0 +1,2 @@
Fix possible crashes related to concurrent
change and use of the :mod:`sys` module attributes.

View File

@ -107,6 +107,7 @@ static const char PyCursesVersion[] = "2.2";
#include "Python.h" #include "Python.h"
#include "pycore_long.h" // _PyLong_GetZero() #include "pycore_long.h" // _PyLong_GetZero()
#include "pycore_structseq.h" // _PyStructSequence_NewType() #include "pycore_structseq.h" // _PyStructSequence_NewType()
#include "pycore_sysmodule.h" // _PySys_GetOptionalAttrString()
#ifdef __hpux #ifdef __hpux
#define STRICT_SYSV_CURSES #define STRICT_SYSV_CURSES
@ -3375,17 +3376,20 @@ _curses_setupterm_impl(PyObject *module, const char *term, int fd)
if (fd == -1) { if (fd == -1) {
PyObject* sys_stdout; PyObject* sys_stdout;
sys_stdout = PySys_GetObject("stdout"); if (_PySys_GetOptionalAttrString("stdout", &sys_stdout) < 0) {
return NULL;
}
if (sys_stdout == NULL || sys_stdout == Py_None) { if (sys_stdout == NULL || sys_stdout == Py_None) {
PyErr_SetString( PyErr_SetString(
PyCursesError, PyCursesError,
"lost sys.stdout"); "lost sys.stdout");
Py_XDECREF(sys_stdout);
return NULL; return NULL;
} }
fd = PyObject_AsFileDescriptor(sys_stdout); fd = PyObject_AsFileDescriptor(sys_stdout);
Py_DECREF(sys_stdout);
if (fd == -1) { if (fd == -1) {
return NULL; return NULL;
} }

View File

@ -18,7 +18,7 @@
#include "pycore_pystate.h" // _PyThreadState_GET() #include "pycore_pystate.h" // _PyThreadState_GET()
#include "pycore_runtime.h" // _Py_ID() #include "pycore_runtime.h" // _Py_ID()
#include "pycore_setobject.h" // _PySet_NextEntry() #include "pycore_setobject.h" // _PySet_NextEntry()
#include "pycore_sysmodule.h" // _PySys_GetAttr() #include "pycore_sysmodule.h" // _PySys_GetSizeOf()
#include <stdlib.h> // strtol() #include <stdlib.h> // strtol()
@ -1930,10 +1930,8 @@ whichmodule(PyObject *global, PyObject *dotted_path)
assert(module_name == NULL); assert(module_name == NULL);
/* Fallback on walking sys.modules */ /* Fallback on walking sys.modules */
PyThreadState *tstate = _PyThreadState_GET(); modules = _PySys_GetRequiredAttr(&_Py_ID(modules));
modules = _PySys_GetAttr(tstate, &_Py_ID(modules));
if (modules == NULL) { if (modules == NULL) {
PyErr_SetString(PyExc_RuntimeError, "unable to get sys.modules");
return NULL; return NULL;
} }
if (PyDict_CheckExact(modules)) { if (PyDict_CheckExact(modules)) {

View File

@ -8,7 +8,7 @@
#include "pycore_modsupport.h" // _PyArg_NoKeywords() #include "pycore_modsupport.h" // _PyArg_NoKeywords()
#include "pycore_pylifecycle.h" #include "pycore_pylifecycle.h"
#include "pycore_pystate.h" // _PyThreadState_SetCurrent() #include "pycore_pystate.h" // _PyThreadState_SetCurrent()
#include "pycore_sysmodule.h" // _PySys_GetAttr() #include "pycore_sysmodule.h" // _PySys_GetOptionalAttr()
#include "pycore_time.h" // _PyTime_FromSeconds() #include "pycore_time.h" // _PyTime_FromSeconds()
#include "pycore_weakref.h" // _PyWeakref_GET_REF() #include "pycore_weakref.h" // _PyWeakref_GET_REF()
@ -2275,9 +2275,12 @@ thread_excepthook(PyObject *module, PyObject *args)
PyObject *exc_tb = PyStructSequence_GET_ITEM(args, 2); PyObject *exc_tb = PyStructSequence_GET_ITEM(args, 2);
PyObject *thread = PyStructSequence_GET_ITEM(args, 3); PyObject *thread = PyStructSequence_GET_ITEM(args, 3);
PyThreadState *tstate = _PyThreadState_GET(); PyObject *file;
PyObject *file = _PySys_GetAttr(tstate, &_Py_ID(stderr)); if (_PySys_GetOptionalAttr( &_Py_ID(stderr), &file) < 0) {
return NULL;
}
if (file == NULL || file == Py_None) { if (file == NULL || file == Py_None) {
Py_XDECREF(file);
if (thread == Py_None) { if (thread == Py_None) {
/* do nothing if sys.stderr is None and thread is None */ /* do nothing if sys.stderr is None and thread is None */
Py_RETURN_NONE; Py_RETURN_NONE;
@ -2294,9 +2297,6 @@ thread_excepthook(PyObject *module, PyObject *args)
Py_RETURN_NONE; Py_RETURN_NONE;
} }
} }
else {
Py_INCREF(file);
}
int res = thread_excepthook_file(file, exc_type, exc_value, exc_tb, int res = thread_excepthook_file(file, exc_type, exc_value, exc_tb,
thread); thread);

View File

@ -31,6 +31,7 @@ Copyright (C) 1994 Steen Lumholt.
#endif #endif
#include "pycore_long.h" // _PyLong_IsNegative() #include "pycore_long.h" // _PyLong_IsNegative()
#include "pycore_sysmodule.h" // _PySys_GetOptionalAttrString()
#ifdef MS_WINDOWS #ifdef MS_WINDOWS
# include <windows.h> # include <windows.h>
@ -142,8 +143,9 @@ _get_tcl_lib_path(void)
if (already_checked == 0) { if (already_checked == 0) {
struct stat stat_buf; struct stat stat_buf;
int stat_return_value; int stat_return_value;
PyObject *prefix;
PyObject *prefix = PySys_GetObject("base_prefix"); // borrowed reference (void) _PySys_GetOptionalAttrString("base_prefix", &prefix);
if (prefix == NULL) { if (prefix == NULL) {
return NULL; return NULL;
} }
@ -151,9 +153,11 @@ _get_tcl_lib_path(void)
/* Check expected location for an installed Python first */ /* Check expected location for an installed Python first */
tcl_library_path = PyUnicode_FromString("\\tcl\\tcl" TCL_VERSION); tcl_library_path = PyUnicode_FromString("\\tcl\\tcl" TCL_VERSION);
if (tcl_library_path == NULL) { if (tcl_library_path == NULL) {
Py_DECREF(prefix);
return NULL; return NULL;
} }
tcl_library_path = PyUnicode_Concat(prefix, tcl_library_path); tcl_library_path = PyUnicode_Concat(prefix, tcl_library_path);
Py_DECREF(prefix);
if (tcl_library_path == NULL) { if (tcl_library_path == NULL) {
return NULL; return NULL;
} }
@ -3485,9 +3489,10 @@ PyInit__tkinter(void)
/* This helps the dynamic loader; in Unicode aware Tcl versions /* This helps the dynamic loader; in Unicode aware Tcl versions
it also helps Tcl find its encodings. */ it also helps Tcl find its encodings. */
uexe = PySys_GetObject("executable"); // borrowed reference (void) _PySys_GetOptionalAttrString("executable", &uexe);
if (uexe && PyUnicode_Check(uexe)) { // sys.executable can be None if (uexe && PyUnicode_Check(uexe)) { // sys.executable can be None
cexe = PyUnicode_EncodeFSDefault(uexe); cexe = PyUnicode_EncodeFSDefault(uexe);
Py_DECREF(uexe);
if (cexe) { if (cexe) {
#ifdef MS_WINDOWS #ifdef MS_WINDOWS
int set_var = 0; int set_var = 0;
@ -3500,12 +3505,14 @@ PyInit__tkinter(void)
if (!ret && GetLastError() == ERROR_ENVVAR_NOT_FOUND) { if (!ret && GetLastError() == ERROR_ENVVAR_NOT_FOUND) {
str_path = _get_tcl_lib_path(); str_path = _get_tcl_lib_path();
if (str_path == NULL && PyErr_Occurred()) { if (str_path == NULL && PyErr_Occurred()) {
Py_DECREF(cexe);
Py_DECREF(m); Py_DECREF(m);
return NULL; return NULL;
} }
if (str_path != NULL) { if (str_path != NULL) {
wcs_path = PyUnicode_AsWideCharString(str_path, NULL); wcs_path = PyUnicode_AsWideCharString(str_path, NULL);
if (wcs_path == NULL) { if (wcs_path == NULL) {
Py_DECREF(cexe);
Py_DECREF(m); Py_DECREF(m);
return NULL; return NULL;
} }
@ -3526,6 +3533,9 @@ PyInit__tkinter(void)
} }
Py_XDECREF(cexe); Py_XDECREF(cexe);
} }
else {
Py_XDECREF(uexe);
}
if (PyErr_Occurred()) { if (PyErr_Occurred()) {
Py_DECREF(m); Py_DECREF(m);

View File

@ -3,7 +3,7 @@
#include "pycore_pyerrors.h" // _Py_DumpExtensionModules #include "pycore_pyerrors.h" // _Py_DumpExtensionModules
#include "pycore_pystate.h" // _PyThreadState_GET() #include "pycore_pystate.h" // _PyThreadState_GET()
#include "pycore_signal.h" // Py_NSIG #include "pycore_signal.h" // Py_NSIG
#include "pycore_sysmodule.h" // _PySys_GetAttr() #include "pycore_sysmodule.h" // _PySys_GetRequiredAttr()
#include "pycore_time.h" // _PyTime_FromSecondsObject() #include "pycore_time.h" // _PyTime_FromSecondsObject()
#include "pycore_traceback.h" // _Py_DumpTracebackThreads #include "pycore_traceback.h" // _Py_DumpTracebackThreads
@ -109,14 +109,13 @@ faulthandler_get_fileno(PyObject **file_ptr)
PyObject *file = *file_ptr; PyObject *file = *file_ptr;
if (file == NULL || file == Py_None) { if (file == NULL || file == Py_None) {
PyThreadState *tstate = _PyThreadState_GET(); file = _PySys_GetRequiredAttr(&_Py_ID(stderr));
file = _PySys_GetAttr(tstate, &_Py_ID(stderr));
if (file == NULL) { if (file == NULL) {
PyErr_SetString(PyExc_RuntimeError, "unable to get sys.stderr");
return -1; return -1;
} }
if (file == Py_None) { if (file == Py_None) {
PyErr_SetString(PyExc_RuntimeError, "sys.stderr is None"); PyErr_SetString(PyExc_RuntimeError, "sys.stderr is None");
Py_DECREF(file);
return -1; return -1;
} }
} }
@ -139,10 +138,15 @@ faulthandler_get_fileno(PyObject **file_ptr)
*file_ptr = NULL; *file_ptr = NULL;
return fd; return fd;
} }
else {
Py_INCREF(file);
}
result = PyObject_CallMethodNoArgs(file, &_Py_ID(fileno)); result = PyObject_CallMethodNoArgs(file, &_Py_ID(fileno));
if (result == NULL) if (result == NULL) {
Py_DECREF(file);
return -1; return -1;
}
fd = -1; fd = -1;
if (PyLong_Check(result)) { if (PyLong_Check(result)) {
@ -155,6 +159,7 @@ faulthandler_get_fileno(PyObject **file_ptr)
if (fd == -1) { if (fd == -1) {
PyErr_SetString(PyExc_RuntimeError, PyErr_SetString(PyExc_RuntimeError,
"file.fileno() is not a valid file descriptor"); "file.fileno() is not a valid file descriptor");
Py_DECREF(file);
return -1; return -1;
} }
@ -234,8 +239,10 @@ faulthandler_dump_traceback_py(PyObject *self,
return NULL; return NULL;
tstate = get_thread_state(); tstate = get_thread_state();
if (tstate == NULL) if (tstate == NULL) {
Py_XDECREF(file);
return NULL; return NULL;
}
if (all_threads) { if (all_threads) {
PyInterpreterState *interp = _PyInterpreterState_GET(); PyInterpreterState *interp = _PyInterpreterState_GET();
@ -246,12 +253,14 @@ faulthandler_dump_traceback_py(PyObject *self,
_PyEval_StartTheWorld(interp); _PyEval_StartTheWorld(interp);
if (errmsg != NULL) { if (errmsg != NULL) {
PyErr_SetString(PyExc_RuntimeError, errmsg); PyErr_SetString(PyExc_RuntimeError, errmsg);
Py_XDECREF(file);
return NULL; return NULL;
} }
} }
else { else {
_Py_DumpTraceback(fd, tstate); _Py_DumpTraceback(fd, tstate);
} }
Py_XDECREF(file);
if (PyErr_CheckSignals()) if (PyErr_CheckSignals())
return NULL; return NULL;
@ -513,10 +522,11 @@ faulthandler_py_enable(PyObject *self, PyObject *args, PyObject *kwargs)
return NULL; return NULL;
tstate = get_thread_state(); tstate = get_thread_state();
if (tstate == NULL) if (tstate == NULL) {
Py_XDECREF(file);
return NULL; return NULL;
}
Py_XINCREF(file);
Py_XSETREF(fatal_error.file, file); Py_XSETREF(fatal_error.file, file);
fatal_error.fd = fd; fatal_error.fd = fd;
fatal_error.all_threads = all_threads; fatal_error.all_threads = all_threads;
@ -706,12 +716,14 @@ faulthandler_dump_traceback_later(PyObject *self,
if (!thread.running) { if (!thread.running) {
thread.running = PyThread_allocate_lock(); thread.running = PyThread_allocate_lock();
if (!thread.running) { if (!thread.running) {
Py_XDECREF(file);
return PyErr_NoMemory(); return PyErr_NoMemory();
} }
} }
if (!thread.cancel_event) { if (!thread.cancel_event) {
thread.cancel_event = PyThread_allocate_lock(); thread.cancel_event = PyThread_allocate_lock();
if (!thread.cancel_event || !thread.running) { if (!thread.cancel_event || !thread.running) {
Py_XDECREF(file);
return PyErr_NoMemory(); return PyErr_NoMemory();
} }
@ -723,6 +735,7 @@ faulthandler_dump_traceback_later(PyObject *self,
/* format the timeout */ /* format the timeout */
header = format_timeout(timeout_us); header = format_timeout(timeout_us);
if (header == NULL) { if (header == NULL) {
Py_XDECREF(file);
return PyErr_NoMemory(); return PyErr_NoMemory();
} }
header_len = strlen(header); header_len = strlen(header);
@ -730,7 +743,6 @@ faulthandler_dump_traceback_later(PyObject *self,
/* Cancel previous thread, if running */ /* Cancel previous thread, if running */
cancel_dump_traceback_later(); cancel_dump_traceback_later();
Py_XINCREF(file);
Py_XSETREF(thread.file, file); Py_XSETREF(thread.file, file);
thread.fd = fd; thread.fd = fd;
/* the downcast is safe: we check that 0 < timeout_us < PY_TIMEOUT_MAX */ /* the downcast is safe: we check that 0 < timeout_us < PY_TIMEOUT_MAX */
@ -892,14 +904,17 @@ faulthandler_register_py(PyObject *self,
if (user_signals == NULL) { if (user_signals == NULL) {
user_signals = PyMem_Calloc(Py_NSIG, sizeof(user_signal_t)); user_signals = PyMem_Calloc(Py_NSIG, sizeof(user_signal_t));
if (user_signals == NULL) if (user_signals == NULL) {
Py_XDECREF(file);
return PyErr_NoMemory(); return PyErr_NoMemory();
} }
}
user = &user_signals[signum]; user = &user_signals[signum];
if (!user->enabled) { if (!user->enabled) {
#ifdef FAULTHANDLER_USE_ALT_STACK #ifdef FAULTHANDLER_USE_ALT_STACK
if (faulthandler_allocate_stack() < 0) { if (faulthandler_allocate_stack() < 0) {
Py_XDECREF(file);
return NULL; return NULL;
} }
#endif #endif
@ -907,13 +922,13 @@ faulthandler_register_py(PyObject *self,
err = faulthandler_register(signum, chain, &previous); err = faulthandler_register(signum, chain, &previous);
if (err) { if (err) {
PyErr_SetFromErrno(PyExc_OSError); PyErr_SetFromErrno(PyExc_OSError);
Py_XDECREF(file);
return NULL; return NULL;
} }
user->previous = previous; user->previous = previous;
} }
Py_XINCREF(file);
Py_XSETREF(user->file, file); Py_XSETREF(user->file, file);
user->fd = fd; user->fd = fd;
user->all_threads = all_threads; user->all_threads = all_threads;

View File

@ -56,6 +56,7 @@ Revision history:
#include "Python.h" #include "Python.h"
#include "osdefs.h" // SEP #include "osdefs.h" // SEP
#include "pycore_sysmodule.h" // _PySys_GetOptionalAttrString()
#include <syslog.h> #include <syslog.h>
@ -89,45 +90,50 @@ syslog_get_argv(void)
Py_ssize_t argv_len, scriptlen; Py_ssize_t argv_len, scriptlen;
PyObject *scriptobj; PyObject *scriptobj;
Py_ssize_t slash; Py_ssize_t slash;
PyObject *argv = PySys_GetObject("argv"); PyObject *argv;
if (argv == NULL) { if (_PySys_GetOptionalAttrString("argv", &argv) <= 0) {
return(NULL); return NULL;
} }
argv_len = PyList_Size(argv); argv_len = PyList_Size(argv);
if (argv_len == -1) { if (argv_len == -1) {
PyErr_Clear(); PyErr_Clear();
return(NULL); Py_DECREF(argv);
return NULL;
} }
if (argv_len == 0) { if (argv_len == 0) {
return(NULL); Py_DECREF(argv);
return NULL;
} }
scriptobj = PyList_GetItem(argv, 0); scriptobj = PyList_GetItem(argv, 0);
Py_XINCREF(scriptobj);
Py_DECREF(argv);
if (scriptobj == NULL) { if (scriptobj == NULL) {
PyErr_Clear(); PyErr_Clear();
return NULL; return NULL;
} }
if (!PyUnicode_Check(scriptobj)) { if (!PyUnicode_Check(scriptobj)) {
return(NULL); Py_DECREF(scriptobj);
return NULL;
} }
scriptlen = PyUnicode_GET_LENGTH(scriptobj); scriptlen = PyUnicode_GET_LENGTH(scriptobj);
if (scriptlen == 0) { if (scriptlen == 0) {
return(NULL); Py_DECREF(scriptobj);
return NULL;
} }
slash = PyUnicode_FindChar(scriptobj, SEP, 0, scriptlen, -1); slash = PyUnicode_FindChar(scriptobj, SEP, 0, scriptlen, -1);
if (slash == -2) { if (slash == -2) {
PyErr_Clear(); PyErr_Clear();
Py_DECREF(scriptobj);
return NULL; return NULL;
} }
if (slash != -1) { if (slash != -1) {
return PyUnicode_Substring(scriptobj, slash + 1, scriptlen); Py_SETREF(scriptobj, PyUnicode_Substring(scriptobj, slash + 1, scriptlen));
} else {
Py_INCREF(scriptobj);
return(scriptobj);
} }
return scriptobj;
} }
@ -162,6 +168,9 @@ syslog_openlog_impl(PyObject *module, PyObject *ident, long logopt,
else { else {
/* get sys.argv[0] or NULL if we can't for some reason */ /* get sys.argv[0] or NULL if we can't for some reason */
ident = syslog_get_argv(); ident = syslog_get_argv();
if (ident == NULL && PyErr_Occurred()) {
return NULL;
}
} }
/* At this point, ident should be INCREF()ed. openlog(3) does not /* At this point, ident should be INCREF()ed. openlog(3) does not

View File

@ -10,6 +10,7 @@
#include "pycore_object.h" // _PyType_AllocNoTrack #include "pycore_object.h" // _PyType_AllocNoTrack
#include "pycore_pyerrors.h" // _PyErr_FormatFromCause() #include "pycore_pyerrors.h" // _PyErr_FormatFromCause()
#include "pycore_pystate.h" // _PyInterpreterState_GET() #include "pycore_pystate.h" // _PyInterpreterState_GET()
#include "pycore_sysmodule.h" // _PySys_GetOptionalAttrString()
#include "osdefs.h" // MAXPATHLEN #include "osdefs.h" // MAXPATHLEN
@ -990,13 +991,18 @@ _Py_module_getattro_impl(PyModuleObject *m, PyObject *name, int suppress)
} }
int is_possibly_shadowing_stdlib = 0; int is_possibly_shadowing_stdlib = 0;
if (is_possibly_shadowing) { if (is_possibly_shadowing) {
PyObject *stdlib_modules = PySys_GetObject("stdlib_module_names"); PyObject *stdlib_modules;
if (_PySys_GetOptionalAttrString("stdlib_module_names", &stdlib_modules) < 0) {
goto done;
}
if (stdlib_modules && PyAnySet_Check(stdlib_modules)) { if (stdlib_modules && PyAnySet_Check(stdlib_modules)) {
is_possibly_shadowing_stdlib = PySet_Contains(stdlib_modules, mod_name); is_possibly_shadowing_stdlib = PySet_Contains(stdlib_modules, mod_name);
if (is_possibly_shadowing_stdlib < 0) { if (is_possibly_shadowing_stdlib < 0) {
Py_DECREF(stdlib_modules);
goto done; goto done;
} }
} }
Py_XDECREF(stdlib_modules);
} }
if (is_possibly_shadowing_stdlib) { if (is_possibly_shadowing_stdlib) {

View File

@ -5,7 +5,7 @@
#include "pycore_pyerrors.h" // _PyErr_Occurred() #include "pycore_pyerrors.h" // _PyErr_Occurred()
#include "pycore_pylifecycle.h" // _Py_IsInterpreterFinalizing() #include "pycore_pylifecycle.h" // _Py_IsInterpreterFinalizing()
#include "pycore_pystate.h" // _PyThreadState_GET() #include "pycore_pystate.h" // _PyThreadState_GET()
#include "pycore_sysmodule.h" // _PySys_GetAttr() #include "pycore_sysmodule.h" // _PySys_GetOptionalAttr()
#include "pycore_traceback.h" // _Py_DisplaySourceLine() #include "pycore_traceback.h" // _Py_DisplaySourceLine()
#include <stdbool.h> #include <stdbool.h>
@ -494,7 +494,7 @@ static void
show_warning(PyThreadState *tstate, PyObject *filename, int lineno, show_warning(PyThreadState *tstate, PyObject *filename, int lineno,
PyObject *text, PyObject *category, PyObject *sourceline) PyObject *text, PyObject *category, PyObject *sourceline)
{ {
PyObject *f_stderr; PyObject *f_stderr = NULL;
PyObject *name; PyObject *name;
char lineno_str[128]; char lineno_str[128];
@ -505,8 +505,7 @@ show_warning(PyThreadState *tstate, PyObject *filename, int lineno,
goto error; goto error;
} }
f_stderr = _PySys_GetAttr(tstate, &_Py_ID(stderr)); if (_PySys_GetOptionalAttr(&_Py_ID(stderr), &f_stderr) <= 0) {
if (f_stderr == NULL) {
fprintf(stderr, "lost sys.stderr\n"); fprintf(stderr, "lost sys.stderr\n");
goto error; goto error;
} }
@ -556,6 +555,7 @@ show_warning(PyThreadState *tstate, PyObject *filename, int lineno,
} }
error: error:
Py_XDECREF(f_stderr);
Py_XDECREF(name); Py_XDECREF(name);
PyErr_Clear(); PyErr_Clear();
} }

View File

@ -11,7 +11,7 @@
#include "pycore_pyerrors.h" // _PyErr_NoMemory() #include "pycore_pyerrors.h" // _PyErr_NoMemory()
#include "pycore_pystate.h" // _PyThreadState_GET() #include "pycore_pystate.h" // _PyThreadState_GET()
#include "pycore_pythonrun.h" // _Py_SourceAsString() #include "pycore_pythonrun.h" // _Py_SourceAsString()
#include "pycore_sysmodule.h" // _PySys_GetAttr() #include "pycore_sysmodule.h" // _PySys_GetRequiredAttr()
#include "pycore_tuple.h" // _PyTuple_FromArray() #include "pycore_tuple.h" // _PyTuple_FromArray()
#include "clinic/bltinmodule.c.h" #include "clinic/bltinmodule.c.h"
@ -457,18 +457,16 @@ builtin_callable(PyObject *module, PyObject *obj)
static PyObject * static PyObject *
builtin_breakpoint(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *keywords) builtin_breakpoint(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *keywords)
{ {
PyObject *hook = PySys_GetObject("breakpointhook"); PyObject *hook = _PySys_GetRequiredAttrString("breakpointhook");
if (hook == NULL) { if (hook == NULL) {
PyErr_SetString(PyExc_RuntimeError, "lost sys.breakpointhook");
return NULL; return NULL;
} }
if (PySys_Audit("builtins.breakpoint", "O", hook) < 0) { if (PySys_Audit("builtins.breakpoint", "O", hook) < 0) {
Py_DECREF(hook);
return NULL; return NULL;
} }
Py_INCREF(hook);
PyObject *retval = PyObject_Vectorcall(hook, args, nargs, keywords); PyObject *retval = PyObject_Vectorcall(hook, args, nargs, keywords);
Py_DECREF(hook); Py_DECREF(hook);
return retval; return retval;
@ -2063,18 +2061,20 @@ builtin_print_impl(PyObject *module, PyObject *args, PyObject *sep,
int i, err; int i, err;
if (file == Py_None) { if (file == Py_None) {
PyThreadState *tstate = _PyThreadState_GET(); file = _PySys_GetRequiredAttr(&_Py_ID(stdout));
file = _PySys_GetAttr(tstate, &_Py_ID(stdout));
if (file == NULL) { if (file == NULL) {
PyErr_SetString(PyExc_RuntimeError, "lost sys.stdout");
return NULL; return NULL;
} }
/* sys.stdout may be None when FILE* stdout isn't connected */ /* sys.stdout may be None when FILE* stdout isn't connected */
if (file == Py_None) { if (file == Py_None) {
Py_DECREF(file);
Py_RETURN_NONE; Py_RETURN_NONE;
} }
} }
else {
Py_INCREF(file);
}
if (sep == Py_None) { if (sep == Py_None) {
sep = NULL; sep = NULL;
@ -2083,6 +2083,7 @@ builtin_print_impl(PyObject *module, PyObject *args, PyObject *sep,
PyErr_Format(PyExc_TypeError, PyErr_Format(PyExc_TypeError,
"sep must be None or a string, not %.200s", "sep must be None or a string, not %.200s",
Py_TYPE(sep)->tp_name); Py_TYPE(sep)->tp_name);
Py_DECREF(file);
return NULL; return NULL;
} }
if (end == Py_None) { if (end == Py_None) {
@ -2092,6 +2093,7 @@ builtin_print_impl(PyObject *module, PyObject *args, PyObject *sep,
PyErr_Format(PyExc_TypeError, PyErr_Format(PyExc_TypeError,
"end must be None or a string, not %.200s", "end must be None or a string, not %.200s",
Py_TYPE(end)->tp_name); Py_TYPE(end)->tp_name);
Py_DECREF(file);
return NULL; return NULL;
} }
@ -2104,11 +2106,13 @@ builtin_print_impl(PyObject *module, PyObject *args, PyObject *sep,
err = PyFile_WriteObject(sep, file, Py_PRINT_RAW); err = PyFile_WriteObject(sep, file, Py_PRINT_RAW);
} }
if (err) { if (err) {
Py_DECREF(file);
return NULL; return NULL;
} }
} }
err = PyFile_WriteObject(PyTuple_GET_ITEM(args, i), file, Py_PRINT_RAW); err = PyFile_WriteObject(PyTuple_GET_ITEM(args, i), file, Py_PRINT_RAW);
if (err) { if (err) {
Py_DECREF(file);
return NULL; return NULL;
} }
} }
@ -2120,14 +2124,17 @@ builtin_print_impl(PyObject *module, PyObject *args, PyObject *sep,
err = PyFile_WriteObject(end, file, Py_PRINT_RAW); err = PyFile_WriteObject(end, file, Py_PRINT_RAW);
} }
if (err) { if (err) {
Py_DECREF(file);
return NULL; return NULL;
} }
if (flush) { if (flush) {
if (_PyFile_Flush(file) < 0) { if (_PyFile_Flush(file) < 0) {
Py_DECREF(file);
return NULL; return NULL;
} }
} }
Py_DECREF(file);
Py_RETURN_NONE; Py_RETURN_NONE;
} }
@ -2152,36 +2159,41 @@ static PyObject *
builtin_input_impl(PyObject *module, PyObject *prompt) builtin_input_impl(PyObject *module, PyObject *prompt)
/*[clinic end generated code: output=83db5a191e7a0d60 input=159c46d4ae40977e]*/ /*[clinic end generated code: output=83db5a191e7a0d60 input=159c46d4ae40977e]*/
{ {
PyThreadState *tstate = _PyThreadState_GET(); PyObject *fin = NULL;
PyObject *fin = _PySys_GetAttr( PyObject *fout = NULL;
tstate, &_Py_ID(stdin)); PyObject *ferr = NULL;
PyObject *fout = _PySys_GetAttr(
tstate, &_Py_ID(stdout));
PyObject *ferr = _PySys_GetAttr(
tstate, &_Py_ID(stderr));
PyObject *tmp; PyObject *tmp;
long fd; long fd;
int tty; int tty;
/* Check that stdin/out/err are intact */ /* Check that stdin/out/err are intact */
if (fin == NULL || fin == Py_None) { fin = _PySys_GetRequiredAttr(&_Py_ID(stdin));
PyErr_SetString(PyExc_RuntimeError, if (fin == NULL) {
"input(): lost sys.stdin"); goto error;
return NULL;
} }
if (fout == NULL || fout == Py_None) { if (fin == Py_None) {
PyErr_SetString(PyExc_RuntimeError, PyErr_SetString(PyExc_RuntimeError, "lost sys.stdin");
"input(): lost sys.stdout"); goto error;
return NULL;
} }
if (ferr == NULL || ferr == Py_None) { fout = _PySys_GetRequiredAttr(&_Py_ID(stdout));
PyErr_SetString(PyExc_RuntimeError, if (fout == NULL) {
"input(): lost sys.stderr"); goto error;
return NULL; }
if (fout == Py_None) {
PyErr_SetString(PyExc_RuntimeError, "lost sys.stdout");
goto error;
}
ferr = _PySys_GetRequiredAttr(&_Py_ID(stderr));
if (ferr == NULL) {
goto error;
}
if (ferr == Py_None) {
PyErr_SetString(PyExc_RuntimeError, "lost sys.stderr");
goto error;
} }
if (PySys_Audit("builtins.input", "O", prompt ? prompt : Py_None) < 0) { if (PySys_Audit("builtins.input", "O", prompt ? prompt : Py_None) < 0) {
return NULL; goto error;
} }
/* First of all, flush stderr */ /* First of all, flush stderr */
@ -2200,8 +2212,9 @@ builtin_input_impl(PyObject *module, PyObject *prompt)
else { else {
fd = PyLong_AsLong(tmp); fd = PyLong_AsLong(tmp);
Py_DECREF(tmp); Py_DECREF(tmp);
if (fd < 0 && PyErr_Occurred()) if (fd < 0 && PyErr_Occurred()) {
return NULL; goto error;
}
tty = fd == fileno(stdin) && isatty(fd); tty = fd == fileno(stdin) && isatty(fd);
} }
if (tty) { if (tty) {
@ -2214,7 +2227,7 @@ builtin_input_impl(PyObject *module, PyObject *prompt)
fd = PyLong_AsLong(tmp); fd = PyLong_AsLong(tmp);
Py_DECREF(tmp); Py_DECREF(tmp);
if (fd < 0 && PyErr_Occurred()) if (fd < 0 && PyErr_Occurred())
return NULL; goto error;
tty = fd == fileno(stdout) && isatty(fd); tty = fd == fileno(stdout) && isatty(fd);
} }
} }
@ -2342,10 +2355,13 @@ builtin_input_impl(PyObject *module, PyObject *prompt)
if (result != NULL) { if (result != NULL) {
if (PySys_Audit("builtins.input/result", "O", result) < 0) { if (PySys_Audit("builtins.input/result", "O", result) < 0) {
return NULL; goto error;
} }
} }
Py_DECREF(fin);
Py_DECREF(fout);
Py_DECREF(ferr);
return result; return result;
_readline_errors: _readline_errors:
@ -2355,7 +2371,7 @@ builtin_input_impl(PyObject *module, PyObject *prompt)
Py_XDECREF(stdout_errors); Py_XDECREF(stdout_errors);
Py_XDECREF(po); Py_XDECREF(po);
if (tty) if (tty)
return NULL; goto error;
PyErr_Clear(); PyErr_Clear();
} }
@ -2363,12 +2379,22 @@ builtin_input_impl(PyObject *module, PyObject *prompt)
/* Fallback if we're not interactive */ /* Fallback if we're not interactive */
if (prompt != NULL) { if (prompt != NULL) {
if (PyFile_WriteObject(prompt, fout, Py_PRINT_RAW) != 0) if (PyFile_WriteObject(prompt, fout, Py_PRINT_RAW) != 0)
return NULL; goto error;
} }
if (_PyFile_Flush(fout) < 0) { if (_PyFile_Flush(fout) < 0) {
PyErr_Clear(); PyErr_Clear();
} }
return PyFile_GetLine(fin, -1); tmp = PyFile_GetLine(fin, -1);
Py_DECREF(fin);
Py_DECREF(fout);
Py_DECREF(ferr);
return tmp;
error:
Py_XDECREF(fin);
Py_XDECREF(fout);
Py_XDECREF(ferr);
return NULL;
} }

View File

@ -32,6 +32,7 @@
#include "pycore_typeobject.h" // _PySuper_Lookup() #include "pycore_typeobject.h" // _PySuper_Lookup()
#include "pycore_uop_ids.h" // Uops #include "pycore_uop_ids.h" // Uops
#include "pycore_pyerrors.h" #include "pycore_pyerrors.h"
#include "pycore_sysmodule.h" // _PySys_GetOptionalAttrString()
#include "pycore_dict.h" #include "pycore_dict.h"
#include "dictobject.h" #include "dictobject.h"
@ -2805,13 +2806,18 @@ import_from(PyThreadState *tstate, PyObject *v, PyObject *name)
} }
int is_possibly_shadowing_stdlib = 0; int is_possibly_shadowing_stdlib = 0;
if (is_possibly_shadowing) { if (is_possibly_shadowing) {
PyObject *stdlib_modules = PySys_GetObject("stdlib_module_names"); PyObject *stdlib_modules;
if (_PySys_GetOptionalAttrString("stdlib_module_names", &stdlib_modules) < 0) {
goto done;
}
if (stdlib_modules && PyAnySet_Check(stdlib_modules)) { if (stdlib_modules && PyAnySet_Check(stdlib_modules)) {
is_possibly_shadowing_stdlib = PySet_Contains(stdlib_modules, mod_name_or_unknown); is_possibly_shadowing_stdlib = PySet_Contains(stdlib_modules, mod_name_or_unknown);
if (is_possibly_shadowing_stdlib < 0) { if (is_possibly_shadowing_stdlib < 0) {
Py_DECREF(stdlib_modules);
goto done; goto done;
} }
} }
Py_XDECREF(stdlib_modules);
} }
if (origin == NULL && PyModule_Check(v)) { if (origin == NULL && PyModule_Check(v)) {

View File

@ -1530,14 +1530,15 @@ write_unraisable_exc(PyThreadState *tstate, PyObject *exc_type,
PyObject *exc_value, PyObject *exc_tb, PyObject *err_msg, PyObject *exc_value, PyObject *exc_tb, PyObject *err_msg,
PyObject *obj) PyObject *obj)
{ {
PyObject *file = _PySys_GetAttr(tstate, &_Py_ID(stderr)); PyObject *file;
if (_PySys_GetOptionalAttr(&_Py_ID(stderr), &file) < 0) {
return -1;
}
if (file == NULL || file == Py_None) { if (file == NULL || file == Py_None) {
Py_XDECREF(file);
return 0; return 0;
} }
/* Hold a strong reference to ensure that sys.stderr doesn't go away
while we use it */
Py_INCREF(file);
int res = write_unraisable_exc_file(tstate, exc_type, exc_value, exc_tb, int res = write_unraisable_exc_file(tstate, exc_type, exc_value, exc_tb,
err_msg, obj, file); err_msg, obj, file);
Py_DECREF(file); Py_DECREF(file);
@ -1636,13 +1637,20 @@ format_unraisable_v(const char *format, va_list va, PyObject *obj)
goto error; goto error;
} }
PyObject *hook = _PySys_GetAttr(tstate, &_Py_ID(unraisablehook)); PyObject *hook;
if (_PySys_GetOptionalAttr(&_Py_ID(unraisablehook), &hook) < 0) {
Py_DECREF(hook_args);
err_msg_str = NULL;
obj = NULL;
goto error;
}
if (hook == NULL) { if (hook == NULL) {
Py_DECREF(hook_args); Py_DECREF(hook_args);
goto default_hook; goto default_hook;
} }
if (_PySys_Audit(tstate, "sys.unraisablehook", "OO", hook, hook_args) < 0) { if (_PySys_Audit(tstate, "sys.unraisablehook", "OO", hook, hook_args) < 0) {
Py_DECREF(hook);
Py_DECREF(hook_args); Py_DECREF(hook_args);
err_msg_str = "Exception ignored in audit hook"; err_msg_str = "Exception ignored in audit hook";
obj = NULL; obj = NULL;
@ -1650,11 +1658,13 @@ format_unraisable_v(const char *format, va_list va, PyObject *obj)
} }
if (hook == Py_None) { if (hook == Py_None) {
Py_DECREF(hook);
Py_DECREF(hook_args); Py_DECREF(hook_args);
goto default_hook; goto default_hook;
} }
PyObject *res = PyObject_CallOneArg(hook, hook_args); PyObject *res = PyObject_CallOneArg(hook, hook_args);
Py_DECREF(hook);
Py_DECREF(hook_args); Py_DECREF(hook_args);
if (res != NULL) { if (res != NULL) {
Py_DECREF(res); Py_DECREF(res);

View File

@ -3341,19 +3341,15 @@ PyObject *
PyImport_GetImporter(PyObject *path) PyImport_GetImporter(PyObject *path)
{ {
PyThreadState *tstate = _PyThreadState_GET(); PyThreadState *tstate = _PyThreadState_GET();
PyObject *path_importer_cache = PySys_GetObject("path_importer_cache"); PyObject *path_importer_cache = _PySys_GetRequiredAttrString("path_importer_cache");
if (path_importer_cache == NULL) { if (path_importer_cache == NULL) {
PyErr_SetString(PyExc_RuntimeError, "lost sys.path_importer_cache");
return NULL; return NULL;
} }
Py_INCREF(path_importer_cache); PyObject *path_hooks = _PySys_GetRequiredAttrString("path_hooks");
PyObject *path_hooks = PySys_GetObject("path_hooks");
if (path_hooks == NULL) { if (path_hooks == NULL) {
PyErr_SetString(PyExc_RuntimeError, "lost sys.path_hooks");
Py_DECREF(path_importer_cache); Py_DECREF(path_importer_cache);
return NULL; return NULL;
} }
Py_INCREF(path_hooks);
PyObject *importer = get_path_importer(tstate, path_importer_cache, path_hooks, path); PyObject *importer = get_path_importer(tstate, path_importer_cache, path_hooks, path);
Py_DECREF(path_hooks); Py_DECREF(path_hooks);
Py_DECREF(path_importer_cache); Py_DECREF(path_importer_cache);
@ -3655,15 +3651,31 @@ import_find_and_load(PyThreadState *tstate, PyObject *abs_name)
PyTime_t t1 = 0, accumulated_copy = accumulated; PyTime_t t1 = 0, accumulated_copy = accumulated;
PyObject *sys_path = PySys_GetObject("path"); PyObject *sys_path, *sys_meta_path, *sys_path_hooks;
PyObject *sys_meta_path = PySys_GetObject("meta_path"); if (_PySys_GetOptionalAttrString("path", &sys_path) < 0) {
PyObject *sys_path_hooks = PySys_GetObject("path_hooks"); return NULL;
}
if (_PySys_GetOptionalAttrString("meta_path", &sys_meta_path) < 0) {
Py_XDECREF(sys_path);
return NULL;
}
if (_PySys_GetOptionalAttrString("path_hooks", &sys_path_hooks) < 0) {
Py_XDECREF(sys_meta_path);
Py_XDECREF(sys_path);
return NULL;
}
if (_PySys_Audit(tstate, "import", "OOOOO", if (_PySys_Audit(tstate, "import", "OOOOO",
abs_name, Py_None, sys_path ? sys_path : Py_None, abs_name, Py_None, sys_path ? sys_path : Py_None,
sys_meta_path ? sys_meta_path : Py_None, sys_meta_path ? sys_meta_path : Py_None,
sys_path_hooks ? sys_path_hooks : Py_None) < 0) { sys_path_hooks ? sys_path_hooks : Py_None) < 0) {
Py_XDECREF(sys_path_hooks);
Py_XDECREF(sys_meta_path);
Py_XDECREF(sys_path);
return NULL; return NULL;
} }
Py_XDECREF(sys_path_hooks);
Py_XDECREF(sys_meta_path);
Py_XDECREF(sys_path);
/* XOptions is initialized after first some imports. /* XOptions is initialized after first some imports.
@ -4111,10 +4123,8 @@ _PyImport_FiniCore(PyInterpreterState *interp)
static int static int
init_zipimport(PyThreadState *tstate, int verbose) init_zipimport(PyThreadState *tstate, int verbose)
{ {
PyObject *path_hooks = PySys_GetObject("path_hooks"); PyObject *path_hooks = _PySys_GetRequiredAttrString("path_hooks");
if (path_hooks == NULL) { if (path_hooks == NULL) {
_PyErr_SetString(tstate, PyExc_RuntimeError,
"unable to get sys.path_hooks");
return -1; return -1;
} }
@ -4134,12 +4144,14 @@ init_zipimport(PyThreadState *tstate, int verbose)
int err = PyList_Insert(path_hooks, 0, zipimporter); int err = PyList_Insert(path_hooks, 0, zipimporter);
Py_DECREF(zipimporter); Py_DECREF(zipimporter);
if (err < 0) { if (err < 0) {
Py_DECREF(path_hooks);
return -1; return -1;
} }
if (verbose) { if (verbose) {
PySys_WriteStderr("# installed zipimport hook\n"); PySys_WriteStderr("# installed zipimport hook\n");
} }
} }
Py_DECREF(path_hooks);
return 0; return 0;
} }

View File

@ -10,6 +10,7 @@
#include "pycore_pymem.h" // _PyMem_SetDefaultAllocator() #include "pycore_pymem.h" // _PyMem_SetDefaultAllocator()
#include "pycore_pystate.h" // _PyThreadState_GET() #include "pycore_pystate.h" // _PyThreadState_GET()
#include "pycore_pystats.h" // _Py_StatsOn() #include "pycore_pystats.h" // _Py_StatsOn()
#include "pycore_sysmodule.h" // _PySys_GetOptionalAttrString()
#include "osdefs.h" // DELIM #include "osdefs.h" // DELIM
@ -3232,10 +3233,13 @@ _Py_DumpPathConfig(PyThreadState *tstate)
#define DUMP_SYS(NAME) \ #define DUMP_SYS(NAME) \
do { \ do { \
obj = PySys_GetObject(#NAME); \
PySys_FormatStderr(" sys.%s = ", #NAME); \ PySys_FormatStderr(" sys.%s = ", #NAME); \
if (_PySys_GetOptionalAttrString(#NAME, &obj) < 0) { \
PyErr_Clear(); \
} \
if (obj != NULL) { \ if (obj != NULL) { \
PySys_FormatStderr("%A", obj); \ PySys_FormatStderr("%A", obj); \
Py_DECREF(obj); \
} \ } \
else { \ else { \
PySys_WriteStderr("(not set)"); \ PySys_WriteStderr("(not set)"); \
@ -3253,7 +3257,8 @@ _Py_DumpPathConfig(PyThreadState *tstate)
DUMP_SYS(exec_prefix); DUMP_SYS(exec_prefix);
#undef DUMP_SYS #undef DUMP_SYS
PyObject *sys_path = PySys_GetObject("path"); /* borrowed reference */ PyObject *sys_path;
(void) _PySys_GetOptionalAttrString("path", &sys_path);
if (sys_path != NULL && PyList_Check(sys_path)) { if (sys_path != NULL && PyList_Check(sys_path)) {
PySys_WriteStderr(" sys.path = [\n"); PySys_WriteStderr(" sys.path = [\n");
Py_ssize_t len = PyList_GET_SIZE(sys_path); Py_ssize_t len = PyList_GET_SIZE(sys_path);
@ -3263,6 +3268,7 @@ _Py_DumpPathConfig(PyThreadState *tstate)
} }
PySys_WriteStderr(" ]\n"); PySys_WriteStderr(" ]\n");
} }
Py_XDECREF(sys_path);
_PyErr_SetRaisedException(tstate, exc); _PyErr_SetRaisedException(tstate, exc);
} }

View File

@ -9,7 +9,7 @@
#include "pycore_intrinsics.h" // INTRINSIC_PRINT #include "pycore_intrinsics.h" // INTRINSIC_PRINT
#include "pycore_pyerrors.h" // _PyErr_SetString() #include "pycore_pyerrors.h" // _PyErr_SetString()
#include "pycore_runtime.h" // _Py_ID() #include "pycore_runtime.h" // _Py_ID()
#include "pycore_sysmodule.h" // _PySys_GetAttr() #include "pycore_sysmodule.h" // _PySys_GetRequiredAttr()
#include "pycore_typevarobject.h" // _Py_make_typevar() #include "pycore_typevarobject.h" // _Py_make_typevar()
@ -23,16 +23,16 @@ no_intrinsic1(PyThreadState* tstate, PyObject *unused)
} }
static PyObject * static PyObject *
print_expr(PyThreadState* tstate, PyObject *value) print_expr(PyThreadState* Py_UNUSED(ignored), PyObject *value)
{ {
PyObject *hook = _PySys_GetAttr(tstate, &_Py_ID(displayhook)); PyObject *hook = _PySys_GetRequiredAttr(&_Py_ID(displayhook));
// Can't use ERROR_IF here. // Can't use ERROR_IF here.
if (hook == NULL) { if (hook == NULL) {
_PyErr_SetString(tstate, PyExc_RuntimeError,
"lost sys.displayhook");
return NULL; return NULL;
} }
return PyObject_CallOneArg(hook, value); PyObject *res = PyObject_CallOneArg(hook, value);
Py_DECREF(hook);
return res;
} }
static int static int

View File

@ -1300,8 +1300,12 @@ init_interp_main(PyThreadState *tstate)
if (is_main_interp) { if (is_main_interp) {
/* Initialize warnings. */ /* Initialize warnings. */
PyObject *warnoptions = PySys_GetObject("warnoptions"); PyObject *warnoptions;
if (warnoptions != NULL && PyList_Size(warnoptions) > 0) if (_PySys_GetOptionalAttrString("warnoptions", &warnoptions) < 0) {
return _PyStatus_ERR("can't initialize warnings");
}
if (warnoptions != NULL && PyList_Check(warnoptions) &&
PyList_Size(warnoptions) > 0)
{ {
PyObject *warnings_module = PyImport_ImportModule("warnings"); PyObject *warnings_module = PyImport_ImportModule("warnings");
if (warnings_module == NULL) { if (warnings_module == NULL) {
@ -1310,6 +1314,7 @@ init_interp_main(PyThreadState *tstate)
} }
Py_XDECREF(warnings_module); Py_XDECREF(warnings_module);
} }
Py_XDECREF(warnoptions);
interp->runtime->initialized = 1; interp->runtime->initialized = 1;
} }
@ -1820,24 +1825,33 @@ file_is_closed(PyObject *fobj)
static int static int
flush_std_files(void) flush_std_files(void)
{ {
PyThreadState *tstate = _PyThreadState_GET(); PyObject *file;
PyObject *fout = _PySys_GetAttr(tstate, &_Py_ID(stdout));
PyObject *ferr = _PySys_GetAttr(tstate, &_Py_ID(stderr));
int status = 0; int status = 0;
if (fout != NULL && fout != Py_None && !file_is_closed(fout)) { if (_PySys_GetOptionalAttr(&_Py_ID(stdout), &file) < 0) {
if (_PyFile_Flush(fout) < 0) { status = -1;
PyErr_FormatUnraisable("Exception ignored on flushing sys.stdout"); }
else if (file != NULL && file != Py_None && !file_is_closed(file)) {
if (_PyFile_Flush(file) < 0) {
status = -1; status = -1;
} }
} }
if (status < 0) {
PyErr_FormatUnraisable("Exception ignored on flushing sys.stdout");
}
Py_XDECREF(file);
if (ferr != NULL && ferr != Py_None && !file_is_closed(ferr)) { if (_PySys_GetOptionalAttr(&_Py_ID(stderr), &file) < 0) {
if (_PyFile_Flush(ferr) < 0) { PyErr_Clear();
status = -1;
}
else if (file != NULL && file != Py_None && !file_is_closed(file)) {
if (_PyFile_Flush(file) < 0) {
PyErr_Clear(); PyErr_Clear();
status = -1; status = -1;
} }
} }
Py_XDECREF(file);
return status; return status;
} }
@ -3048,10 +3062,14 @@ _Py_FatalError_PrintExc(PyThreadState *tstate)
return 0; return 0;
} }
PyObject *ferr = _PySys_GetAttr(tstate, &_Py_ID(stderr)); PyObject *ferr;
if (_PySys_GetOptionalAttr(&_Py_ID(stderr), &ferr) < 0) {
_PyErr_Clear(tstate);
}
if (ferr == NULL || ferr == Py_None) { if (ferr == NULL || ferr == Py_None) {
/* sys.stderr is not set yet or set to None, /* sys.stderr is not set yet or set to None,
no need to try to display the exception */ no need to try to display the exception */
Py_XDECREF(ferr);
Py_DECREF(exc); Py_DECREF(exc);
return 0; return 0;
} }
@ -3067,6 +3085,7 @@ _Py_FatalError_PrintExc(PyThreadState *tstate)
if (_PyFile_Flush(ferr) < 0) { if (_PyFile_Flush(ferr) < 0) {
_PyErr_Clear(tstate); _PyErr_Clear(tstate);
} }
Py_DECREF(ferr);
return has_tb; return has_tb;
} }

View File

@ -109,17 +109,35 @@ _PyRun_InteractiveLoopObject(FILE *fp, PyObject *filename, PyCompilerFlags *flag
flags = &local_flags; flags = &local_flags;
} }
PyThreadState *tstate = _PyThreadState_GET(); PyObject *v;
PyObject *v = _PySys_GetAttr(tstate, &_Py_ID(ps1)); if (_PySys_GetOptionalAttr(&_Py_ID(ps1), &v) < 0) {
if (v == NULL) { PyErr_Print();
_PySys_SetAttr(&_Py_ID(ps1), v = PyUnicode_FromString(">>> ")); return -1;
Py_XDECREF(v);
} }
v = _PySys_GetAttr(tstate, &_Py_ID(ps2));
if (v == NULL) { if (v == NULL) {
_PySys_SetAttr(&_Py_ID(ps2), v = PyUnicode_FromString("... ")); v = PyUnicode_FromString(">>> ");
Py_XDECREF(v); if (v == NULL) {
PyErr_Clear();
} }
if (_PySys_SetAttr(&_Py_ID(ps1), v) < 0) {
PyErr_Clear();
}
}
Py_XDECREF(v);
if (_PySys_GetOptionalAttr(&_Py_ID(ps2), &v) < 0) {
PyErr_Print();
return -1;
}
if (v == NULL) {
v = PyUnicode_FromString("... ");
if (v == NULL) {
PyErr_Clear();
}
if (_PySys_SetAttr(&_Py_ID(ps2), v) < 0) {
PyErr_Clear();
}
}
Py_XDECREF(v);
#ifdef Py_REF_DEBUG #ifdef Py_REF_DEBUG
int show_ref_count = _Py_GetConfig()->show_ref_count; int show_ref_count = _Py_GetConfig()->show_ref_count;
@ -179,31 +197,37 @@ pyrun_one_parse_ast(FILE *fp, PyObject *filename,
PyCompilerFlags *flags, PyArena *arena, PyCompilerFlags *flags, PyArena *arena,
mod_ty *pmod, PyObject** interactive_src) mod_ty *pmod, PyObject** interactive_src)
{ {
PyThreadState *tstate = _PyThreadState_GET();
// Get sys.stdin.encoding (as UTF-8) // Get sys.stdin.encoding (as UTF-8)
PyObject *attr; // borrowed ref PyObject *attr;
PyObject *encoding_obj = NULL; PyObject *encoding_obj = NULL;
const char *encoding = NULL; const char *encoding = NULL;
if (fp == stdin) { if (fp == stdin) {
attr = _PySys_GetAttr(tstate, &_Py_ID(stdin)); if (_PySys_GetOptionalAttr(&_Py_ID(stdin), &attr) < 0) {
if (attr && attr != Py_None) { PyErr_Clear();
encoding_obj = PyObject_GetAttr(attr, &_Py_ID(encoding)); }
if (encoding_obj) { else if (attr != NULL && attr != Py_None) {
if (PyObject_GetOptionalAttr(attr, &_Py_ID(encoding), &encoding_obj) < 0) {
PyErr_Clear();
}
else if (encoding_obj && PyUnicode_Check(encoding_obj)) {
encoding = PyUnicode_AsUTF8(encoding_obj); encoding = PyUnicode_AsUTF8(encoding_obj);
if (!encoding) { if (!encoding) {
PyErr_Clear(); PyErr_Clear();
} }
} }
} }
Py_XDECREF(attr);
} }
// Get sys.ps1 (as UTF-8) // Get sys.ps1 (as UTF-8)
attr = _PySys_GetAttr(tstate, &_Py_ID(ps1));
PyObject *ps1_obj = NULL; PyObject *ps1_obj = NULL;
const char *ps1 = ""; const char *ps1 = "";
if (attr != NULL) { if (_PySys_GetOptionalAttr(&_Py_ID(ps1), &attr) < 0) {
PyErr_Clear();
}
else if (attr != NULL) {
ps1_obj = PyObject_Str(attr); ps1_obj = PyObject_Str(attr);
Py_DECREF(attr);
if (ps1_obj == NULL) { if (ps1_obj == NULL) {
PyErr_Clear(); PyErr_Clear();
} }
@ -217,11 +241,14 @@ pyrun_one_parse_ast(FILE *fp, PyObject *filename,
} }
// Get sys.ps2 (as UTF-8) // Get sys.ps2 (as UTF-8)
attr = _PySys_GetAttr(tstate, &_Py_ID(ps2));
PyObject *ps2_obj = NULL; PyObject *ps2_obj = NULL;
const char *ps2 = ""; const char *ps2 = "";
if (attr != NULL) { if (_PySys_GetOptionalAttr(&_Py_ID(ps2), &attr) < 0) {
PyErr_Clear();
}
else if (attr != NULL) {
ps2_obj = PyObject_Str(attr); ps2_obj = PyObject_Str(attr);
Py_DECREF(attr);
if (ps2_obj == NULL) { if (ps2_obj == NULL) {
PyErr_Clear(); PyErr_Clear();
} }
@ -621,9 +648,11 @@ _Py_HandleSystemExit(int *exitcode_p)
Py_SETREF(exc, code); Py_SETREF(exc, code);
} }
PyThreadState *tstate = _PyThreadState_GET(); PyObject *sys_stderr;
PyObject *sys_stderr = _PySys_GetAttr(tstate, &_Py_ID(stderr)); if (_PySys_GetOptionalAttr(&_Py_ID(stderr), &sys_stderr) < 0) {
if (sys_stderr != NULL && sys_stderr != Py_None) { PyErr_Clear();
}
else if (sys_stderr != NULL && sys_stderr != Py_None) {
if (PyFile_WriteObject(exc, sys_stderr, Py_PRINT_RAW) < 0) { if (PyFile_WriteObject(exc, sys_stderr, Py_PRINT_RAW) < 0) {
PyErr_Clear(); PyErr_Clear();
} }
@ -635,6 +664,7 @@ _Py_HandleSystemExit(int *exitcode_p)
fflush(stderr); fflush(stderr);
} }
PySys_WriteStderr("\n"); PySys_WriteStderr("\n");
Py_XDECREF(sys_stderr);
Py_CLEAR(exc); Py_CLEAR(exc);
*exitcode_p = 1; *exitcode_p = 1;
return 1; return 1;
@ -654,7 +684,7 @@ handle_system_exit(void)
static void static void
_PyErr_PrintEx(PyThreadState *tstate, int set_sys_last_vars) _PyErr_PrintEx(PyThreadState *tstate, int set_sys_last_vars)
{ {
PyObject *typ = NULL, *tb = NULL; PyObject *typ = NULL, *tb = NULL, *hook = NULL;
handle_system_exit(); handle_system_exit();
PyObject *exc = _PyErr_GetRaisedException(tstate); PyObject *exc = _PyErr_GetRaisedException(tstate);
@ -683,7 +713,9 @@ _PyErr_PrintEx(PyThreadState *tstate, int set_sys_last_vars)
_PyErr_Clear(tstate); _PyErr_Clear(tstate);
} }
} }
PyObject *hook = _PySys_GetAttr(tstate, &_Py_ID(excepthook)); if (_PySys_GetOptionalAttr(&_Py_ID(excepthook), &hook) < 0) {
PyErr_Clear();
}
if (_PySys_Audit(tstate, "sys.excepthook", "OOOO", hook ? hook : Py_None, if (_PySys_Audit(tstate, "sys.excepthook", "OOOO", hook ? hook : Py_None,
typ, exc, tb) < 0) { typ, exc, tb) < 0) {
if (PyErr_ExceptionMatches(PyExc_RuntimeError)) { if (PyErr_ExceptionMatches(PyExc_RuntimeError)) {
@ -717,6 +749,7 @@ _PyErr_PrintEx(PyThreadState *tstate, int set_sys_last_vars)
} }
done: done:
Py_XDECREF(hook);
Py_XDECREF(typ); Py_XDECREF(typ);
Py_XDECREF(exc); Py_XDECREF(exc);
Py_XDECREF(tb); Py_XDECREF(tb);
@ -1165,17 +1198,24 @@ _PyErr_Display(PyObject *file, PyObject *unused, PyObject *value, PyObject *tb)
void void
PyErr_Display(PyObject *unused, PyObject *value, PyObject *tb) PyErr_Display(PyObject *unused, PyObject *value, PyObject *tb)
{ {
PyThreadState *tstate = _PyThreadState_GET(); PyObject *file;
PyObject *file = _PySys_GetAttr(tstate, &_Py_ID(stderr)); if (_PySys_GetOptionalAttr(&_Py_ID(stderr), &file) < 0) {
PyObject *exc = PyErr_GetRaisedException();
_PyObject_Dump(value);
fprintf(stderr, "lost sys.stderr\n");
_PyObject_Dump(exc);
Py_DECREF(exc);
return;
}
if (file == NULL) { if (file == NULL) {
_PyObject_Dump(value); _PyObject_Dump(value);
fprintf(stderr, "lost sys.stderr\n"); fprintf(stderr, "lost sys.stderr\n");
return; return;
} }
if (file == Py_None) { if (file == Py_None) {
Py_DECREF(file);
return; return;
} }
Py_INCREF(file);
_PyErr_Display(file, NULL, value, tb); _PyErr_Display(file, NULL, value, tb);
Py_DECREF(file); Py_DECREF(file);
} }
@ -1282,11 +1322,15 @@ PyRun_FileExFlags(FILE *fp, const char *filename, int start, PyObject *globals,
static void static void
flush_io_stream(PyThreadState *tstate, PyObject *name) flush_io_stream(PyThreadState *tstate, PyObject *name)
{ {
PyObject *f = _PySys_GetAttr(tstate, name); PyObject *f;
if (_PySys_GetOptionalAttr(name, &f) < 0) {
PyErr_Clear();
}
if (f != NULL) { if (f != NULL) {
if (_PyFile_Flush(f) < 0) { if (_PyFile_Flush(f) < 0) {
PyErr_Clear(); PyErr_Clear();
} }
Py_DECREF(f);
} }
} }

View File

@ -85,34 +85,93 @@ _PySys_GetAttr(PyThreadState *tstate, PyObject *name)
return value; return value;
} }
static PyObject * PyObject *
_PySys_GetObject(PyInterpreterState *interp, const char *name) _PySys_GetRequiredAttr(PyObject *name)
{ {
PyObject *sysdict = interp->sysdict; if (!PyUnicode_Check(name)) {
PyErr_Format(PyExc_TypeError,
"attribute name must be string, not '%.200s'",
Py_TYPE(name)->tp_name);
return NULL;
}
PyThreadState *tstate = _PyThreadState_GET();
PyObject *sysdict = tstate->interp->sysdict;
if (sysdict == NULL) { if (sysdict == NULL) {
PyErr_SetString(PyExc_RuntimeError, "no sys module");
return NULL; return NULL;
} }
PyObject *value; PyObject *value;
if (PyDict_GetItemStringRef(sysdict, name, &value) != 1) { if (PyDict_GetItemRef(sysdict, name, &value) == 0) {
PyErr_Format(PyExc_RuntimeError, "lost sys.%U", name);
}
return value;
}
PyObject *
_PySys_GetRequiredAttrString(const char *name)
{
PyThreadState *tstate = _PyThreadState_GET();
PyObject *sysdict = tstate->interp->sysdict;
if (sysdict == NULL) {
PyErr_SetString(PyExc_RuntimeError, "no sys module");
return NULL; return NULL;
} }
Py_DECREF(value); // return a borrowed reference PyObject *value;
if (PyDict_GetItemStringRef(sysdict, name, &value) == 0) {
PyErr_Format(PyExc_RuntimeError, "lost sys.%s", name);
}
return value; return value;
} }
int
_PySys_GetOptionalAttr(PyObject *name, PyObject **value)
{
if (!PyUnicode_Check(name)) {
PyErr_Format(PyExc_TypeError,
"attribute name must be string, not '%.200s'",
Py_TYPE(name)->tp_name);
*value = NULL;
return -1;
}
PyThreadState *tstate = _PyThreadState_GET();
PyObject *sysdict = tstate->interp->sysdict;
if (sysdict == NULL) {
*value = NULL;
return 0;
}
return PyDict_GetItemRef(sysdict, name, value);
}
int
_PySys_GetOptionalAttrString(const char *name, PyObject **value)
{
PyThreadState *tstate = _PyThreadState_GET();
PyObject *sysdict = tstate->interp->sysdict;
if (sysdict == NULL) {
*value = NULL;
return 0;
}
return PyDict_GetItemStringRef(sysdict, name, value);
}
PyObject * PyObject *
PySys_GetObject(const char *name) PySys_GetObject(const char *name)
{ {
PyThreadState *tstate = _PyThreadState_GET(); PyThreadState *tstate = _PyThreadState_GET();
PyObject *sysdict = tstate->interp->sysdict;
if (sysdict == NULL) {
return NULL;
}
PyObject *exc = _PyErr_GetRaisedException(tstate); PyObject *exc = _PyErr_GetRaisedException(tstate);
PyObject *value = _PySys_GetObject(tstate->interp, name); PyObject *value;
(void) PyDict_GetItemStringRef(sysdict, name, &value);
/* XXX Suppress a new exception if it was raised and restore /* XXX Suppress a new exception if it was raised and restore
* the old one. */ * the old one. */
if (_PyErr_Occurred(tstate)) { if (_PyErr_Occurred(tstate)) {
PyErr_FormatUnraisable("Exception ignored in PySys_GetObject()"); PyErr_FormatUnraisable("Exception ignored in PySys_GetObject()");
} }
_PyErr_SetRaisedException(tstate, exc); _PyErr_SetRaisedException(tstate, exc);
Py_XDECREF(value); // return a borrowed reference
return value; return value;
} }
@ -123,6 +182,10 @@ sys_set_object(PyInterpreterState *interp, PyObject *key, PyObject *v)
return -1; return -1;
} }
PyObject *sd = interp->sysdict; PyObject *sd = interp->sysdict;
if (sd == NULL) {
PyErr_SetString(PyExc_RuntimeError, "no sys module");
return -1;
}
if (v == NULL) { if (v == NULL) {
if (PyDict_Pop(sd, key, NULL) < 0) { if (PyDict_Pop(sd, key, NULL) < 0) {
return -1; return -1;
@ -748,9 +811,13 @@ sys_displayhook(PyObject *module, PyObject *o)
} }
if (PyObject_SetAttr(builtins, _Py_LATIN1_CHR('_'), Py_None) != 0) if (PyObject_SetAttr(builtins, _Py_LATIN1_CHR('_'), Py_None) != 0)
return NULL; return NULL;
outf = _PySys_GetAttr(tstate, &_Py_ID(stdout)); outf = _PySys_GetRequiredAttr(&_Py_ID(stdout));
if (outf == NULL || outf == Py_None) { if (outf == NULL) {
return NULL;
}
if (outf == Py_None) {
_PyErr_SetString(tstate, PyExc_RuntimeError, "lost sys.stdout"); _PyErr_SetString(tstate, PyExc_RuntimeError, "lost sys.stdout");
Py_DECREF(outf);
return NULL; return NULL;
} }
if (PyFile_WriteObject(o, outf, 0) != 0) { if (PyFile_WriteObject(o, outf, 0) != 0) {
@ -761,17 +828,23 @@ sys_displayhook(PyObject *module, PyObject *o)
_PyErr_Clear(tstate); _PyErr_Clear(tstate);
err = sys_displayhook_unencodable(outf, o); err = sys_displayhook_unencodable(outf, o);
if (err) { if (err) {
Py_DECREF(outf);
return NULL; return NULL;
} }
} }
else { else {
Py_DECREF(outf);
return NULL; return NULL;
} }
} }
if (PyFile_WriteObject(_Py_LATIN1_CHR('\n'), outf, Py_PRINT_RAW) != 0) if (PyFile_WriteObject(_Py_LATIN1_CHR('\n'), outf, Py_PRINT_RAW) != 0) {
Py_DECREF(outf);
return NULL; return NULL;
if (PyObject_SetAttr(builtins, _Py_LATIN1_CHR('_'), o) != 0) }
Py_DECREF(outf);
if (PyObject_SetAttr(builtins, _Py_LATIN1_CHR('_'), o) != 0) {
return NULL; return NULL;
}
Py_RETURN_NONE; Py_RETURN_NONE;
} }
@ -2798,7 +2871,10 @@ _PySys_ReadPreinitXOptions(PyConfig *config)
static PyObject * static PyObject *
get_warnoptions(PyThreadState *tstate) get_warnoptions(PyThreadState *tstate)
{ {
PyObject *warnoptions = _PySys_GetAttr(tstate, &_Py_ID(warnoptions)); PyObject *warnoptions;
if (_PySys_GetOptionalAttr(&_Py_ID(warnoptions), &warnoptions) < 0) {
return NULL;
}
if (warnoptions == NULL || !PyList_Check(warnoptions)) { if (warnoptions == NULL || !PyList_Check(warnoptions)) {
/* PEP432 TODO: we can reach this if warnoptions is NULL in the main /* PEP432 TODO: we can reach this if warnoptions is NULL in the main
* interpreter config. When that happens, we need to properly set * interpreter config. When that happens, we need to properly set
@ -2810,6 +2886,7 @@ get_warnoptions(PyThreadState *tstate)
* call optional for embedding applications, thus making this * call optional for embedding applications, thus making this
* reachable again. * reachable again.
*/ */
Py_XDECREF(warnoptions);
warnoptions = PyList_New(0); warnoptions = PyList_New(0);
if (warnoptions == NULL) { if (warnoptions == NULL) {
return NULL; return NULL;
@ -2818,7 +2895,6 @@ get_warnoptions(PyThreadState *tstate)
Py_DECREF(warnoptions); Py_DECREF(warnoptions);
return NULL; return NULL;
} }
Py_DECREF(warnoptions);
} }
return warnoptions; return warnoptions;
} }
@ -2832,10 +2908,15 @@ PySys_ResetWarnOptions(void)
return; return;
} }
PyObject *warnoptions = _PySys_GetAttr(tstate, &_Py_ID(warnoptions)); PyObject *warnoptions;
if (warnoptions == NULL || !PyList_Check(warnoptions)) if (_PySys_GetOptionalAttr(&_Py_ID(warnoptions), &warnoptions) < 0) {
PyErr_Clear();
return; return;
}
if (warnoptions != NULL && PyList_Check(warnoptions)) {
PyList_SetSlice(warnoptions, 0, PyList_GET_SIZE(warnoptions), NULL); PyList_SetSlice(warnoptions, 0, PyList_GET_SIZE(warnoptions), NULL);
}
Py_XDECREF(warnoptions);
} }
static int static int
@ -2847,8 +2928,10 @@ _PySys_AddWarnOptionWithError(PyThreadState *tstate, PyObject *option)
return -1; return -1;
} }
if (PyList_Append(warnoptions, option)) { if (PyList_Append(warnoptions, option)) {
Py_DECREF(warnoptions);
return -1; return -1;
} }
Py_DECREF(warnoptions);
return 0; return 0;
} }
@ -2889,16 +2972,24 @@ _Py_COMP_DIAG_POP
PyAPI_FUNC(int) PyAPI_FUNC(int)
PySys_HasWarnOptions(void) PySys_HasWarnOptions(void)
{ {
PyThreadState *tstate = _PyThreadState_GET(); PyObject *warnoptions;
PyObject *warnoptions = _PySys_GetAttr(tstate, &_Py_ID(warnoptions)); if (_PySys_GetOptionalAttr(&_Py_ID(warnoptions), &warnoptions) < 0) {
return (warnoptions != NULL && PyList_Check(warnoptions) PyErr_Clear();
&& PyList_GET_SIZE(warnoptions) > 0); return 0;
}
int r = (warnoptions != NULL && PyList_Check(warnoptions) &&
PyList_GET_SIZE(warnoptions) > 0);
Py_XDECREF(warnoptions);
return r;
} }
static PyObject * static PyObject *
get_xoptions(PyThreadState *tstate) get_xoptions(PyThreadState *tstate)
{ {
PyObject *xoptions = _PySys_GetAttr(tstate, &_Py_ID(_xoptions)); PyObject *xoptions;
if (_PySys_GetOptionalAttr(&_Py_ID(_xoptions), &xoptions) < 0) {
return NULL;
}
if (xoptions == NULL || !PyDict_Check(xoptions)) { if (xoptions == NULL || !PyDict_Check(xoptions)) {
/* PEP432 TODO: we can reach this if xoptions is NULL in the main /* PEP432 TODO: we can reach this if xoptions is NULL in the main
* interpreter config. When that happens, we need to properly set * interpreter config. When that happens, we need to properly set
@ -2910,6 +3001,7 @@ get_xoptions(PyThreadState *tstate)
* call optional for embedding applications, thus making this * call optional for embedding applications, thus making this
* reachable again. * reachable again.
*/ */
Py_XDECREF(xoptions);
xoptions = PyDict_New(); xoptions = PyDict_New();
if (xoptions == NULL) { if (xoptions == NULL) {
return NULL; return NULL;
@ -2918,7 +3010,6 @@ get_xoptions(PyThreadState *tstate)
Py_DECREF(xoptions); Py_DECREF(xoptions);
return NULL; return NULL;
} }
Py_DECREF(xoptions);
} }
return xoptions; return xoptions;
} }
@ -2957,11 +3048,13 @@ _PySys_AddXOptionWithError(const wchar_t *s)
} }
Py_DECREF(name); Py_DECREF(name);
Py_DECREF(value); Py_DECREF(value);
Py_DECREF(opts);
return 0; return 0;
error: error:
Py_XDECREF(name); Py_XDECREF(name);
Py_XDECREF(value); Py_XDECREF(value);
Py_XDECREF(opts);
return -1; return -1;
} }
@ -2984,7 +3077,9 @@ PyObject *
PySys_GetXOptions(void) PySys_GetXOptions(void)
{ {
PyThreadState *tstate = _PyThreadState_GET(); PyThreadState *tstate = _PyThreadState_GET();
return get_xoptions(tstate); PyObject *opts = get_xoptions(tstate);
Py_XDECREF(opts);
return opts;
} }
/* XXX This doc string is too long to be a single string literal in VC++ 5.0. /* XXX This doc string is too long to be a single string literal in VC++ 5.0.
@ -3720,16 +3815,15 @@ _PySys_UpdateConfig(PyThreadState *tstate)
#undef COPY_WSTR #undef COPY_WSTR
// sys.flags // sys.flags
PyObject *flags = _PySys_GetObject(interp, "flags"); // borrowed ref PyObject *flags = _PySys_GetRequiredAttrString("flags");
if (flags == NULL) { if (flags == NULL) {
if (!_PyErr_Occurred(tstate)) {
_PyErr_SetString(tstate, PyExc_RuntimeError, "lost sys.flags");
}
return -1; return -1;
} }
if (set_flags_from_config(interp, flags) < 0) { if (set_flags_from_config(interp, flags) < 0) {
Py_DECREF(flags);
return -1; return -1;
} }
Py_DECREF(flags);
SET_SYS("dont_write_bytecode", PyBool_FromLong(!config->write_bytecode)); SET_SYS("dont_write_bytecode", PyBool_FromLong(!config->write_bytecode));
@ -3961,12 +4055,15 @@ PySys_SetArgvEx(int argc, wchar_t **argv, int updatepath)
Py_FatalError("can't compute path0 from argv"); Py_FatalError("can't compute path0 from argv");
} }
PyObject *sys_path = _PySys_GetAttr(tstate, &_Py_ID(path)); PyObject *sys_path;
if (sys_path != NULL) { if (_PySys_GetOptionalAttr(&_Py_ID(path), &sys_path) < 0) {
Py_FatalError("can't get sys.path");
}
else if (sys_path != NULL) {
if (PyList_Insert(sys_path, 0, path0) < 0) { if (PyList_Insert(sys_path, 0, path0) < 0) {
Py_DECREF(path0);
Py_FatalError("can't prepend path0 to sys.path"); Py_FatalError("can't prepend path0 to sys.path");
} }
Py_DECREF(sys_path);
} }
Py_DECREF(path0); Py_DECREF(path0);
} }
@ -4054,8 +4151,8 @@ sys_write(PyObject *key, FILE *fp, const char *format, va_list va)
PyThreadState *tstate = _PyThreadState_GET(); PyThreadState *tstate = _PyThreadState_GET();
PyObject *exc = _PyErr_GetRaisedException(tstate); PyObject *exc = _PyErr_GetRaisedException(tstate);
file = _PySys_GetAttr(tstate, key);
written = PyOS_vsnprintf(buffer, sizeof(buffer), format, va); written = PyOS_vsnprintf(buffer, sizeof(buffer), format, va);
file = _PySys_GetRequiredAttr(key);
if (sys_pyfile_write(buffer, file) != 0) { if (sys_pyfile_write(buffer, file) != 0) {
_PyErr_Clear(tstate); _PyErr_Clear(tstate);
fputs(buffer, fp); fputs(buffer, fp);
@ -4065,6 +4162,7 @@ sys_write(PyObject *key, FILE *fp, const char *format, va_list va)
if (sys_pyfile_write(truncated, file) != 0) if (sys_pyfile_write(truncated, file) != 0)
fputs(truncated, fp); fputs(truncated, fp);
} }
Py_XDECREF(file);
_PyErr_SetRaisedException(tstate, exc); _PyErr_SetRaisedException(tstate, exc);
} }
@ -4096,15 +4194,16 @@ sys_format(PyObject *key, FILE *fp, const char *format, va_list va)
PyThreadState *tstate = _PyThreadState_GET(); PyThreadState *tstate = _PyThreadState_GET();
PyObject *exc = _PyErr_GetRaisedException(tstate); PyObject *exc = _PyErr_GetRaisedException(tstate);
file = _PySys_GetAttr(tstate, key);
message = PyUnicode_FromFormatV(format, va); message = PyUnicode_FromFormatV(format, va);
if (message != NULL) { if (message != NULL) {
file = _PySys_GetRequiredAttr(key);
if (sys_pyfile_write_unicode(message, file) != 0) { if (sys_pyfile_write_unicode(message, file) != 0) {
_PyErr_Clear(tstate); _PyErr_Clear(tstate);
utf8 = PyUnicode_AsUTF8(message); utf8 = PyUnicode_AsUTF8(message);
if (utf8 != NULL) if (utf8 != NULL)
fputs(utf8, fp); fputs(utf8, fp);
} }
Py_XDECREF(file);
Py_DECREF(message); Py_DECREF(message);
} }
_PyErr_SetRaisedException(tstate, exc); _PyErr_SetRaisedException(tstate, exc);

View File

@ -12,7 +12,7 @@
#include "pycore_pyarena.h" // _PyArena_Free() #include "pycore_pyarena.h" // _PyArena_Free()
#include "pycore_pyerrors.h" // _PyErr_GetRaisedException() #include "pycore_pyerrors.h" // _PyErr_GetRaisedException()
#include "pycore_pystate.h" // _PyThreadState_GET() #include "pycore_pystate.h" // _PyThreadState_GET()
#include "pycore_sysmodule.h" // _PySys_GetAttr() #include "pycore_sysmodule.h" // _PySys_GetOptionalAttr()
#include "pycore_traceback.h" // EXCEPTION_TB_HEADER #include "pycore_traceback.h" // EXCEPTION_TB_HEADER
#include "frameobject.h" // PyFrame_New() #include "frameobject.h" // PyFrame_New()
@ -346,9 +346,13 @@ _Py_FindSourceFile(PyObject *filename, char* namebuf, size_t namelen, PyObject *
taillen = strlen(tail); taillen = strlen(tail);
PyThreadState *tstate = _PyThreadState_GET(); PyThreadState *tstate = _PyThreadState_GET();
syspath = _PySys_GetAttr(tstate, &_Py_ID(path)); if (_PySys_GetOptionalAttr(&_Py_ID(path), &syspath) < 0) {
if (syspath == NULL || !PyList_Check(syspath)) PyErr_Clear();
goto error; goto error;
}
if (syspath == NULL || !PyList_Check(syspath)) {
goto error;
}
npath = PyList_Size(syspath); npath = PyList_Size(syspath);
open = PyObject_GetAttr(io, &_Py_ID(open)); open = PyObject_GetAttr(io, &_Py_ID(open));
@ -391,6 +395,7 @@ _Py_FindSourceFile(PyObject *filename, char* namebuf, size_t namelen, PyObject *
result = NULL; result = NULL;
finally: finally:
Py_XDECREF(open); Py_XDECREF(open);
Py_XDECREF(syspath);
Py_DECREF(filebytes); Py_DECREF(filebytes);
return result; return result;
} }
@ -719,17 +724,21 @@ _PyTraceBack_Print(PyObject *v, const char *header, PyObject *f)
PyErr_BadInternalCall(); PyErr_BadInternalCall();
return -1; return -1;
} }
limitv = PySys_GetObject("tracebacklimit"); if (_PySys_GetOptionalAttrString("tracebacklimit", &limitv) < 0) {
if (limitv && PyLong_Check(limitv)) { return -1;
}
else if (limitv != NULL && PyLong_Check(limitv)) {
int overflow; int overflow;
limit = PyLong_AsLongAndOverflow(limitv, &overflow); limit = PyLong_AsLongAndOverflow(limitv, &overflow);
if (overflow > 0) { if (overflow > 0) {
limit = LONG_MAX; limit = LONG_MAX;
} }
else if (limit <= 0) { else if (limit <= 0) {
Py_DECREF(limitv);
return 0; return 0;
} }
} }
Py_XDECREF(limitv);
if (PyFile_WriteString(header, f) < 0) { if (PyFile_WriteString(header, f) < 0) {
return -1; return -1;