mirror of
https://github.com/python/cpython.git
synced 2025-08-04 08:59:19 +00:00
gh-130163: Fix crashes related to PySys_GetObject() (GH-130503)
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().
This commit is contained in:
parent
2dad1e08ec
commit
0ef4ffeefd
23 changed files with 513 additions and 213 deletions
|
@ -5,7 +5,7 @@
|
|||
#include "pycore_pyerrors.h" // _PyErr_Occurred()
|
||||
#include "pycore_pylifecycle.h" // _Py_IsInterpreterFinalizing()
|
||||
#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 <stdbool.h>
|
||||
|
@ -552,7 +552,7 @@ static void
|
|||
show_warning(PyThreadState *tstate, PyObject *filename, int lineno,
|
||||
PyObject *text, PyObject *category, PyObject *sourceline)
|
||||
{
|
||||
PyObject *f_stderr;
|
||||
PyObject *f_stderr = NULL;
|
||||
PyObject *name;
|
||||
char lineno_str[128];
|
||||
|
||||
|
@ -563,8 +563,7 @@ show_warning(PyThreadState *tstate, PyObject *filename, int lineno,
|
|||
goto error;
|
||||
}
|
||||
|
||||
f_stderr = _PySys_GetAttr(tstate, &_Py_ID(stderr));
|
||||
if (f_stderr == NULL) {
|
||||
if (_PySys_GetOptionalAttr(&_Py_ID(stderr), &f_stderr) <= 0) {
|
||||
fprintf(stderr, "lost sys.stderr\n");
|
||||
goto error;
|
||||
}
|
||||
|
@ -614,6 +613,7 @@ show_warning(PyThreadState *tstate, PyObject *filename, int lineno,
|
|||
}
|
||||
|
||||
error:
|
||||
Py_XDECREF(f_stderr);
|
||||
Py_XDECREF(name);
|
||||
PyErr_Clear();
|
||||
}
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
#include "pycore_pyerrors.h" // _PyErr_NoMemory()
|
||||
#include "pycore_pystate.h" // _PyThreadState_GET()
|
||||
#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_cell.h" // PyCell_GetRef()
|
||||
|
||||
|
@ -462,18 +462,16 @@ builtin_callable(PyObject *module, PyObject *obj)
|
|||
static PyObject *
|
||||
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) {
|
||||
PyErr_SetString(PyExc_RuntimeError, "lost sys.breakpointhook");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (PySys_Audit("builtins.breakpoint", "O", hook) < 0) {
|
||||
Py_DECREF(hook);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Py_INCREF(hook);
|
||||
PyObject *retval = PyObject_Vectorcall(hook, args, nargs, keywords);
|
||||
Py_DECREF(hook);
|
||||
return retval;
|
||||
|
@ -2171,18 +2169,20 @@ builtin_print_impl(PyObject *module, PyObject * const *args,
|
|||
int i, err;
|
||||
|
||||
if (file == Py_None) {
|
||||
PyThreadState *tstate = _PyThreadState_GET();
|
||||
file = _PySys_GetAttr(tstate, &_Py_ID(stdout));
|
||||
file = _PySys_GetRequiredAttr(&_Py_ID(stdout));
|
||||
if (file == NULL) {
|
||||
PyErr_SetString(PyExc_RuntimeError, "lost sys.stdout");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* sys.stdout may be None when FILE* stdout isn't connected */
|
||||
if (file == Py_None) {
|
||||
Py_DECREF(file);
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
}
|
||||
else {
|
||||
Py_INCREF(file);
|
||||
}
|
||||
|
||||
if (sep == Py_None) {
|
||||
sep = NULL;
|
||||
|
@ -2191,6 +2191,7 @@ builtin_print_impl(PyObject *module, PyObject * const *args,
|
|||
PyErr_Format(PyExc_TypeError,
|
||||
"sep must be None or a string, not %.200s",
|
||||
Py_TYPE(sep)->tp_name);
|
||||
Py_DECREF(file);
|
||||
return NULL;
|
||||
}
|
||||
if (end == Py_None) {
|
||||
|
@ -2200,6 +2201,7 @@ builtin_print_impl(PyObject *module, PyObject * const *args,
|
|||
PyErr_Format(PyExc_TypeError,
|
||||
"end must be None or a string, not %.200s",
|
||||
Py_TYPE(end)->tp_name);
|
||||
Py_DECREF(file);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -2212,11 +2214,13 @@ builtin_print_impl(PyObject *module, PyObject * const *args,
|
|||
err = PyFile_WriteObject(sep, file, Py_PRINT_RAW);
|
||||
}
|
||||
if (err) {
|
||||
Py_DECREF(file);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
err = PyFile_WriteObject(args[i], file, Py_PRINT_RAW);
|
||||
if (err) {
|
||||
Py_DECREF(file);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
@ -2228,14 +2232,17 @@ builtin_print_impl(PyObject *module, PyObject * const *args,
|
|||
err = PyFile_WriteObject(end, file, Py_PRINT_RAW);
|
||||
}
|
||||
if (err) {
|
||||
Py_DECREF(file);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (flush) {
|
||||
if (_PyFile_Flush(file) < 0) {
|
||||
Py_DECREF(file);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
Py_DECREF(file);
|
||||
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
@ -2260,36 +2267,41 @@ static PyObject *
|
|||
builtin_input_impl(PyObject *module, PyObject *prompt)
|
||||
/*[clinic end generated code: output=83db5a191e7a0d60 input=159c46d4ae40977e]*/
|
||||
{
|
||||
PyThreadState *tstate = _PyThreadState_GET();
|
||||
PyObject *fin = _PySys_GetAttr(
|
||||
tstate, &_Py_ID(stdin));
|
||||
PyObject *fout = _PySys_GetAttr(
|
||||
tstate, &_Py_ID(stdout));
|
||||
PyObject *ferr = _PySys_GetAttr(
|
||||
tstate, &_Py_ID(stderr));
|
||||
PyObject *fin = NULL;
|
||||
PyObject *fout = NULL;
|
||||
PyObject *ferr = NULL;
|
||||
PyObject *tmp;
|
||||
long fd;
|
||||
int tty;
|
||||
|
||||
/* Check that stdin/out/err are intact */
|
||||
if (fin == NULL || fin == Py_None) {
|
||||
PyErr_SetString(PyExc_RuntimeError,
|
||||
"input(): lost sys.stdin");
|
||||
return NULL;
|
||||
fin = _PySys_GetRequiredAttr(&_Py_ID(stdin));
|
||||
if (fin == NULL) {
|
||||
goto error;
|
||||
}
|
||||
if (fout == NULL || fout == Py_None) {
|
||||
PyErr_SetString(PyExc_RuntimeError,
|
||||
"input(): lost sys.stdout");
|
||||
return NULL;
|
||||
if (fin == Py_None) {
|
||||
PyErr_SetString(PyExc_RuntimeError, "lost sys.stdin");
|
||||
goto error;
|
||||
}
|
||||
if (ferr == NULL || ferr == Py_None) {
|
||||
PyErr_SetString(PyExc_RuntimeError,
|
||||
"input(): lost sys.stderr");
|
||||
return NULL;
|
||||
fout = _PySys_GetRequiredAttr(&_Py_ID(stdout));
|
||||
if (fout == NULL) {
|
||||
goto error;
|
||||
}
|
||||
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) {
|
||||
return NULL;
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* First of all, flush stderr */
|
||||
|
@ -2308,8 +2320,9 @@ builtin_input_impl(PyObject *module, PyObject *prompt)
|
|||
else {
|
||||
fd = PyLong_AsLong(tmp);
|
||||
Py_DECREF(tmp);
|
||||
if (fd < 0 && PyErr_Occurred())
|
||||
return NULL;
|
||||
if (fd < 0 && PyErr_Occurred()) {
|
||||
goto error;
|
||||
}
|
||||
tty = fd == fileno(stdin) && isatty(fd);
|
||||
}
|
||||
if (tty) {
|
||||
|
@ -2322,7 +2335,7 @@ builtin_input_impl(PyObject *module, PyObject *prompt)
|
|||
fd = PyLong_AsLong(tmp);
|
||||
Py_DECREF(tmp);
|
||||
if (fd < 0 && PyErr_Occurred())
|
||||
return NULL;
|
||||
goto error;
|
||||
tty = fd == fileno(stdout) && isatty(fd);
|
||||
}
|
||||
}
|
||||
|
@ -2450,10 +2463,13 @@ builtin_input_impl(PyObject *module, PyObject *prompt)
|
|||
|
||||
if (result != NULL) {
|
||||
if (PySys_Audit("builtins.input/result", "O", result) < 0) {
|
||||
return NULL;
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
|
||||
Py_DECREF(fin);
|
||||
Py_DECREF(fout);
|
||||
Py_DECREF(ferr);
|
||||
return result;
|
||||
|
||||
_readline_errors:
|
||||
|
@ -2463,7 +2479,7 @@ builtin_input_impl(PyObject *module, PyObject *prompt)
|
|||
Py_XDECREF(stdout_errors);
|
||||
Py_XDECREF(po);
|
||||
if (tty)
|
||||
return NULL;
|
||||
goto error;
|
||||
|
||||
PyErr_Clear();
|
||||
}
|
||||
|
@ -2471,12 +2487,22 @@ builtin_input_impl(PyObject *module, PyObject *prompt)
|
|||
/* Fallback if we're not interactive */
|
||||
if (prompt != NULL) {
|
||||
if (PyFile_WriteObject(prompt, fout, Py_PRINT_RAW) != 0)
|
||||
return NULL;
|
||||
goto error;
|
||||
}
|
||||
if (_PyFile_Flush(fout) < 0) {
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -31,6 +31,7 @@
|
|||
#include "pycore_tuple.h" // _PyTuple_ITEMS()
|
||||
#include "pycore_uop_ids.h" // Uops
|
||||
#include "pycore_pyerrors.h"
|
||||
#include "pycore_sysmodule.h" // _PySys_GetOptionalAttrString()
|
||||
|
||||
#include "pycore_dict.h"
|
||||
#include "dictobject.h"
|
||||
|
@ -2822,13 +2823,18 @@ _PyEval_ImportFrom(PyThreadState *tstate, PyObject *v, PyObject *name)
|
|||
}
|
||||
int is_possibly_shadowing_stdlib = 0;
|
||||
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)) {
|
||||
is_possibly_shadowing_stdlib = PySet_Contains(stdlib_modules, mod_name_or_unknown);
|
||||
if (is_possibly_shadowing_stdlib < 0) {
|
||||
Py_DECREF(stdlib_modules);
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
Py_XDECREF(stdlib_modules);
|
||||
}
|
||||
|
||||
if (origin == NULL && PyModule_Check(v)) {
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
#include "pycore_pyerrors.h" // _PyErr_Format()
|
||||
#include "pycore_pystate.h" // _PyThreadState_GET()
|
||||
#include "pycore_structseq.h" // _PyStructSequence_FiniBuiltin()
|
||||
#include "pycore_sysmodule.h" // _PySys_GetAttr()
|
||||
#include "pycore_sysmodule.h" // _PySys_GetOptionalAttr()
|
||||
#include "pycore_traceback.h" // _PyTraceBack_FromFrame()
|
||||
|
||||
#ifdef MS_WINDOWS
|
||||
|
@ -1532,14 +1532,15 @@ write_unraisable_exc(PyThreadState *tstate, PyObject *exc_type,
|
|||
PyObject *exc_value, PyObject *exc_tb, PyObject *err_msg,
|
||||
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) {
|
||||
Py_XDECREF(file);
|
||||
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,
|
||||
err_msg, obj, file);
|
||||
Py_DECREF(file);
|
||||
|
@ -1638,13 +1639,20 @@ format_unraisable_v(const char *format, va_list va, PyObject *obj)
|
|||
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) {
|
||||
Py_DECREF(hook_args);
|
||||
goto default_hook;
|
||||
}
|
||||
|
||||
if (_PySys_Audit(tstate, "sys.unraisablehook", "OO", hook, hook_args) < 0) {
|
||||
Py_DECREF(hook);
|
||||
Py_DECREF(hook_args);
|
||||
err_msg_str = "Exception ignored in audit hook";
|
||||
obj = NULL;
|
||||
|
@ -1652,11 +1660,13 @@ format_unraisable_v(const char *format, va_list va, PyObject *obj)
|
|||
}
|
||||
|
||||
if (hook == Py_None) {
|
||||
Py_DECREF(hook);
|
||||
Py_DECREF(hook_args);
|
||||
goto default_hook;
|
||||
}
|
||||
|
||||
PyObject *res = PyObject_CallOneArg(hook, hook_args);
|
||||
Py_DECREF(hook);
|
||||
Py_DECREF(hook_args);
|
||||
if (res != NULL) {
|
||||
Py_DECREF(res);
|
||||
|
|
|
@ -3326,19 +3326,15 @@ PyObject *
|
|||
PyImport_GetImporter(PyObject *path)
|
||||
{
|
||||
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) {
|
||||
PyErr_SetString(PyExc_RuntimeError, "lost sys.path_importer_cache");
|
||||
return NULL;
|
||||
}
|
||||
Py_INCREF(path_importer_cache);
|
||||
PyObject *path_hooks = PySys_GetObject("path_hooks");
|
||||
PyObject *path_hooks = _PySys_GetRequiredAttrString("path_hooks");
|
||||
if (path_hooks == NULL) {
|
||||
PyErr_SetString(PyExc_RuntimeError, "lost sys.path_hooks");
|
||||
Py_DECREF(path_importer_cache);
|
||||
return NULL;
|
||||
}
|
||||
Py_INCREF(path_hooks);
|
||||
PyObject *importer = get_path_importer(tstate, path_importer_cache, path_hooks, path);
|
||||
Py_DECREF(path_hooks);
|
||||
Py_DECREF(path_importer_cache);
|
||||
|
@ -3640,15 +3636,31 @@ import_find_and_load(PyThreadState *tstate, PyObject *abs_name)
|
|||
|
||||
PyTime_t t1 = 0, accumulated_copy = accumulated;
|
||||
|
||||
PyObject *sys_path = PySys_GetObject("path");
|
||||
PyObject *sys_meta_path = PySys_GetObject("meta_path");
|
||||
PyObject *sys_path_hooks = PySys_GetObject("path_hooks");
|
||||
PyObject *sys_path, *sys_meta_path, *sys_path_hooks;
|
||||
if (_PySys_GetOptionalAttrString("path", &sys_path) < 0) {
|
||||
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",
|
||||
abs_name, Py_None, sys_path ? sys_path : Py_None,
|
||||
sys_meta_path ? sys_meta_path : Py_None,
|
||||
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;
|
||||
}
|
||||
Py_XDECREF(sys_path_hooks);
|
||||
Py_XDECREF(sys_meta_path);
|
||||
Py_XDECREF(sys_path);
|
||||
|
||||
|
||||
/* XOptions is initialized after first some imports.
|
||||
|
@ -4074,10 +4086,8 @@ _PyImport_FiniCore(PyInterpreterState *interp)
|
|||
static int
|
||||
init_zipimport(PyThreadState *tstate, int verbose)
|
||||
{
|
||||
PyObject *path_hooks = PySys_GetObject("path_hooks");
|
||||
PyObject *path_hooks = _PySys_GetRequiredAttrString("path_hooks");
|
||||
if (path_hooks == NULL) {
|
||||
_PyErr_SetString(tstate, PyExc_RuntimeError,
|
||||
"unable to get sys.path_hooks");
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -4097,12 +4107,14 @@ init_zipimport(PyThreadState *tstate, int verbose)
|
|||
int err = PyList_Insert(path_hooks, 0, zipimporter);
|
||||
Py_DECREF(zipimporter);
|
||||
if (err < 0) {
|
||||
Py_DECREF(path_hooks);
|
||||
return -1;
|
||||
}
|
||||
if (verbose) {
|
||||
PySys_WriteStderr("# installed zipimport hook\n");
|
||||
}
|
||||
}
|
||||
Py_DECREF(path_hooks);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -3470,10 +3470,13 @@ _Py_DumpPathConfig(PyThreadState *tstate)
|
|||
|
||||
#define DUMP_SYS(NAME) \
|
||||
do { \
|
||||
obj = PySys_GetObject(#NAME); \
|
||||
PySys_FormatStderr(" sys.%s = ", #NAME); \
|
||||
if (_PySys_GetOptionalAttrString(#NAME, &obj) < 0) { \
|
||||
PyErr_Clear(); \
|
||||
} \
|
||||
if (obj != NULL) { \
|
||||
PySys_FormatStderr("%A", obj); \
|
||||
Py_DECREF(obj); \
|
||||
} \
|
||||
else { \
|
||||
PySys_WriteStderr("(not set)"); \
|
||||
|
@ -3491,7 +3494,8 @@ _Py_DumpPathConfig(PyThreadState *tstate)
|
|||
DUMP_SYS(exec_prefix);
|
||||
#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)) {
|
||||
PySys_WriteStderr(" sys.path = [\n");
|
||||
Py_ssize_t len = PyList_GET_SIZE(sys_path);
|
||||
|
@ -3501,6 +3505,7 @@ _Py_DumpPathConfig(PyThreadState *tstate)
|
|||
}
|
||||
PySys_WriteStderr(" ]\n");
|
||||
}
|
||||
Py_XDECREF(sys_path);
|
||||
|
||||
_PyErr_SetRaisedException(tstate, exc);
|
||||
}
|
||||
|
@ -4110,22 +4115,10 @@ _PyConfig_CreateXOptionsDict(const PyConfig *config)
|
|||
}
|
||||
|
||||
|
||||
static PyObject*
|
||||
config_get_sys(const char *name)
|
||||
{
|
||||
PyObject *value = PySys_GetObject(name);
|
||||
if (value == NULL) {
|
||||
PyErr_Format(PyExc_RuntimeError, "lost sys.%s", name);
|
||||
return NULL;
|
||||
}
|
||||
return Py_NewRef(value);
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
config_get_sys_write_bytecode(const PyConfig *config, int *value)
|
||||
{
|
||||
PyObject *attr = config_get_sys("dont_write_bytecode");
|
||||
PyObject *attr = _PySys_GetRequiredAttrString("dont_write_bytecode");
|
||||
if (attr == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
@ -4146,7 +4139,7 @@ config_get(const PyConfig *config, const PyConfigSpec *spec,
|
|||
{
|
||||
if (use_sys) {
|
||||
if (spec->sys.attr != NULL) {
|
||||
return config_get_sys(spec->sys.attr);
|
||||
return _PySys_GetRequiredAttrString(spec->sys.attr);
|
||||
}
|
||||
|
||||
if (strcmp(spec->name, "write_bytecode") == 0) {
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
#include "pycore_intrinsics.h" // INTRINSIC_PRINT
|
||||
#include "pycore_pyerrors.h" // _PyErr_SetString()
|
||||
#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()
|
||||
|
||||
|
||||
|
@ -23,16 +23,16 @@ no_intrinsic1(PyThreadState* tstate, PyObject *unused)
|
|||
}
|
||||
|
||||
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.
|
||||
if (hook == NULL) {
|
||||
_PyErr_SetString(tstate, PyExc_RuntimeError,
|
||||
"lost sys.displayhook");
|
||||
return NULL;
|
||||
}
|
||||
return PyObject_CallOneArg(hook, value);
|
||||
PyObject *res = PyObject_CallOneArg(hook, value);
|
||||
Py_DECREF(hook);
|
||||
return res;
|
||||
}
|
||||
|
||||
static int
|
||||
|
|
|
@ -27,7 +27,7 @@
|
|||
#include "pycore_runtime_init.h" // _PyRuntimeState_INIT
|
||||
#include "pycore_setobject.h" // _PySet_NextEntry()
|
||||
#include "pycore_sliceobject.h" // _PySlice_Fini()
|
||||
#include "pycore_sysmodule.h" // _PySys_GetAttr()
|
||||
#include "pycore_sysmodule.h" // _PySys_ClearAttrString()
|
||||
#include "pycore_traceback.h" // _Py_DumpTracebackThreads()
|
||||
#include "pycore_uniqueid.h" // _PyObject_FinalizeUniqueIdPool()
|
||||
#include "pycore_typeobject.h" // _PyTypes_InitTypes()
|
||||
|
@ -1254,8 +1254,12 @@ init_interp_main(PyThreadState *tstate)
|
|||
|
||||
if (is_main_interp) {
|
||||
/* Initialize warnings. */
|
||||
PyObject *warnoptions = PySys_GetObject("warnoptions");
|
||||
if (warnoptions != NULL && PyList_Size(warnoptions) > 0)
|
||||
PyObject *warnoptions;
|
||||
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");
|
||||
if (warnings_module == NULL) {
|
||||
|
@ -1264,6 +1268,7 @@ init_interp_main(PyThreadState *tstate)
|
|||
}
|
||||
Py_XDECREF(warnings_module);
|
||||
}
|
||||
Py_XDECREF(warnoptions);
|
||||
|
||||
interp->runtime->initialized = 1;
|
||||
}
|
||||
|
@ -1770,24 +1775,33 @@ file_is_closed(PyObject *fobj)
|
|||
static int
|
||||
flush_std_files(void)
|
||||
{
|
||||
PyThreadState *tstate = _PyThreadState_GET();
|
||||
PyObject *fout = _PySys_GetAttr(tstate, &_Py_ID(stdout));
|
||||
PyObject *ferr = _PySys_GetAttr(tstate, &_Py_ID(stderr));
|
||||
PyObject *file;
|
||||
int status = 0;
|
||||
|
||||
if (fout != NULL && fout != Py_None && !file_is_closed(fout)) {
|
||||
if (_PyFile_Flush(fout) < 0) {
|
||||
PyErr_FormatUnraisable("Exception ignored while flushing sys.stdout");
|
||||
if (_PySys_GetOptionalAttr(&_Py_ID(stdout), &file) < 0) {
|
||||
status = -1;
|
||||
}
|
||||
else if (file != NULL && file != Py_None && !file_is_closed(file)) {
|
||||
if (_PyFile_Flush(file) < 0) {
|
||||
status = -1;
|
||||
}
|
||||
}
|
||||
if (status < 0) {
|
||||
PyErr_FormatUnraisable("Exception ignored while flushing sys.stdout");
|
||||
}
|
||||
Py_XDECREF(file);
|
||||
|
||||
if (ferr != NULL && ferr != Py_None && !file_is_closed(ferr)) {
|
||||
if (_PyFile_Flush(ferr) < 0) {
|
||||
if (_PySys_GetOptionalAttr(&_Py_ID(stderr), &file) < 0) {
|
||||
PyErr_Clear();
|
||||
status = -1;
|
||||
}
|
||||
else if (file != NULL && file != Py_None && !file_is_closed(file)) {
|
||||
if (_PyFile_Flush(file) < 0) {
|
||||
PyErr_Clear();
|
||||
status = -1;
|
||||
}
|
||||
}
|
||||
Py_XDECREF(file);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
@ -2998,10 +3012,14 @@ _Py_FatalError_PrintExc(PyThreadState *tstate)
|
|||
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) {
|
||||
/* sys.stderr is not set yet or set to None,
|
||||
no need to try to display the exception */
|
||||
Py_XDECREF(ferr);
|
||||
Py_DECREF(exc);
|
||||
return 0;
|
||||
}
|
||||
|
@ -3017,6 +3035,7 @@ _Py_FatalError_PrintExc(PyThreadState *tstate)
|
|||
if (_PyFile_Flush(ferr) < 0) {
|
||||
_PyErr_Clear(tstate);
|
||||
}
|
||||
Py_DECREF(ferr);
|
||||
|
||||
return has_tb;
|
||||
}
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
#include "pycore_pylifecycle.h" // _Py_FdIsInteractive()
|
||||
#include "pycore_pystate.h" // _PyInterpreterState_GET()
|
||||
#include "pycore_pythonrun.h" // export _PyRun_InteractiveLoopObject()
|
||||
#include "pycore_sysmodule.h" // _PySys_GetAttr()
|
||||
#include "pycore_sysmodule.h" // _PySys_SetAttr()
|
||||
#include "pycore_traceback.h" // _PyTraceBack_Print()
|
||||
|
||||
#include "errcode.h" // E_EOF
|
||||
|
@ -110,17 +110,35 @@ _PyRun_InteractiveLoopObject(FILE *fp, PyObject *filename, PyCompilerFlags *flag
|
|||
flags = &local_flags;
|
||||
}
|
||||
|
||||
PyThreadState *tstate = _PyThreadState_GET();
|
||||
PyObject *v = _PySys_GetAttr(tstate, &_Py_ID(ps1));
|
||||
if (v == NULL) {
|
||||
_PySys_SetAttr(&_Py_ID(ps1), v = PyUnicode_FromString(">>> "));
|
||||
Py_XDECREF(v);
|
||||
PyObject *v;
|
||||
if (_PySys_GetOptionalAttr(&_Py_ID(ps1), &v) < 0) {
|
||||
PyErr_Print();
|
||||
return -1;
|
||||
}
|
||||
v = _PySys_GetAttr(tstate, &_Py_ID(ps2));
|
||||
if (v == NULL) {
|
||||
_PySys_SetAttr(&_Py_ID(ps2), v = PyUnicode_FromString("... "));
|
||||
Py_XDECREF(v);
|
||||
v = PyUnicode_FromString(">>> ");
|
||||
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
|
||||
int show_ref_count = _Py_GetConfig()->show_ref_count;
|
||||
|
@ -180,31 +198,37 @@ pyrun_one_parse_ast(FILE *fp, PyObject *filename,
|
|||
PyCompilerFlags *flags, PyArena *arena,
|
||||
mod_ty *pmod, PyObject** interactive_src)
|
||||
{
|
||||
PyThreadState *tstate = _PyThreadState_GET();
|
||||
|
||||
// Get sys.stdin.encoding (as UTF-8)
|
||||
PyObject *attr; // borrowed ref
|
||||
PyObject *attr;
|
||||
PyObject *encoding_obj = NULL;
|
||||
const char *encoding = NULL;
|
||||
if (fp == stdin) {
|
||||
attr = _PySys_GetAttr(tstate, &_Py_ID(stdin));
|
||||
if (attr && attr != Py_None) {
|
||||
encoding_obj = PyObject_GetAttr(attr, &_Py_ID(encoding));
|
||||
if (encoding_obj) {
|
||||
if (_PySys_GetOptionalAttr(&_Py_ID(stdin), &attr) < 0) {
|
||||
PyErr_Clear();
|
||||
}
|
||||
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);
|
||||
if (!encoding) {
|
||||
PyErr_Clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
Py_XDECREF(attr);
|
||||
}
|
||||
|
||||
// Get sys.ps1 (as UTF-8)
|
||||
attr = _PySys_GetAttr(tstate, &_Py_ID(ps1));
|
||||
PyObject *ps1_obj = NULL;
|
||||
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);
|
||||
Py_DECREF(attr);
|
||||
if (ps1_obj == NULL) {
|
||||
PyErr_Clear();
|
||||
}
|
||||
|
@ -218,11 +242,14 @@ pyrun_one_parse_ast(FILE *fp, PyObject *filename,
|
|||
}
|
||||
|
||||
// Get sys.ps2 (as UTF-8)
|
||||
attr = _PySys_GetAttr(tstate, &_Py_ID(ps2));
|
||||
PyObject *ps2_obj = NULL;
|
||||
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);
|
||||
Py_DECREF(attr);
|
||||
if (ps2_obj == NULL) {
|
||||
PyErr_Clear();
|
||||
}
|
||||
|
@ -627,9 +654,11 @@ _Py_HandleSystemExitAndKeyboardInterrupt(int *exitcode_p)
|
|||
Py_SETREF(exc, code);
|
||||
}
|
||||
|
||||
PyThreadState *tstate = _PyThreadState_GET();
|
||||
PyObject *sys_stderr = _PySys_GetAttr(tstate, &_Py_ID(stderr));
|
||||
if (sys_stderr != NULL && sys_stderr != Py_None) {
|
||||
PyObject *sys_stderr;
|
||||
if (_PySys_GetOptionalAttr(&_Py_ID(stderr), &sys_stderr) < 0) {
|
||||
PyErr_Clear();
|
||||
}
|
||||
else if (sys_stderr != NULL && sys_stderr != Py_None) {
|
||||
if (PyFile_WriteObject(exc, sys_stderr, Py_PRINT_RAW) < 0) {
|
||||
PyErr_Clear();
|
||||
}
|
||||
|
@ -641,6 +670,7 @@ _Py_HandleSystemExitAndKeyboardInterrupt(int *exitcode_p)
|
|||
fflush(stderr);
|
||||
}
|
||||
PySys_WriteStderr("\n");
|
||||
Py_XDECREF(sys_stderr);
|
||||
Py_CLEAR(exc);
|
||||
*exitcode_p = 1;
|
||||
return 1;
|
||||
|
@ -660,7 +690,7 @@ handle_system_exit(void)
|
|||
static void
|
||||
_PyErr_PrintEx(PyThreadState *tstate, int set_sys_last_vars)
|
||||
{
|
||||
PyObject *typ = NULL, *tb = NULL;
|
||||
PyObject *typ = NULL, *tb = NULL, *hook = NULL;
|
||||
handle_system_exit();
|
||||
|
||||
PyObject *exc = _PyErr_GetRaisedException(tstate);
|
||||
|
@ -689,7 +719,9 @@ _PyErr_PrintEx(PyThreadState *tstate, int set_sys_last_vars)
|
|||
_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,
|
||||
typ, exc, tb) < 0) {
|
||||
if (PyErr_ExceptionMatches(PyExc_RuntimeError)) {
|
||||
|
@ -723,6 +755,7 @@ _PyErr_PrintEx(PyThreadState *tstate, int set_sys_last_vars)
|
|||
}
|
||||
|
||||
done:
|
||||
Py_XDECREF(hook);
|
||||
Py_XDECREF(typ);
|
||||
Py_XDECREF(exc);
|
||||
Py_XDECREF(tb);
|
||||
|
@ -1160,17 +1193,24 @@ fallback:
|
|||
void
|
||||
PyErr_Display(PyObject *unused, PyObject *value, PyObject *tb)
|
||||
{
|
||||
PyThreadState *tstate = _PyThreadState_GET();
|
||||
PyObject *file = _PySys_GetAttr(tstate, &_Py_ID(stderr));
|
||||
PyObject *file;
|
||||
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) {
|
||||
_PyObject_Dump(value);
|
||||
fprintf(stderr, "lost sys.stderr\n");
|
||||
return;
|
||||
}
|
||||
if (file == Py_None) {
|
||||
Py_DECREF(file);
|
||||
return;
|
||||
}
|
||||
Py_INCREF(file);
|
||||
_PyErr_Display(file, NULL, value, tb);
|
||||
Py_DECREF(file);
|
||||
}
|
||||
|
@ -1277,11 +1317,15 @@ PyRun_FileExFlags(FILE *fp, const char *filename, int start, PyObject *globals,
|
|||
static void
|
||||
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 (_PyFile_Flush(f) < 0) {
|
||||
PyErr_Clear();
|
||||
}
|
||||
Py_DECREF(f);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -72,48 +72,92 @@ module sys
|
|||
|
||||
|
||||
PyObject *
|
||||
_PySys_GetAttr(PyThreadState *tstate, PyObject *name)
|
||||
_PySys_GetRequiredAttr(PyObject *name)
|
||||
{
|
||||
PyObject *sd = tstate->interp->sysdict;
|
||||
if (sd == NULL) {
|
||||
if (!PyUnicode_Check(name)) {
|
||||
PyErr_Format(PyExc_TypeError,
|
||||
"attribute name must be string, not '%.200s'",
|
||||
Py_TYPE(name)->tp_name);
|
||||
return NULL;
|
||||
}
|
||||
PyObject *exc = _PyErr_GetRaisedException(tstate);
|
||||
/* XXX Suppress a new exception if it was raised and restore
|
||||
* the old one. */
|
||||
PyObject *value = _PyDict_GetItemWithError(sd, name);
|
||||
_PyErr_SetRaisedException(tstate, exc);
|
||||
return value;
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
_PySys_GetObject(PyInterpreterState *interp, const char *name)
|
||||
{
|
||||
PyObject *sysdict = interp->sysdict;
|
||||
PyThreadState *tstate = _PyThreadState_GET();
|
||||
PyObject *sysdict = tstate->interp->sysdict;
|
||||
if (sysdict == NULL) {
|
||||
PyErr_SetString(PyExc_RuntimeError, "no sys module");
|
||||
return NULL;
|
||||
}
|
||||
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;
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
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 *
|
||||
PySys_GetObject(const char *name)
|
||||
{
|
||||
PyThreadState *tstate = _PyThreadState_GET();
|
||||
|
||||
PyObject *sysdict = tstate->interp->sysdict;
|
||||
if (sysdict == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
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
|
||||
* the old one. */
|
||||
if (_PyErr_Occurred(tstate)) {
|
||||
PyErr_FormatUnraisable("Exception ignored in PySys_GetObject()");
|
||||
}
|
||||
_PyErr_SetRaisedException(tstate, exc);
|
||||
Py_XDECREF(value); // return a borrowed reference
|
||||
return value;
|
||||
}
|
||||
|
||||
|
@ -124,6 +168,10 @@ sys_set_object(PyInterpreterState *interp, PyObject *key, PyObject *v)
|
|||
return -1;
|
||||
}
|
||||
PyObject *sd = interp->sysdict;
|
||||
if (sd == NULL) {
|
||||
PyErr_SetString(PyExc_RuntimeError, "no sys module");
|
||||
return -1;
|
||||
}
|
||||
if (v == NULL) {
|
||||
if (PyDict_Pop(sd, key, NULL) < 0) {
|
||||
return -1;
|
||||
|
@ -721,9 +769,13 @@ sys_displayhook(PyObject *module, PyObject *o)
|
|||
}
|
||||
if (PyObject_SetAttr(builtins, _Py_LATIN1_CHR('_'), Py_None) != 0)
|
||||
return NULL;
|
||||
outf = _PySys_GetAttr(tstate, &_Py_ID(stdout));
|
||||
if (outf == NULL || outf == Py_None) {
|
||||
outf = _PySys_GetRequiredAttr(&_Py_ID(stdout));
|
||||
if (outf == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
if (outf == Py_None) {
|
||||
_PyErr_SetString(tstate, PyExc_RuntimeError, "lost sys.stdout");
|
||||
Py_DECREF(outf);
|
||||
return NULL;
|
||||
}
|
||||
if (PyFile_WriteObject(o, outf, 0) != 0) {
|
||||
|
@ -734,17 +786,23 @@ sys_displayhook(PyObject *module, PyObject *o)
|
|||
_PyErr_Clear(tstate);
|
||||
err = sys_displayhook_unencodable(outf, o);
|
||||
if (err) {
|
||||
Py_DECREF(outf);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
else {
|
||||
Py_DECREF(outf);
|
||||
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;
|
||||
if (PyObject_SetAttr(builtins, _Py_LATIN1_CHR('_'), o) != 0)
|
||||
}
|
||||
Py_DECREF(outf);
|
||||
if (PyObject_SetAttr(builtins, _Py_LATIN1_CHR('_'), o) != 0) {
|
||||
return NULL;
|
||||
}
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
|
@ -2814,7 +2872,10 @@ _PySys_ReadPreinitXOptions(PyConfig *config)
|
|||
static PyObject *
|
||||
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)) {
|
||||
/* PEP432 TODO: we can reach this if warnoptions is NULL in the main
|
||||
* interpreter config. When that happens, we need to properly set
|
||||
|
@ -2826,6 +2887,7 @@ get_warnoptions(PyThreadState *tstate)
|
|||
* call optional for embedding applications, thus making this
|
||||
* reachable again.
|
||||
*/
|
||||
Py_XDECREF(warnoptions);
|
||||
warnoptions = PyList_New(0);
|
||||
if (warnoptions == NULL) {
|
||||
return NULL;
|
||||
|
@ -2834,7 +2896,6 @@ get_warnoptions(PyThreadState *tstate)
|
|||
Py_DECREF(warnoptions);
|
||||
return NULL;
|
||||
}
|
||||
Py_DECREF(warnoptions);
|
||||
}
|
||||
return warnoptions;
|
||||
}
|
||||
|
@ -2848,10 +2909,15 @@ PySys_ResetWarnOptions(void)
|
|||
return;
|
||||
}
|
||||
|
||||
PyObject *warnoptions = _PySys_GetAttr(tstate, &_Py_ID(warnoptions));
|
||||
if (warnoptions == NULL || !PyList_Check(warnoptions))
|
||||
PyObject *warnoptions;
|
||||
if (_PySys_GetOptionalAttr(&_Py_ID(warnoptions), &warnoptions) < 0) {
|
||||
PyErr_Clear();
|
||||
return;
|
||||
PyList_SetSlice(warnoptions, 0, PyList_GET_SIZE(warnoptions), NULL);
|
||||
}
|
||||
if (warnoptions != NULL && PyList_Check(warnoptions)) {
|
||||
PyList_SetSlice(warnoptions, 0, PyList_GET_SIZE(warnoptions), NULL);
|
||||
}
|
||||
Py_XDECREF(warnoptions);
|
||||
}
|
||||
|
||||
static int
|
||||
|
@ -2863,8 +2929,10 @@ _PySys_AddWarnOptionWithError(PyThreadState *tstate, PyObject *option)
|
|||
return -1;
|
||||
}
|
||||
if (PyList_Append(warnoptions, option)) {
|
||||
Py_DECREF(warnoptions);
|
||||
return -1;
|
||||
}
|
||||
Py_DECREF(warnoptions);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -2905,16 +2973,24 @@ _Py_COMP_DIAG_POP
|
|||
PyAPI_FUNC(int)
|
||||
PySys_HasWarnOptions(void)
|
||||
{
|
||||
PyThreadState *tstate = _PyThreadState_GET();
|
||||
PyObject *warnoptions = _PySys_GetAttr(tstate, &_Py_ID(warnoptions));
|
||||
return (warnoptions != NULL && PyList_Check(warnoptions)
|
||||
&& PyList_GET_SIZE(warnoptions) > 0);
|
||||
PyObject *warnoptions;
|
||||
if (_PySys_GetOptionalAttr(&_Py_ID(warnoptions), &warnoptions) < 0) {
|
||||
PyErr_Clear();
|
||||
return 0;
|
||||
}
|
||||
int r = (warnoptions != NULL && PyList_Check(warnoptions) &&
|
||||
PyList_GET_SIZE(warnoptions) > 0);
|
||||
Py_XDECREF(warnoptions);
|
||||
return r;
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
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)) {
|
||||
/* PEP432 TODO: we can reach this if xoptions is NULL in the main
|
||||
* interpreter config. When that happens, we need to properly set
|
||||
|
@ -2926,6 +3002,7 @@ get_xoptions(PyThreadState *tstate)
|
|||
* call optional for embedding applications, thus making this
|
||||
* reachable again.
|
||||
*/
|
||||
Py_XDECREF(xoptions);
|
||||
xoptions = PyDict_New();
|
||||
if (xoptions == NULL) {
|
||||
return NULL;
|
||||
|
@ -2934,7 +3011,6 @@ get_xoptions(PyThreadState *tstate)
|
|||
Py_DECREF(xoptions);
|
||||
return NULL;
|
||||
}
|
||||
Py_DECREF(xoptions);
|
||||
}
|
||||
return xoptions;
|
||||
}
|
||||
|
@ -2973,11 +3049,13 @@ _PySys_AddXOptionWithError(const wchar_t *s)
|
|||
}
|
||||
Py_DECREF(name);
|
||||
Py_DECREF(value);
|
||||
Py_DECREF(opts);
|
||||
return 0;
|
||||
|
||||
error:
|
||||
Py_XDECREF(name);
|
||||
Py_XDECREF(value);
|
||||
Py_XDECREF(opts);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -3000,7 +3078,9 @@ PyObject *
|
|||
PySys_GetXOptions(void)
|
||||
{
|
||||
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.
|
||||
|
@ -3159,11 +3239,8 @@ sys_set_flag(PyObject *flags, Py_ssize_t pos, PyObject *value)
|
|||
int
|
||||
_PySys_SetFlagObj(Py_ssize_t pos, PyObject *value)
|
||||
{
|
||||
PyObject *flags = Py_XNewRef(PySys_GetObject("flags"));
|
||||
PyObject *flags = _PySys_GetRequiredAttrString("flags");
|
||||
if (flags == NULL) {
|
||||
if (!PyErr_Occurred()) {
|
||||
PyErr_SetString(PyExc_RuntimeError, "lost sys.flags");
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -3722,16 +3799,15 @@ _PySys_UpdateConfig(PyThreadState *tstate)
|
|||
#undef COPY_WSTR
|
||||
|
||||
// sys.flags
|
||||
PyObject *flags = _PySys_GetObject(interp, "flags"); // borrowed ref
|
||||
PyObject *flags = _PySys_GetRequiredAttrString("flags");
|
||||
if (flags == NULL) {
|
||||
if (!_PyErr_Occurred(tstate)) {
|
||||
_PyErr_SetString(tstate, PyExc_RuntimeError, "lost sys.flags");
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
if (set_flags_from_config(interp, flags) < 0) {
|
||||
Py_DECREF(flags);
|
||||
return -1;
|
||||
}
|
||||
Py_DECREF(flags);
|
||||
|
||||
SET_SYS("dont_write_bytecode", PyBool_FromLong(!config->write_bytecode));
|
||||
|
||||
|
@ -3963,12 +4039,15 @@ PySys_SetArgvEx(int argc, wchar_t **argv, int updatepath)
|
|||
Py_FatalError("can't compute path0 from argv");
|
||||
}
|
||||
|
||||
PyObject *sys_path = _PySys_GetAttr(tstate, &_Py_ID(path));
|
||||
if (sys_path != NULL) {
|
||||
PyObject *sys_path;
|
||||
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) {
|
||||
Py_DECREF(path0);
|
||||
Py_FatalError("can't prepend path0 to sys.path");
|
||||
}
|
||||
Py_DECREF(sys_path);
|
||||
}
|
||||
Py_DECREF(path0);
|
||||
}
|
||||
|
@ -4056,8 +4135,8 @@ sys_write(PyObject *key, FILE *fp, const char *format, va_list va)
|
|||
PyThreadState *tstate = _PyThreadState_GET();
|
||||
|
||||
PyObject *exc = _PyErr_GetRaisedException(tstate);
|
||||
file = _PySys_GetAttr(tstate, key);
|
||||
written = PyOS_vsnprintf(buffer, sizeof(buffer), format, va);
|
||||
file = _PySys_GetRequiredAttr(key);
|
||||
if (sys_pyfile_write(buffer, file) != 0) {
|
||||
_PyErr_Clear(tstate);
|
||||
fputs(buffer, fp);
|
||||
|
@ -4067,6 +4146,7 @@ sys_write(PyObject *key, FILE *fp, const char *format, va_list va)
|
|||
if (sys_pyfile_write(truncated, file) != 0)
|
||||
fputs(truncated, fp);
|
||||
}
|
||||
Py_XDECREF(file);
|
||||
_PyErr_SetRaisedException(tstate, exc);
|
||||
}
|
||||
|
||||
|
@ -4098,15 +4178,16 @@ sys_format(PyObject *key, FILE *fp, const char *format, va_list va)
|
|||
PyThreadState *tstate = _PyThreadState_GET();
|
||||
|
||||
PyObject *exc = _PyErr_GetRaisedException(tstate);
|
||||
file = _PySys_GetAttr(tstate, key);
|
||||
message = PyUnicode_FromFormatV(format, va);
|
||||
if (message != NULL) {
|
||||
file = _PySys_GetRequiredAttr(key);
|
||||
if (sys_pyfile_write_unicode(message, file) != 0) {
|
||||
_PyErr_Clear(tstate);
|
||||
utf8 = PyUnicode_AsUTF8(message);
|
||||
if (utf8 != NULL)
|
||||
fputs(utf8, fp);
|
||||
}
|
||||
Py_XDECREF(file);
|
||||
Py_DECREF(message);
|
||||
}
|
||||
_PyErr_SetRaisedException(tstate, exc);
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
#include "pycore_pyarena.h" // _PyArena_Free()
|
||||
#include "pycore_pyerrors.h" // _PyErr_GetRaisedException()
|
||||
#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 "frameobject.h" // PyFrame_New()
|
||||
|
@ -356,9 +356,13 @@ _Py_FindSourceFile(PyObject *filename, char* namebuf, size_t namelen, PyObject *
|
|||
taillen = strlen(tail);
|
||||
|
||||
PyThreadState *tstate = _PyThreadState_GET();
|
||||
syspath = _PySys_GetAttr(tstate, &_Py_ID(path));
|
||||
if (syspath == NULL || !PyList_Check(syspath))
|
||||
if (_PySys_GetOptionalAttr(&_Py_ID(path), &syspath) < 0) {
|
||||
PyErr_Clear();
|
||||
goto error;
|
||||
}
|
||||
if (syspath == NULL || !PyList_Check(syspath)) {
|
||||
goto error;
|
||||
}
|
||||
npath = PyList_Size(syspath);
|
||||
|
||||
open = PyObject_GetAttr(io, &_Py_ID(open));
|
||||
|
@ -401,6 +405,7 @@ error:
|
|||
result = NULL;
|
||||
finally:
|
||||
Py_XDECREF(open);
|
||||
Py_XDECREF(syspath);
|
||||
Py_DECREF(filebytes);
|
||||
return result;
|
||||
}
|
||||
|
@ -729,17 +734,21 @@ _PyTraceBack_Print(PyObject *v, const char *header, PyObject *f)
|
|||
PyErr_BadInternalCall();
|
||||
return -1;
|
||||
}
|
||||
limitv = PySys_GetObject("tracebacklimit");
|
||||
if (limitv && PyLong_Check(limitv)) {
|
||||
if (_PySys_GetOptionalAttrString("tracebacklimit", &limitv) < 0) {
|
||||
return -1;
|
||||
}
|
||||
else if (limitv != NULL && PyLong_Check(limitv)) {
|
||||
int overflow;
|
||||
limit = PyLong_AsLongAndOverflow(limitv, &overflow);
|
||||
if (overflow > 0) {
|
||||
limit = LONG_MAX;
|
||||
}
|
||||
else if (limit <= 0) {
|
||||
Py_DECREF(limitv);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
Py_XDECREF(limitv);
|
||||
|
||||
if (PyFile_WriteString(header, f) < 0) {
|
||||
return -1;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue