summaryrefslogtreecommitdiffstats
path: root/contrib/tools/python3/Python/sysmodule.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/tools/python3/Python/sysmodule.c')
-rw-r--r--contrib/tools/python3/Python/sysmodule.c651
1 files changed, 488 insertions, 163 deletions
diff --git a/contrib/tools/python3/Python/sysmodule.c b/contrib/tools/python3/Python/sysmodule.c
index 7813048be45..782c595d2ab 100644
--- a/contrib/tools/python3/Python/sysmodule.c
+++ b/contrib/tools/python3/Python/sysmodule.c
@@ -17,29 +17,37 @@ Data members:
#include "Python.h"
#include "pycore_call.h" // _PyObject_CallNoArgs()
#include "pycore_ceval.h" // _PyEval_SetAsyncGenFinalizer()
+#include "pycore_dict.h" // _PyDict_GetItemWithError()
#include "pycore_frame.h" // _PyInterpreterFrame
#include "pycore_initconfig.h" // _PyStatus_EXCEPTION()
#include "pycore_long.h" // _PY_LONG_MAX_STR_DIGITS_THRESHOLD
+#include "pycore_modsupport.h" // _PyModule_CreateInitialized()
#include "pycore_namespace.h" // _PyNamespace_New()
-#include "pycore_object.h" // _PyObject_IS_GC()
+#include "pycore_object.h" // _PyObject_DebugTypeStats()
#include "pycore_pathconfig.h" // _PyPathConfig_ComputeSysPath0()
#include "pycore_pyerrors.h" // _PyErr_GetRaisedException()
#include "pycore_pylifecycle.h" // _PyErr_WriteUnraisableDefaultHook()
#include "pycore_pymath.h" // _PY_SHORT_FLOAT_REPR
#include "pycore_pymem.h" // _PyMem_SetDefaultAllocator()
#include "pycore_pystate.h" // _PyThreadState_GET()
+#include "pycore_pystats.h" // _Py_PrintSpecializationStats()
#include "pycore_structseq.h" // _PyStructSequence_InitBuiltinWithFlags()
+#include "pycore_sysmodule.h" // export _PySys_GetSizeOf()
#include "pycore_tuple.h" // _PyTuple_FromArray()
-#include "frameobject.h" // PyFrame_FastToLocalsWithError()
-#include "pydtrace.h"
+#include "pydtrace.h" // PyDTrace_AUDIT()
#include "osdefs.h" // DELIM
#include "stdlib_module_names.h" // _Py_stdlib_module_names
-#include <locale.h>
+
+#ifdef HAVE_UNISTD_H
+# include <unistd.h> // getpid()
+#endif
#ifdef MS_WINDOWS
-#define WIN32_LEAN_AND_MEAN
-#include <windows.h>
+# ifndef WIN32_LEAN_AND_MEAN
+# define WIN32_LEAN_AND_MEAN
+# endif
+# include <windows.h>
#endif /* MS_WINDOWS */
#ifdef MS_COREDLL
@@ -49,11 +57,11 @@ extern const char *PyWin_DLLVersionString;
#endif
#ifdef __EMSCRIPTEN__
-#error #include <emscripten.h>
+# error #include <emscripten.h>
#endif
#ifdef HAVE_FCNTL_H
-#include <fcntl.h>
+# include <fcntl.h>
#endif
/*[clinic input]
@@ -63,6 +71,7 @@ module sys
#include "clinic/sysmodule.c.h"
+
PyObject *
_PySys_GetAttr(PyThreadState *tstate, PyObject *name)
{
@@ -78,26 +87,93 @@ _PySys_GetAttr(PyThreadState *tstate, PyObject *name)
return value;
}
-static PyObject *
-_PySys_GetObject(PyInterpreterState *interp, const char *name)
+ PyObject *
+_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) {
+ PyErr_SetString(PyExc_RuntimeError, "no sys module");
return NULL;
}
- return _PyDict_GetItemStringWithError(sysdict, name);
+ PyObject *value;
+ if (PyDict_GetItemRef(sysdict, name, &value) == 0) {
+ PyErr_Format(PyExc_RuntimeError, "lost sys.%U", name);
+ }
+ return value;
}
PyObject *
-PySys_GetObject(const char *name)
+_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;
+ }
+ 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;
}
@@ -108,12 +184,14 @@ 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) {
- v = _PyDict_Pop(sd, key, Py_None);
- if (v == NULL) {
+ if (PyDict_Pop(sd, key, NULL) < 0) {
return -1;
}
- Py_DECREF(v);
return 0;
}
else {
@@ -178,9 +256,7 @@ static int
sys_audit_tstate(PyThreadState *ts, const char *event,
const char *argFormat, va_list vargs)
{
- /* N format is inappropriate, because you do not know
- whether the reference is consumed by the call.
- Assert rather than exception for perf reasons */
+ assert(event != NULL);
assert(!argFormat || !strchr(argFormat, 'N'));
if (!ts) {
@@ -211,7 +287,7 @@ sys_audit_tstate(PyThreadState *ts, const char *event,
/* Initialize event args now */
if (argFormat && argFormat[0]) {
- eventArgs = _Py_VaBuildValue_SizeT(argFormat, vargs);
+ eventArgs = Py_VaBuildValue(argFormat, vargs);
if (eventArgs && !PyTuple_Check(eventArgs)) {
PyObject *argTuple = PyTuple_Pack(1, eventArgs);
Py_SETREF(eventArgs, argTuple);
@@ -256,7 +332,7 @@ sys_audit_tstate(PyThreadState *ts, const char *event,
PyThreadState_EnterTracing(ts);
while ((hook = PyIter_Next(hooks)) != NULL) {
PyObject *o;
- int canTrace = _PyObject_LookupAttr(hook, &_Py_ID(__cantrace__), &o);
+ int canTrace = PyObject_GetOptionalAttr(hook, &_Py_ID(__cantrace__), &o);
if (o) {
canTrace = PyObject_IsTrue(o);
Py_DECREF(o);
@@ -268,7 +344,7 @@ sys_audit_tstate(PyThreadState *ts, const char *event,
PyThreadState_LeaveTracing(ts);
}
PyObject* args[2] = {eventName, eventArgs};
- o = _PyObject_FastCallTstate(ts, hook, args, 2);
+ o = _PyObject_VectorcallTstate(ts, hook, args, 2, NULL);
if (canTrace) {
PyThreadState_EnterTracing(ts);
}
@@ -325,6 +401,21 @@ PySys_Audit(const char *event, const char *argFormat, ...)
return res;
}
+int
+PySys_AuditTuple(const char *event, PyObject *args)
+{
+ if (args == NULL) {
+ return PySys_Audit(event, NULL);
+ }
+
+ if (!PyTuple_Check(args)) {
+ PyErr_Format(PyExc_TypeError, "args must be tuple, got %s",
+ Py_TYPE(args)->tp_name);
+ return -1;
+ }
+ return PySys_Audit(event, "O", args);
+}
+
/* We expose this function primarily for our own cleanup during
* finalization. In general, it should not need to be called,
* and as such the function is not exported.
@@ -424,15 +515,9 @@ PySys_AddAuditHook(Py_AuditHookFunction hook, void *userData)
e->hookCFunction = (Py_AuditHookFunction)hook;
e->userData = userData;
- if (runtime->audit_hooks.mutex == NULL) {
- /* The runtime must not be initailized yet. */
- add_audit_hook_entry_unlocked(runtime, e);
- }
- else {
- PyThread_acquire_lock(runtime->audit_hooks.mutex, WAIT_LOCK);
- add_audit_hook_entry_unlocked(runtime, e);
- PyThread_release_lock(runtime->audit_hooks.mutex);
- }
+ PyMutex_Lock(&runtime->audit_hooks.mutex);
+ add_audit_hook_entry_unlocked(runtime, e);
+ PyMutex_Unlock(&runtime->audit_hooks.mutex);
return 0;
}
@@ -479,7 +564,8 @@ sys_addaudithook_impl(PyObject *module, PyObject *hook)
}
PyDoc_STRVAR(audit_doc,
-"audit(event, *args)\n\
+"audit($module, event, /, *args)\n\
+--\n\
\n\
Passes the event to any audit hooks that are attached.");
@@ -496,6 +582,8 @@ sys_audit(PyObject *self, PyObject *const *args, Py_ssize_t argc)
return NULL;
}
+ assert(args[0] != NULL);
+
if (!should_audit(tstate->interp)) {
Py_RETURN_NONE;
}
@@ -620,7 +708,8 @@ sys_breakpointhook(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyOb
}
PyDoc_STRVAR(breakpointhook_doc,
-"breakpointhook(*args, **kws)\n"
+"breakpointhook($module, /, *args, **kwargs)\n"
+"--\n"
"\n"
"This hook function is called by built-in breakpoint().\n"
);
@@ -656,7 +745,7 @@ sys_displayhook_unencodable(PyObject *outf, PyObject *o)
if (encoded == NULL)
goto error;
- if (_PyObject_LookupAttr(outf, &_Py_ID(buffer), &buffer) < 0) {
+ if (PyObject_GetOptionalAttr(outf, &_Py_ID(buffer), &buffer) < 0) {
Py_DECREF(encoded);
goto error;
}
@@ -724,9 +813,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) {
@@ -737,17 +830,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;
}
@@ -862,6 +961,13 @@ sys_exit_impl(PyObject *module, PyObject *status)
}
+static PyObject *
+get_utf8_unicode(void)
+{
+ _Py_DECLARE_STR(utf_8, "utf-8");
+ PyObject *ret = &_Py_STR(utf_8);
+ return Py_NewRef(ret);
+}
/*[clinic input]
sys.getdefaultencoding
@@ -873,9 +979,7 @@ static PyObject *
sys_getdefaultencoding_impl(PyObject *module)
/*[clinic end generated code: output=256d19dfcc0711e6 input=d416856ddbef6909]*/
{
- _Py_DECLARE_STR(utf_8, "utf-8");
- PyObject *ret = &_Py_STR(utf_8);
- return Py_NewRef(ret);
+ return get_utf8_unicode();
}
/*[clinic input]
@@ -890,7 +994,17 @@ sys_getfilesystemencoding_impl(PyObject *module)
{
PyInterpreterState *interp = _PyInterpreterState_GET();
const PyConfig *config = _PyInterpreterState_GetConfig(interp);
- return PyUnicode_FromWideChar(config->filesystem_encoding, -1);
+
+ if (wcscmp(config->filesystem_encoding, L"utf-8") == 0) {
+ return get_utf8_unicode();
+ }
+
+ PyObject *u = PyUnicode_FromWideChar(config->filesystem_encoding, -1);
+ if (u == NULL) {
+ return NULL;
+ }
+ _PyUnicode_InternImmortal(interp, &u);
+ return u;
}
/*[clinic input]
@@ -905,7 +1019,12 @@ sys_getfilesystemencodeerrors_impl(PyObject *module)
{
PyInterpreterState *interp = _PyInterpreterState_GET();
const PyConfig *config = _PyInterpreterState_GetConfig(interp);
- return PyUnicode_FromWideChar(config->filesystem_errors, -1);
+ PyObject *u = PyUnicode_FromWideChar(config->filesystem_errors, -1);
+ if (u == NULL) {
+ return NULL;
+ }
+ _PyUnicode_InternImmortal(interp, &u);
+ return u;
}
/*[clinic input]
@@ -939,6 +1058,23 @@ sys_intern_impl(PyObject *module, PyObject *s)
}
+/*[clinic input]
+sys._is_interned -> bool
+
+ string: unicode
+ /
+
+Return True if the given string is "interned".
+[clinic start generated code]*/
+
+static int
+sys__is_interned_impl(PyObject *module, PyObject *string)
+/*[clinic end generated code: output=c3678267b4e9d7ed input=039843e17883b606]*/
+{
+ return PyUnicode_CHECK_INTERNED(string);
+}
+
+
/*
* Cached interned string objects used for calling the profile and
* trace functions.
@@ -959,23 +1095,13 @@ static PyObject *
call_trampoline(PyThreadState *tstate, PyObject* callback,
PyFrameObject *frame, int what, PyObject *arg)
{
-
- PyObject *stack[3];
- stack[0] = (PyObject *)frame;
- stack[1] = whatstrings[what];
- stack[2] = (arg != NULL) ? arg : Py_None;
-
- /* Discard any previous modifications the frame's fast locals */
- if (frame->f_fast_as_locals) {
- if (PyFrame_FastToLocalsWithError(frame) < 0) {
- return NULL;
- }
- }
-
/* call the Python-level function */
- PyObject *result = _PyObject_FastCallTstate(tstate, callback, stack, 3);
+ if (arg == NULL) {
+ arg = Py_None;
+ }
+ PyObject *args[3] = {(PyObject *)frame, whatstrings[what], arg};
+ PyObject *result = _PyObject_VectorcallTstate(tstate, callback, args, 3, NULL);
- PyFrame_LocalsToFast(frame, 1);
return result;
}
@@ -1026,34 +1152,40 @@ trace_trampoline(PyObject *self, PyFrameObject *frame,
return 0;
}
+/*[clinic input]
+sys.settrace
+
+ function: object
+ /
+
+Set the global debug tracing function.
+
+It will be called on each function call. See the debugger chapter
+in the library manual.
+[clinic start generated code]*/
+
static PyObject *
-sys_settrace(PyObject *self, PyObject *args)
+sys_settrace(PyObject *module, PyObject *function)
+/*[clinic end generated code: output=999d12e9d6ec4678 input=8107feb01c5f1c4e]*/
{
PyThreadState *tstate = _PyThreadState_GET();
- if (args == Py_None) {
+ if (function == Py_None) {
if (_PyEval_SetTrace(tstate, NULL, NULL) < 0) {
return NULL;
}
}
else {
- if (_PyEval_SetTrace(tstate, trace_trampoline, args) < 0) {
+ if (_PyEval_SetTrace(tstate, trace_trampoline, function) < 0) {
return NULL;
}
}
Py_RETURN_NONE;
}
-PyDoc_STRVAR(settrace_doc,
-"settrace(function)\n\
-\n\
-Set the global debug tracing function. It will be called on each\n\
-function call. See the debugger chapter in the library manual."
-);
-
/*[clinic input]
sys._settraceallthreads
- arg: object
+ function as arg: object
/
Set the global debug tracing function in all running threads belonging to the current interpreter.
@@ -1064,7 +1196,7 @@ in the library manual.
static PyObject *
sys__settraceallthreads(PyObject *module, PyObject *arg)
-/*[clinic end generated code: output=161cca30207bf3ca input=5906aa1485a50289]*/
+/*[clinic end generated code: output=161cca30207bf3ca input=d4bde1f810d73675]*/
{
PyObject* argument = NULL;
Py_tracefunc func = NULL;
@@ -1074,9 +1206,10 @@ sys__settraceallthreads(PyObject *module, PyObject *arg)
argument = arg;
}
-
- PyEval_SetTraceAllThreads(func, argument);
-
+ PyInterpreterState *interp = _PyInterpreterState_GET();
+ if (_PyEval_SetTraceAllThreads(interp, func, argument) < 0) {
+ return NULL;
+ }
Py_RETURN_NONE;
}
@@ -1100,45 +1233,51 @@ sys_gettrace_impl(PyObject *module)
return Py_NewRef(temp);
}
+/*[clinic input]
+sys.setprofile
+
+ function: object
+ /
+
+Set the profiling function.
+
+It will be called on each function call and return. See the profiler
+chapter in the library manual.
+[clinic start generated code]*/
+
static PyObject *
-sys_setprofile(PyObject *self, PyObject *args)
+sys_setprofile(PyObject *module, PyObject *function)
+/*[clinic end generated code: output=1c3503105939db9c input=055d0d7961413a62]*/
{
PyThreadState *tstate = _PyThreadState_GET();
- if (args == Py_None) {
+ if (function == Py_None) {
if (_PyEval_SetProfile(tstate, NULL, NULL) < 0) {
return NULL;
}
}
else {
- if (_PyEval_SetProfile(tstate, profile_trampoline, args) < 0) {
+ if (_PyEval_SetProfile(tstate, profile_trampoline, function) < 0) {
return NULL;
}
}
Py_RETURN_NONE;
}
-PyDoc_STRVAR(setprofile_doc,
-"setprofile(function)\n\
-\n\
-Set the profiling function. It will be called on each function call\n\
-and return. See the profiler chapter in the library manual."
-);
-
/*[clinic input]
sys._setprofileallthreads
- arg: object
+ function as arg: object
/
Set the profiling function in all running threads belonging to the current interpreter.
-It will be called on each function call and return. See the profiler chapter
-in the library manual.
+It will be called on each function call and return. See the profiler
+chapter in the library manual.
[clinic start generated code]*/
static PyObject *
sys__setprofileallthreads(PyObject *module, PyObject *arg)
-/*[clinic end generated code: output=2d61319e27b309fe input=d1a356d3f4f9060a]*/
+/*[clinic end generated code: output=2d61319e27b309fe input=a10589439ba20cee]*/
{
PyObject* argument = NULL;
Py_tracefunc func = NULL;
@@ -1148,8 +1287,10 @@ sys__setprofileallthreads(PyObject *module, PyObject *arg)
argument = arg;
}
- PyEval_SetProfileAllThreads(func, argument);
-
+ PyInterpreterState *interp = _PyInterpreterState_GET();
+ if (_PyEval_SetProfileAllThreads(interp, func, argument) < 0) {
+ return NULL;
+ }
Py_RETURN_NONE;
}
@@ -1334,12 +1475,6 @@ sys_set_asyncgen_hooks(PyObject *self, PyObject *args, PyObject *kw)
Py_TYPE(finalizer)->tp_name);
return NULL;
}
- if (_PyEval_SetAsyncGenFinalizer(finalizer) < 0) {
- return NULL;
- }
- }
- else if (finalizer == Py_None && _PyEval_SetAsyncGenFinalizer(NULL) < 0) {
- return NULL;
}
if (firstiter && firstiter != Py_None) {
@@ -1349,15 +1484,33 @@ sys_set_asyncgen_hooks(PyObject *self, PyObject *args, PyObject *kw)
Py_TYPE(firstiter)->tp_name);
return NULL;
}
- if (_PyEval_SetAsyncGenFirstiter(firstiter) < 0) {
+ }
+
+ PyObject *cur_finalizer = _PyEval_GetAsyncGenFinalizer();
+
+ if (finalizer && finalizer != Py_None) {
+ if (_PyEval_SetAsyncGenFinalizer(finalizer) < 0) {
return NULL;
}
}
- else if (firstiter == Py_None && _PyEval_SetAsyncGenFirstiter(NULL) < 0) {
+ else if (finalizer == Py_None && _PyEval_SetAsyncGenFinalizer(NULL) < 0) {
return NULL;
}
+ if (firstiter && firstiter != Py_None) {
+ if (_PyEval_SetAsyncGenFirstiter(firstiter) < 0) {
+ goto error;
+ }
+ }
+ else if (firstiter == Py_None && _PyEval_SetAsyncGenFirstiter(NULL) < 0) {
+ goto error;
+ }
+
Py_RETURN_NONE;
+
+error:
+ _PyEval_SetAsyncGenFinalizer(cur_finalizer);
+ return NULL;
}
PyDoc_STRVAR(set_asyncgen_hooks_doc,
@@ -1543,6 +1696,9 @@ _sys_getwindowsversion_from_kernel32(void)
!GetFileVersionInfoW(kernel32_path, 0, verblock_size, verblock) ||
!VerQueryValueW(verblock, L"", (LPVOID)&ffi, &ffi_len)) {
PyErr_SetFromWindowsErr(0);
+ if (verblock) {
+ PyMem_RawFree(verblock);
+ }
return NULL;
}
@@ -1584,15 +1740,13 @@ sys_getwindowsversion_impl(PyObject *module)
int pos = 0;
OSVERSIONINFOEXW ver;
- version = PyObject_GetAttrString(module, "_cached_windows_version");
+ if (PyObject_GetOptionalAttrString(module, "_cached_windows_version", &version) < 0) {
+ return NULL;
+ };
if (version && PyObject_TypeCheck(version, &WindowsVersionType)) {
return version;
}
- if (!PyErr_ExceptionMatches(PyExc_AttributeError)) {
- return NULL;
- }
Py_XDECREF(version);
- PyErr_Clear();
ver.dwOSVersionInfoSize = sizeof(ver);
if (!GetVersionExW((OSVERSIONINFOW*) &ver))
@@ -1672,6 +1826,13 @@ static PyObject *
sys__enablelegacywindowsfsencoding_impl(PyObject *module)
/*[clinic end generated code: output=f5c3855b45e24fe9 input=2bfa931a20704492]*/
{
+ if (PyErr_WarnEx(PyExc_DeprecationWarning,
+ "sys._enablelegacywindowsfsencoding() is deprecated and will be "
+ "removed in Python 3.16. Use PYTHONLEGACYWINDOWSFSENCODING "
+ "instead.", 1))
+ {
+ return NULL;
+ }
if (_PyUnicode_EnableLegacyWindowsFSEncoding() < 0) {
return NULL;
}
@@ -1828,7 +1989,15 @@ _PySys_GetSizeOf(PyObject *o)
return (size_t)-1;
}
- return (size_t)size + _PyType_PreHeaderSize(Py_TYPE(o));
+ size_t presize = 0;
+ if (!Py_IS_TYPE(o, &PyType_Type) ||
+ PyType_HasFeature((PyTypeObject *)o, Py_TPFLAGS_HEAPTYPE))
+ {
+ /* Add the size of the pre-header if "o" is not a static type */
+ presize = _PyType_PreHeaderSize(Py_TYPE(o));
+ }
+
+ return (size_t)size + presize;
}
static PyObject *
@@ -1958,7 +2127,7 @@ sys__getframe_impl(PyObject *module, int depth)
/*[clinic end generated code: output=d438776c04d59804 input=c1be8a6464b11ee5]*/
{
PyThreadState *tstate = _PyThreadState_GET();
- _PyInterpreterFrame *frame = tstate->cframe->current_frame;
+ _PyInterpreterFrame *frame = tstate->current_frame;
if (frame != NULL) {
while (depth > 0) {
@@ -2034,11 +2203,6 @@ sys_call_tracing_impl(PyObject *module, PyObject *func, PyObject *funcargs)
return _PyEval_CallTracing(func, funcargs);
}
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
/*[clinic input]
sys._debugmallocstats
@@ -2067,10 +2231,6 @@ sys__debugmallocstats_impl(PyObject *module)
extern PyObject *_Py_GetObjects(PyObject *, PyObject *);
#endif
-#ifdef __cplusplus
-}
-#endif
-
/*[clinic input]
sys._clear_type_cache
@@ -2086,6 +2246,24 @@ sys__clear_type_cache_impl(PyObject *module)
Py_RETURN_NONE;
}
+/*[clinic input]
+sys._clear_internal_caches
+
+Clear all internal performance-related caches.
+[clinic start generated code]*/
+
+static PyObject *
+sys__clear_internal_caches_impl(PyObject *module)
+/*[clinic end generated code: output=0ee128670a4966d6 input=253e741ca744f6e8]*/
+{
+#ifdef _Py_TIER2
+ PyInterpreterState *interp = _PyInterpreterState_GET();
+ _Py_Executors_InvalidateAll(interp, 0);
+#endif
+ PyType_ClearCache();
+ Py_RETURN_NONE;
+}
+
/* Note that, for now, we do not have a per-interpreter equivalent
for sys.is_finalizing(). */
@@ -2099,35 +2277,36 @@ static PyObject *
sys_is_finalizing_impl(PyObject *module)
/*[clinic end generated code: output=735b5ff7962ab281 input=f0df747a039948a5]*/
{
- return PyBool_FromLong(_Py_IsFinalizing());
+ return PyBool_FromLong(Py_IsFinalizing());
}
+
#ifdef Py_STATS
/*[clinic input]
sys._stats_on
-Turns on stats gathering (stats gathering is on by default).
+Turns on stats gathering (stats gathering is off by default).
[clinic start generated code]*/
static PyObject *
sys__stats_on_impl(PyObject *module)
-/*[clinic end generated code: output=aca53eafcbb4d9fe input=8ddc6df94e484f3a]*/
+/*[clinic end generated code: output=aca53eafcbb4d9fe input=43b5bfe145299e55]*/
{
- _py_stats = &_py_stats_struct;
+ _Py_StatsOn();
Py_RETURN_NONE;
}
/*[clinic input]
sys._stats_off
-Turns off stats gathering (stats gathering is on by default).
+Turns off stats gathering (stats gathering is off by default).
[clinic start generated code]*/
static PyObject *
sys__stats_off_impl(PyObject *module)
-/*[clinic end generated code: output=1534c1ee63812214 input=b3e50e71ecf29f66]*/
+/*[clinic end generated code: output=1534c1ee63812214 input=d1a84c60c56cbce2]*/
{
- _py_stats = NULL;
+ _Py_StatsOff();
Py_RETURN_NONE;
}
@@ -2146,21 +2325,23 @@ sys__stats_clear_impl(PyObject *module)
}
/*[clinic input]
-sys._stats_dump
+sys._stats_dump -> bool
Dump stats to file, and clears the stats.
+
+Return False if no statistics were not dumped because stats gathering was off.
[clinic start generated code]*/
-static PyObject *
+static int
sys__stats_dump_impl(PyObject *module)
-/*[clinic end generated code: output=79f796fb2b4ddf05 input=92346f16d64f6f95]*/
+/*[clinic end generated code: output=6e346b4ba0de4489 input=31a489e39418b2a5]*/
{
- _Py_PrintSpecializationStats(1);
+ int res = _Py_PrintSpecializationStats(1);
_Py_StatsClear();
- Py_RETURN_NONE;
+ return res;
}
+#endif // Py_STATS
-#endif
#ifdef ANDROID_API_LEVEL
/*[clinic input]
@@ -2201,6 +2382,16 @@ sys_activate_stack_trampoline_impl(PyObject *module, const char *backend)
}
}
}
+ else if (strcmp(backend, "perf_jit") == 0) {
+ _PyPerf_Callbacks cur_cb;
+ _PyPerfTrampoline_GetCallbacks(&cur_cb);
+ if (cur_cb.write_state != _Py_perfmap_jit_callbacks.write_state) {
+ if (_PyPerfTrampoline_SetCallbacks(&_Py_perfmap_jit_callbacks) < 0 ) {
+ PyErr_SetString(PyExc_ValueError, "can't activate perf jit trampoline");
+ return NULL;
+ }
+ }
+ }
else {
PyErr_Format(PyExc_ValueError, "invalid backend: %s", backend);
return NULL;
@@ -2274,7 +2465,7 @@ sys__getframemodulename_impl(PyObject *module, int depth)
if (PySys_Audit("sys._getframemodulename", "i", depth) < 0) {
return NULL;
}
- _PyInterpreterFrame *f = _PyThreadState_GET()->cframe->current_frame;
+ _PyInterpreterFrame *f = _PyThreadState_GET()->current_frame;
while (f && (_PyFrame_IsIncomplete(f) || depth-- > 0)) {
f = f->previous;
}
@@ -2289,10 +2480,52 @@ sys__getframemodulename_impl(PyObject *module, int depth)
return Py_NewRef(r);
}
+/*[clinic input]
+sys._get_cpu_count_config -> int
+
+Private function for getting PyConfig.cpu_count
+[clinic start generated code]*/
+
+static int
+sys__get_cpu_count_config_impl(PyObject *module)
+/*[clinic end generated code: output=36611bb5efad16dc input=523e1ade2204084e]*/
+{
+ const PyConfig *config = _Py_GetConfig();
+ return config->cpu_count;
+}
+
+/*[clinic input]
+sys._baserepl
+
+Private function for getting the base REPL
+[clinic start generated code]*/
+
+static PyObject *
+sys__baserepl_impl(PyObject *module)
+/*[clinic end generated code: output=f19a36375ebe0a45 input=ade0ebb9fab56f3c]*/
+{
+ PyCompilerFlags cf = _PyCompilerFlags_INIT;
+ PyRun_AnyFileExFlags(stdin, "<stdin>", 0, &cf);
+ Py_RETURN_NONE;
+}
+
+/*[clinic input]
+sys._is_gil_enabled -> bool
+
+Return True if the GIL is currently enabled and False otherwise.
+[clinic start generated code]*/
-#ifdef __cplusplus
-extern "C" {
+static int
+sys__is_gil_enabled_impl(PyObject *module)
+/*[clinic end generated code: output=57732cf53f5b9120 input=7e9c47f15a00e809]*/
+{
+#ifdef Py_GIL_DISABLED
+ return _PyEval_IsGILEnabled(_PyThreadState_GET());
+#else
+ return 1;
#endif
+}
+
static PerfMapState perf_map_state;
@@ -2335,7 +2568,7 @@ PyAPI_FUNC(int) PyUnstable_WritePerfMapEntry(
#ifndef MS_WINDOWS
if (perf_map_state.perf_map == NULL) {
int ret = PyUnstable_PerfMapState_Init();
- if(ret != 0){
+ if (ret != 0){
return ret;
}
}
@@ -2362,9 +2595,51 @@ PyAPI_FUNC(void) PyUnstable_PerfMapState_Fini(void) {
#endif
}
-#ifdef __cplusplus
-}
+PyAPI_FUNC(int) PyUnstable_CopyPerfMapFile(const char* parent_filename) {
+#ifndef MS_WINDOWS
+ FILE* from = fopen(parent_filename, "r");
+ if (!from) {
+ return -1;
+ }
+ if (perf_map_state.perf_map == NULL) {
+ int ret = PyUnstable_PerfMapState_Init();
+ if (ret != 0) {
+ return ret;
+ }
+ }
+ char buf[4096];
+ PyThread_acquire_lock(perf_map_state.map_lock, 1);
+ int result = 0;
+ while (1) {
+ size_t bytes_read = fread(buf, 1, sizeof(buf), from);
+ if (bytes_read == 0) {
+ if (ferror(from)) {
+ result = -1;
+ }
+ break;
+ }
+
+ size_t bytes_written = fwrite(buf, 1, bytes_read, perf_map_state.perf_map);
+ if (bytes_written < bytes_read) {
+ result = -1;
+ break;
+ }
+
+ if (fflush(perf_map_state.perf_map) != 0) {
+ result = -1;
+ break;
+ }
+
+ if (bytes_read < sizeof(buf) && feof(from)) {
+ break;
+ }
+ }
+ fclose(from);
+ PyThread_release_lock(perf_map_state.map_lock);
+ return result;
#endif
+ return 0;
+}
static PyMethodDef sys_methods[] = {
@@ -2373,6 +2648,7 @@ static PyMethodDef sys_methods[] = {
{"audit", _PyCFunction_CAST(sys_audit), METH_FASTCALL, audit_doc },
{"breakpointhook", _PyCFunction_CAST(sys_breakpointhook),
METH_FASTCALL | METH_KEYWORDS, breakpointhook_doc},
+ SYS__CLEAR_INTERNAL_CACHES_METHODDEF
SYS__CLEAR_TYPE_CACHE_METHODDEF
SYS__CURRENT_FRAMES_METHODDEF
SYS__CURRENT_EXCEPTIONS_METHODDEF
@@ -2400,16 +2676,17 @@ static PyMethodDef sys_methods[] = {
SYS_GETWINDOWSVERSION_METHODDEF
SYS__ENABLELEGACYWINDOWSFSENCODING_METHODDEF
SYS_INTERN_METHODDEF
+ SYS__IS_INTERNED_METHODDEF
SYS_IS_FINALIZING_METHODDEF
SYS_MDEBUG_METHODDEF
SYS_SETSWITCHINTERVAL_METHODDEF
SYS_GETSWITCHINTERVAL_METHODDEF
SYS_SETDLOPENFLAGS_METHODDEF
- {"setprofile", sys_setprofile, METH_O, setprofile_doc},
+ SYS_SETPROFILE_METHODDEF
SYS__SETPROFILEALLTHREADS_METHODDEF
SYS_GETPROFILE_METHODDEF
SYS_SETRECURSIONLIMIT_METHODDEF
- {"settrace", sys_settrace, METH_O, settrace_doc},
+ SYS_SETTRACE_METHODDEF
SYS__SETTRACEALLTHREADS_METHODDEF
SYS_GETTRACE_METHODDEF
SYS_CALL_TRACING_METHODDEF
@@ -2426,12 +2703,15 @@ static PyMethodDef sys_methods[] = {
SYS_UNRAISABLEHOOK_METHODDEF
SYS_GET_INT_MAX_STR_DIGITS_METHODDEF
SYS_SET_INT_MAX_STR_DIGITS_METHODDEF
+ SYS__BASEREPL_METHODDEF
#ifdef Py_STATS
SYS__STATS_ON_METHODDEF
SYS__STATS_OFF_METHODDEF
SYS__STATS_CLEAR_METHODDEF
SYS__STATS_DUMP_METHODDEF
#endif
+ SYS__GET_CPU_COUNT_CONFIG_METHODDEF
+ SYS__IS_GIL_ENABLED_METHODDEF
{NULL, NULL} // sentinel
};
@@ -2610,7 +2890,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
@@ -2622,6 +2905,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;
@@ -2630,7 +2914,6 @@ get_warnoptions(PyThreadState *tstate)
Py_DECREF(warnoptions);
return NULL;
}
- Py_DECREF(warnoptions);
}
return warnoptions;
}
@@ -2644,10 +2927,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
@@ -2659,12 +2947,15 @@ _PySys_AddWarnOptionWithError(PyThreadState *tstate, PyObject *option)
return -1;
}
if (PyList_Append(warnoptions, option)) {
+ Py_DECREF(warnoptions);
return -1;
}
+ Py_DECREF(warnoptions);
return 0;
}
-void
+// Removed in Python 3.13 API, but kept for the stable ABI
+PyAPI_FUNC(void)
PySys_AddWarnOptionUnicode(PyObject *option)
{
PyThreadState *tstate = _PyThreadState_GET();
@@ -2676,7 +2967,8 @@ PySys_AddWarnOptionUnicode(PyObject *option)
}
}
-void
+// Removed in Python 3.13 API, but kept for the stable ABI
+PyAPI_FUNC(void)
PySys_AddWarnOption(const wchar_t *s)
{
PyThreadState *tstate = _PyThreadState_GET();
@@ -2695,19 +2987,28 @@ _Py_COMP_DIAG_POP
Py_DECREF(unicode);
}
-int
+// Removed in Python 3.13 API, but kept for the stable ABI
+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
@@ -2719,6 +3020,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;
@@ -2727,7 +3029,6 @@ get_xoptions(PyThreadState *tstate)
Py_DECREF(xoptions);
return NULL;
}
- Py_DECREF(xoptions);
}
return xoptions;
}
@@ -2766,15 +3067,18 @@ _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;
}
-void
+// Removed in Python 3.13 API, but kept for the stable ABI
+PyAPI_FUNC(void)
PySys_AddXOption(const wchar_t *s)
{
PyThreadState *tstate = _PyThreadState_GET();
@@ -2792,7 +3096,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.
@@ -2924,6 +3230,7 @@ static PyStructSequence_Field flags_fields[] = {
{"warn_default_encoding", "-X warn_default_encoding"},
{"safe_path", "-P"},
{"int_max_str_digits", "-X int_max_str_digits"},
+ {"gil", "-X gil"},
{0}
};
@@ -2973,6 +3280,16 @@ set_flags_from_config(PyInterpreterState *interp, PyObject *flags)
SetFlag(config->warn_default_encoding);
SetFlagObj(PyBool_FromLong(config->safe_path));
SetFlag(config->int_max_str_digits);
+#ifdef Py_GIL_DISABLED
+ if (config->enable_gil == _PyConfig_GIL_DEFAULT) {
+ SetFlagObj(Py_NewRef(Py_None));
+ }
+ else {
+ SetFlag(config->enable_gil);
+ }
+#else
+ SetFlagObj(PyLong_FromLong(1));
+#endif
#undef SetFlagObj
#undef SetFlag
return 0;
@@ -3517,16 +3834,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));
@@ -3589,6 +3905,9 @@ _PySys_Create(PyThreadState *tstate, PyObject **sysmod_p)
if (sysmod == NULL) {
return _PyStatus_ERR("failed to create a module object");
}
+#ifdef Py_GIL_DISABLED
+ PyUnstable_Module_SetGIL(sysmod, Py_MOD_GIL_NOT_USED);
+#endif
PyObject *sysdict = PyModule_GetDict(sysmod);
if (sysdict == NULL) {
@@ -3615,7 +3934,7 @@ _PySys_Create(PyThreadState *tstate, PyObject **sysmod_p)
return status;
}
- if (_PyImport_FixupBuiltin(sysmod, "sys", modules) < 0) {
+ if (_PyImport_FixupBuiltin(tstate, sysmod, "sys", modules) < 0) {
goto error;
}
@@ -3690,7 +4009,8 @@ makepathobject(const wchar_t *path, wchar_t delim)
return v;
}
-void
+// Removed in Python 3.13 API, but kept for the stable ABI
+PyAPI_FUNC(void)
PySys_SetPath(const wchar_t *path)
{
PyObject *v;
@@ -3754,12 +4074,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);
}
@@ -3784,7 +4107,7 @@ sys_pyfile_write_unicode(PyObject *unicode, PyObject *file)
if (file == NULL)
return -1;
assert(unicode != NULL);
- PyObject *result = _PyObject_CallMethodOneArg(file, &_Py_ID(write), unicode);
+ PyObject *result = PyObject_CallMethodOneArg(file, &_Py_ID(write), unicode);
if (result == NULL) {
return -1;
}
@@ -3847,8 +4170,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);
@@ -3858,6 +4181,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);
}
@@ -3889,15 +4213,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);