1
2 /* System module */
3
4 /*
5 Various bits of information used by the interpreter are collected in
6 module 'sys'.
7 Function member:
8 - exit(sts): raise SystemExit
9 Data members:
10 - stdin, stdout, stderr: standard file objects
11 - modules: the table of modules (dictionary)
12 - path: module search path (list of strings)
13 - argv: script arguments (list of strings)
14 - ps1, ps2: optional primary and secondary prompts (strings)
15 */
16
17 #include "Python.h"
18 #include "pycore_call.h" // _PyObject_CallNoArgs()
19 #include "pycore_ceval.h" // _PyEval_SetAsyncGenFinalizer()
20 #include "pycore_dict.h" // _PyDict_GetItemWithError()
21 #include "pycore_frame.h" // _PyInterpreterFrame
22 #include "pycore_initconfig.h" // _PyStatus_EXCEPTION()
23 #include "pycore_long.h" // _PY_LONG_MAX_STR_DIGITS_THRESHOLD
24 #include "pycore_modsupport.h" // _PyModule_CreateInitialized()
25 #include "pycore_namespace.h" // _PyNamespace_New()
26 #include "pycore_object.h" // _PyObject_DebugTypeStats()
27 #include "pycore_pathconfig.h" // _PyPathConfig_ComputeSysPath0()
28 #include "pycore_pyerrors.h" // _PyErr_GetRaisedException()
29 #include "pycore_pylifecycle.h" // _PyErr_WriteUnraisableDefaultHook()
30 #include "pycore_pymath.h" // _PY_SHORT_FLOAT_REPR
31 #include "pycore_pymem.h" // _PyMem_SetDefaultAllocator()
32 #include "pycore_pystate.h" // _PyThreadState_GET()
33 #include "pycore_pystats.h" // _Py_PrintSpecializationStats()
34 #include "pycore_structseq.h" // _PyStructSequence_InitBuiltinWithFlags()
35 #include "pycore_sysmodule.h" // export _PySys_GetSizeOf()
36 #include "pycore_tuple.h" // _PyTuple_FromArray()
37
38 #include "pydtrace.h" // PyDTrace_AUDIT()
39 #include "osdefs.h" // DELIM
40 #include "stdlib_module_names.h" // _Py_stdlib_module_names
41
42 #ifdef HAVE_UNISTD_H
43 # include <unistd.h> // getpid()
44 #endif
45
46 #ifdef MS_WINDOWS
47 # define WIN32_LEAN_AND_MEAN
48 # include <windows.h>
49 #endif /* MS_WINDOWS */
50
51 #ifdef MS_COREDLL
52 extern void *PyWin_DLLhModule;
53 /* A string loaded from the DLL at startup: */
54 extern const char *PyWin_DLLVersionString;
55 #endif
56
57 #ifdef __EMSCRIPTEN__
58 # include <emscripten.h>
59 #endif
60
61 #ifdef HAVE_FCNTL_H
62 # include <fcntl.h>
63 #endif
64
65 /*[clinic input]
66 module sys
67 [clinic start generated code]*/
68 /*[clinic end generated code: output=da39a3ee5e6b4b0d input=3726b388feee8cea]*/
69
70 #include "clinic/sysmodule.c.h"
71
72
73 PyObject *
_PySys_GetAttr(PyThreadState * tstate,PyObject * name)74 _PySys_GetAttr(PyThreadState *tstate, PyObject *name)
75 {
76 PyObject *sd = tstate->interp->sysdict;
77 if (sd == NULL) {
78 return NULL;
79 }
80 PyObject *exc = _PyErr_GetRaisedException(tstate);
81 /* XXX Suppress a new exception if it was raised and restore
82 * the old one. */
83 PyObject *value = _PyDict_GetItemWithError(sd, name);
84 _PyErr_SetRaisedException(tstate, exc);
85 return value;
86 }
87
88 static PyObject *
_PySys_GetObject(PyInterpreterState * interp,const char * name)89 _PySys_GetObject(PyInterpreterState *interp, const char *name)
90 {
91 PyObject *sysdict = interp->sysdict;
92 if (sysdict == NULL) {
93 return NULL;
94 }
95 PyObject *value;
96 if (PyDict_GetItemStringRef(sysdict, name, &value) != 1) {
97 return NULL;
98 }
99 Py_DECREF(value); // return a borrowed reference
100 return value;
101 }
102
103 PyObject *
PySys_GetObject(const char * name)104 PySys_GetObject(const char *name)
105 {
106 PyThreadState *tstate = _PyThreadState_GET();
107
108 PyObject *exc = _PyErr_GetRaisedException(tstate);
109 PyObject *value = _PySys_GetObject(tstate->interp, name);
110 /* XXX Suppress a new exception if it was raised and restore
111 * the old one. */
112 if (_PyErr_Occurred(tstate)) {
113 PyErr_FormatUnraisable("Exception ignored in PySys_GetObject()");
114 }
115 _PyErr_SetRaisedException(tstate, exc);
116 return value;
117 }
118
119 static int
sys_set_object(PyInterpreterState * interp,PyObject * key,PyObject * v)120 sys_set_object(PyInterpreterState *interp, PyObject *key, PyObject *v)
121 {
122 if (key == NULL) {
123 return -1;
124 }
125 PyObject *sd = interp->sysdict;
126 if (v == NULL) {
127 if (PyDict_Pop(sd, key, NULL) < 0) {
128 return -1;
129 }
130 return 0;
131 }
132 else {
133 return PyDict_SetItem(sd, key, v);
134 }
135 }
136
137 int
_PySys_SetAttr(PyObject * key,PyObject * v)138 _PySys_SetAttr(PyObject *key, PyObject *v)
139 {
140 PyInterpreterState *interp = _PyInterpreterState_GET();
141 return sys_set_object(interp, key, v);
142 }
143
144 static int
sys_set_object_str(PyInterpreterState * interp,const char * name,PyObject * v)145 sys_set_object_str(PyInterpreterState *interp, const char *name, PyObject *v)
146 {
147 PyObject *key = v ? PyUnicode_InternFromString(name)
148 : PyUnicode_FromString(name);
149 int r = sys_set_object(interp, key, v);
150 Py_XDECREF(key);
151 return r;
152 }
153
154 int
PySys_SetObject(const char * name,PyObject * v)155 PySys_SetObject(const char *name, PyObject *v)
156 {
157 PyInterpreterState *interp = _PyInterpreterState_GET();
158 return sys_set_object_str(interp, name, v);
159 }
160
161 int
_PySys_ClearAttrString(PyInterpreterState * interp,const char * name,int verbose)162 _PySys_ClearAttrString(PyInterpreterState *interp,
163 const char *name, int verbose)
164 {
165 if (verbose) {
166 PySys_WriteStderr("# clear sys.%s\n", name);
167 }
168 /* To play it safe, we set the attr to None instead of deleting it. */
169 if (PyDict_SetItemString(interp->sysdict, name, Py_None) < 0) {
170 return -1;
171 }
172 return 0;
173 }
174
175
176 static int
should_audit(PyInterpreterState * interp)177 should_audit(PyInterpreterState *interp)
178 {
179 /* interp must not be NULL, but test it just in case for extra safety */
180 assert(interp != NULL);
181 if (!interp) {
182 return 0;
183 }
184 return (interp->runtime->audit_hooks.head
185 || interp->audit_hooks
186 || PyDTrace_AUDIT_ENABLED());
187 }
188
189
190 static int
sys_audit_tstate(PyThreadState * ts,const char * event,const char * argFormat,va_list vargs)191 sys_audit_tstate(PyThreadState *ts, const char *event,
192 const char *argFormat, va_list vargs)
193 {
194 assert(event != NULL);
195 assert(!argFormat || !strchr(argFormat, 'N'));
196
197 if (!ts) {
198 /* Audit hooks cannot be called with a NULL thread state */
199 return 0;
200 }
201
202 /* The current implementation cannot be called if tstate is not
203 the current Python thread state. */
204 assert(ts == _PyThreadState_GET());
205
206 /* Early exit when no hooks are registered */
207 PyInterpreterState *is = ts->interp;
208 if (!should_audit(is)) {
209 return 0;
210 }
211
212 PyObject *eventName = NULL;
213 PyObject *eventArgs = NULL;
214 PyObject *hooks = NULL;
215 PyObject *hook = NULL;
216 int res = -1;
217
218 int dtrace = PyDTrace_AUDIT_ENABLED();
219
220
221 PyObject *exc = _PyErr_GetRaisedException(ts);
222
223 /* Initialize event args now */
224 if (argFormat && argFormat[0]) {
225 eventArgs = Py_VaBuildValue(argFormat, vargs);
226 if (eventArgs && !PyTuple_Check(eventArgs)) {
227 PyObject *argTuple = PyTuple_Pack(1, eventArgs);
228 Py_SETREF(eventArgs, argTuple);
229 }
230 }
231 else {
232 eventArgs = PyTuple_New(0);
233 }
234 if (!eventArgs) {
235 goto exit;
236 }
237
238 /* Call global hooks
239 *
240 * We don't worry about any races on hooks getting added,
241 * since that would not leave is in an inconsistent state. */
242 _Py_AuditHookEntry *e = is->runtime->audit_hooks.head;
243 for (; e; e = e->next) {
244 if (e->hookCFunction(event, eventArgs, e->userData) < 0) {
245 goto exit;
246 }
247 }
248
249 /* Dtrace USDT point */
250 if (dtrace) {
251 PyDTrace_AUDIT(event, (void *)eventArgs);
252 }
253
254 /* Call interpreter hooks */
255 if (is->audit_hooks) {
256 eventName = PyUnicode_FromString(event);
257 if (!eventName) {
258 goto exit;
259 }
260
261 hooks = PyObject_GetIter(is->audit_hooks);
262 if (!hooks) {
263 goto exit;
264 }
265
266 /* Disallow tracing in hooks unless explicitly enabled */
267 PyThreadState_EnterTracing(ts);
268 while ((hook = PyIter_Next(hooks)) != NULL) {
269 PyObject *o;
270 int canTrace = PyObject_GetOptionalAttr(hook, &_Py_ID(__cantrace__), &o);
271 if (o) {
272 canTrace = PyObject_IsTrue(o);
273 Py_DECREF(o);
274 }
275 if (canTrace < 0) {
276 break;
277 }
278 if (canTrace) {
279 PyThreadState_LeaveTracing(ts);
280 }
281 PyObject* args[2] = {eventName, eventArgs};
282 o = _PyObject_VectorcallTstate(ts, hook, args, 2, NULL);
283 if (canTrace) {
284 PyThreadState_EnterTracing(ts);
285 }
286 if (!o) {
287 break;
288 }
289 Py_DECREF(o);
290 Py_CLEAR(hook);
291 }
292 PyThreadState_LeaveTracing(ts);
293 if (_PyErr_Occurred(ts)) {
294 goto exit;
295 }
296 }
297
298 res = 0;
299
300 exit:
301 Py_XDECREF(hook);
302 Py_XDECREF(hooks);
303 Py_XDECREF(eventName);
304 Py_XDECREF(eventArgs);
305
306 if (!res) {
307 _PyErr_SetRaisedException(ts, exc);
308 }
309 else {
310 assert(_PyErr_Occurred(ts));
311 Py_XDECREF(exc);
312 }
313
314 return res;
315 }
316
317 int
_PySys_Audit(PyThreadState * tstate,const char * event,const char * argFormat,...)318 _PySys_Audit(PyThreadState *tstate, const char *event,
319 const char *argFormat, ...)
320 {
321 va_list vargs;
322 va_start(vargs, argFormat);
323 int res = sys_audit_tstate(tstate, event, argFormat, vargs);
324 va_end(vargs);
325 return res;
326 }
327
328 int
PySys_Audit(const char * event,const char * argFormat,...)329 PySys_Audit(const char *event, const char *argFormat, ...)
330 {
331 PyThreadState *tstate = _PyThreadState_GET();
332 va_list vargs;
333 va_start(vargs, argFormat);
334 int res = sys_audit_tstate(tstate, event, argFormat, vargs);
335 va_end(vargs);
336 return res;
337 }
338
339 int
PySys_AuditTuple(const char * event,PyObject * args)340 PySys_AuditTuple(const char *event, PyObject *args)
341 {
342 if (args == NULL) {
343 return PySys_Audit(event, NULL);
344 }
345
346 if (!PyTuple_Check(args)) {
347 PyErr_Format(PyExc_TypeError, "args must be tuple, got %s",
348 Py_TYPE(args)->tp_name);
349 return -1;
350 }
351 return PySys_Audit(event, "O", args);
352 }
353
354 /* We expose this function primarily for our own cleanup during
355 * finalization. In general, it should not need to be called,
356 * and as such the function is not exported.
357 *
358 * Must be finalizing to clear hooks */
359 void
_PySys_ClearAuditHooks(PyThreadState * ts)360 _PySys_ClearAuditHooks(PyThreadState *ts)
361 {
362 assert(ts != NULL);
363 if (!ts) {
364 return;
365 }
366
367 _PyRuntimeState *runtime = ts->interp->runtime;
368 /* The hooks are global so we have to check for runtime finalization. */
369 PyThreadState *finalizing = _PyRuntimeState_GetFinalizing(runtime);
370 assert(finalizing == ts);
371 if (finalizing != ts) {
372 return;
373 }
374
375 const PyConfig *config = _PyInterpreterState_GetConfig(ts->interp);
376 if (config->verbose) {
377 PySys_WriteStderr("# clear sys.audit hooks\n");
378 }
379
380 /* Hooks can abort later hooks for this event, but cannot
381 abort the clear operation itself. */
382 _PySys_Audit(ts, "cpython._PySys_ClearAuditHooks", NULL);
383 _PyErr_Clear(ts);
384
385 /* We don't worry about the very unlikely race right here,
386 * since it's entirely benign. Nothing else removes entries
387 * from the list and adding an entry right now would not cause
388 * any trouble. */
389 _Py_AuditHookEntry *e = runtime->audit_hooks.head, *n;
390 runtime->audit_hooks.head = NULL;
391 while (e) {
392 n = e->next;
393 PyMem_RawFree(e);
394 e = n;
395 }
396 }
397
398 static void
add_audit_hook_entry_unlocked(_PyRuntimeState * runtime,_Py_AuditHookEntry * entry)399 add_audit_hook_entry_unlocked(_PyRuntimeState *runtime,
400 _Py_AuditHookEntry *entry)
401 {
402 if (runtime->audit_hooks.head == NULL) {
403 runtime->audit_hooks.head = entry;
404 }
405 else {
406 _Py_AuditHookEntry *last = runtime->audit_hooks.head;
407 while (last->next) {
408 last = last->next;
409 }
410 last->next = entry;
411 }
412 }
413
414 int
PySys_AddAuditHook(Py_AuditHookFunction hook,void * userData)415 PySys_AddAuditHook(Py_AuditHookFunction hook, void *userData)
416 {
417 /* tstate can be NULL, so access directly _PyRuntime:
418 PySys_AddAuditHook() can be called before Python is initialized. */
419 _PyRuntimeState *runtime = &_PyRuntime;
420 PyThreadState *tstate;
421 if (runtime->initialized) {
422 tstate = _PyThreadState_GET();
423 }
424 else {
425 tstate = NULL;
426 }
427
428 /* Invoke existing audit hooks to allow them an opportunity to abort. */
429 /* Cannot invoke hooks until we are initialized */
430 if (tstate != NULL) {
431 if (_PySys_Audit(tstate, "sys.addaudithook", NULL) < 0) {
432 if (_PyErr_ExceptionMatches(tstate, PyExc_RuntimeError)) {
433 /* We do not report errors derived from RuntimeError */
434 _PyErr_Clear(tstate);
435 return 0;
436 }
437 return -1;
438 }
439 }
440
441 _Py_AuditHookEntry *e = (_Py_AuditHookEntry*)PyMem_RawMalloc(
442 sizeof(_Py_AuditHookEntry));
443 if (!e) {
444 if (tstate != NULL) {
445 _PyErr_NoMemory(tstate);
446 }
447 return -1;
448 }
449 e->next = NULL;
450 e->hookCFunction = (Py_AuditHookFunction)hook;
451 e->userData = userData;
452
453 PyMutex_Lock(&runtime->audit_hooks.mutex);
454 add_audit_hook_entry_unlocked(runtime, e);
455 PyMutex_Unlock(&runtime->audit_hooks.mutex);
456
457 return 0;
458 }
459
460 /*[clinic input]
461 sys.addaudithook
462
463 hook: object
464
465 Adds a new audit hook callback.
466 [clinic start generated code]*/
467
468 static PyObject *
sys_addaudithook_impl(PyObject * module,PyObject * hook)469 sys_addaudithook_impl(PyObject *module, PyObject *hook)
470 /*[clinic end generated code: output=4f9c17aaeb02f44e input=0f3e191217a45e34]*/
471 {
472 PyThreadState *tstate = _PyThreadState_GET();
473
474 /* Invoke existing audit hooks to allow them an opportunity to abort. */
475 if (_PySys_Audit(tstate, "sys.addaudithook", NULL) < 0) {
476 if (_PyErr_ExceptionMatches(tstate, PyExc_Exception)) {
477 /* We do not report errors derived from Exception */
478 _PyErr_Clear(tstate);
479 Py_RETURN_NONE;
480 }
481 return NULL;
482 }
483
484 PyInterpreterState *interp = tstate->interp;
485 if (interp->audit_hooks == NULL) {
486 interp->audit_hooks = PyList_New(0);
487 if (interp->audit_hooks == NULL) {
488 return NULL;
489 }
490 /* Avoid having our list of hooks show up in the GC module */
491 PyObject_GC_UnTrack(interp->audit_hooks);
492 }
493
494 if (PyList_Append(interp->audit_hooks, hook) < 0) {
495 return NULL;
496 }
497
498 Py_RETURN_NONE;
499 }
500
501 PyDoc_STRVAR(audit_doc,
502 "audit($module, event, /, *args)\n\
503 --\n\
504 \n\
505 Passes the event to any audit hooks that are attached.");
506
507 static PyObject *
sys_audit(PyObject * self,PyObject * const * args,Py_ssize_t argc)508 sys_audit(PyObject *self, PyObject *const *args, Py_ssize_t argc)
509 {
510 PyThreadState *tstate = _PyThreadState_GET();
511 _Py_EnsureTstateNotNULL(tstate);
512
513 if (argc == 0) {
514 _PyErr_SetString(tstate, PyExc_TypeError,
515 "audit() missing 1 required positional argument: "
516 "'event'");
517 return NULL;
518 }
519
520 assert(args[0] != NULL);
521
522 if (!should_audit(tstate->interp)) {
523 Py_RETURN_NONE;
524 }
525
526 PyObject *auditEvent = args[0];
527 if (!auditEvent) {
528 _PyErr_SetString(tstate, PyExc_TypeError,
529 "expected str for argument 'event'");
530 return NULL;
531 }
532 if (!PyUnicode_Check(auditEvent)) {
533 _PyErr_Format(tstate, PyExc_TypeError,
534 "expected str for argument 'event', not %.200s",
535 Py_TYPE(auditEvent)->tp_name);
536 return NULL;
537 }
538 const char *event = PyUnicode_AsUTF8(auditEvent);
539 if (!event) {
540 return NULL;
541 }
542
543 PyObject *auditArgs = _PyTuple_FromArray(args + 1, argc - 1);
544 if (!auditArgs) {
545 return NULL;
546 }
547
548 int res = _PySys_Audit(tstate, event, "O", auditArgs);
549 Py_DECREF(auditArgs);
550
551 if (res < 0) {
552 return NULL;
553 }
554
555 Py_RETURN_NONE;
556 }
557
558
559 static PyObject *
sys_breakpointhook(PyObject * self,PyObject * const * args,Py_ssize_t nargs,PyObject * keywords)560 sys_breakpointhook(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *keywords)
561 {
562 PyThreadState *tstate = _PyThreadState_GET();
563 assert(!_PyErr_Occurred(tstate));
564 char *envar = Py_GETENV("PYTHONBREAKPOINT");
565
566 if (envar == NULL || strlen(envar) == 0) {
567 envar = "pdb.set_trace";
568 }
569 else if (!strcmp(envar, "0")) {
570 /* The breakpoint is explicitly no-op'd. */
571 Py_RETURN_NONE;
572 }
573 /* According to POSIX the string returned by getenv() might be invalidated
574 * or the string content might be overwritten by a subsequent call to
575 * getenv(). Since importing a module can performs the getenv() calls,
576 * we need to save a copy of envar. */
577 envar = _PyMem_RawStrdup(envar);
578 if (envar == NULL) {
579 _PyErr_NoMemory(tstate);
580 return NULL;
581 }
582 const char *last_dot = strrchr(envar, '.');
583 const char *attrname = NULL;
584 PyObject *modulepath = NULL;
585
586 if (last_dot == NULL) {
587 /* The breakpoint is a built-in, e.g. PYTHONBREAKPOINT=int */
588 modulepath = PyUnicode_FromString("builtins");
589 attrname = envar;
590 }
591 else if (last_dot != envar) {
592 /* Split on the last dot; */
593 modulepath = PyUnicode_FromStringAndSize(envar, last_dot - envar);
594 attrname = last_dot + 1;
595 }
596 else {
597 goto warn;
598 }
599 if (modulepath == NULL) {
600 PyMem_RawFree(envar);
601 return NULL;
602 }
603
604 PyObject *module = PyImport_Import(modulepath);
605 Py_DECREF(modulepath);
606
607 if (module == NULL) {
608 if (_PyErr_ExceptionMatches(tstate, PyExc_ImportError)) {
609 goto warn;
610 }
611 PyMem_RawFree(envar);
612 return NULL;
613 }
614
615 PyObject *hook = PyObject_GetAttrString(module, attrname);
616 Py_DECREF(module);
617
618 if (hook == NULL) {
619 if (_PyErr_ExceptionMatches(tstate, PyExc_AttributeError)) {
620 goto warn;
621 }
622 PyMem_RawFree(envar);
623 return NULL;
624 }
625 PyMem_RawFree(envar);
626 PyObject *retval = PyObject_Vectorcall(hook, args, nargs, keywords);
627 Py_DECREF(hook);
628 return retval;
629
630 warn:
631 /* If any of the imports went wrong, then warn and ignore. */
632 _PyErr_Clear(tstate);
633 int status = PyErr_WarnFormat(
634 PyExc_RuntimeWarning, 0,
635 "Ignoring unimportable $PYTHONBREAKPOINT: \"%s\"", envar);
636 PyMem_RawFree(envar);
637 if (status < 0) {
638 /* Printing the warning raised an exception. */
639 return NULL;
640 }
641 /* The warning was (probably) issued. */
642 Py_RETURN_NONE;
643 }
644
645 PyDoc_STRVAR(breakpointhook_doc,
646 "breakpointhook($module, /, *args, **kwargs)\n"
647 "--\n"
648 "\n"
649 "This hook function is called by built-in breakpoint().\n"
650 );
651
652 /* Write repr(o) to sys.stdout using sys.stdout.encoding and 'backslashreplace'
653 error handler. If sys.stdout has a buffer attribute, use
654 sys.stdout.buffer.write(encoded), otherwise redecode the string and use
655 sys.stdout.write(redecoded).
656
657 Helper function for sys_displayhook(). */
658 static int
sys_displayhook_unencodable(PyObject * outf,PyObject * o)659 sys_displayhook_unencodable(PyObject *outf, PyObject *o)
660 {
661 PyObject *stdout_encoding = NULL;
662 PyObject *encoded, *escaped_str, *repr_str, *buffer, *result;
663 const char *stdout_encoding_str;
664 int ret;
665
666 stdout_encoding = PyObject_GetAttr(outf, &_Py_ID(encoding));
667 if (stdout_encoding == NULL)
668 goto error;
669 stdout_encoding_str = PyUnicode_AsUTF8(stdout_encoding);
670 if (stdout_encoding_str == NULL)
671 goto error;
672
673 repr_str = PyObject_Repr(o);
674 if (repr_str == NULL)
675 goto error;
676 encoded = PyUnicode_AsEncodedString(repr_str,
677 stdout_encoding_str,
678 "backslashreplace");
679 Py_DECREF(repr_str);
680 if (encoded == NULL)
681 goto error;
682
683 if (PyObject_GetOptionalAttr(outf, &_Py_ID(buffer), &buffer) < 0) {
684 Py_DECREF(encoded);
685 goto error;
686 }
687 if (buffer) {
688 result = PyObject_CallMethodOneArg(buffer, &_Py_ID(write), encoded);
689 Py_DECREF(buffer);
690 Py_DECREF(encoded);
691 if (result == NULL)
692 goto error;
693 Py_DECREF(result);
694 }
695 else {
696 escaped_str = PyUnicode_FromEncodedObject(encoded,
697 stdout_encoding_str,
698 "strict");
699 Py_DECREF(encoded);
700 if (PyFile_WriteObject(escaped_str, outf, Py_PRINT_RAW) != 0) {
701 Py_DECREF(escaped_str);
702 goto error;
703 }
704 Py_DECREF(escaped_str);
705 }
706 ret = 0;
707 goto finally;
708
709 error:
710 ret = -1;
711 finally:
712 Py_XDECREF(stdout_encoding);
713 return ret;
714 }
715
716 /*[clinic input]
717 sys.displayhook
718
719 object as o: object
720 /
721
722 Print an object to sys.stdout and also save it in builtins._
723 [clinic start generated code]*/
724
725 static PyObject *
sys_displayhook(PyObject * module,PyObject * o)726 sys_displayhook(PyObject *module, PyObject *o)
727 /*[clinic end generated code: output=347477d006df92ed input=08ba730166d7ef72]*/
728 {
729 PyObject *outf;
730 PyObject *builtins;
731 PyThreadState *tstate = _PyThreadState_GET();
732
733 builtins = PyImport_GetModule(&_Py_ID(builtins));
734 if (builtins == NULL) {
735 if (!_PyErr_Occurred(tstate)) {
736 _PyErr_SetString(tstate, PyExc_RuntimeError,
737 "lost builtins module");
738 }
739 return NULL;
740 }
741 Py_DECREF(builtins);
742
743 /* Print value except if None */
744 /* After printing, also assign to '_' */
745 /* Before, set '_' to None to avoid recursion */
746 if (o == Py_None) {
747 Py_RETURN_NONE;
748 }
749 if (PyObject_SetAttr(builtins, _Py_LATIN1_CHR('_'), Py_None) != 0)
750 return NULL;
751 outf = _PySys_GetAttr(tstate, &_Py_ID(stdout));
752 if (outf == NULL || outf == Py_None) {
753 _PyErr_SetString(tstate, PyExc_RuntimeError, "lost sys.stdout");
754 return NULL;
755 }
756 if (PyFile_WriteObject(o, outf, 0) != 0) {
757 if (_PyErr_ExceptionMatches(tstate, PyExc_UnicodeEncodeError)) {
758 int err;
759 /* repr(o) is not encodable to sys.stdout.encoding with
760 * sys.stdout.errors error handler (which is probably 'strict') */
761 _PyErr_Clear(tstate);
762 err = sys_displayhook_unencodable(outf, o);
763 if (err) {
764 return NULL;
765 }
766 }
767 else {
768 return NULL;
769 }
770 }
771 if (PyFile_WriteObject(_Py_LATIN1_CHR('\n'), outf, Py_PRINT_RAW) != 0)
772 return NULL;
773 if (PyObject_SetAttr(builtins, _Py_LATIN1_CHR('_'), o) != 0)
774 return NULL;
775 Py_RETURN_NONE;
776 }
777
778
779 /*[clinic input]
780 sys.excepthook
781
782 exctype: object
783 value: object
784 traceback: object
785 /
786
787 Handle an exception by displaying it with a traceback on sys.stderr.
788 [clinic start generated code]*/
789
790 static PyObject *
sys_excepthook_impl(PyObject * module,PyObject * exctype,PyObject * value,PyObject * traceback)791 sys_excepthook_impl(PyObject *module, PyObject *exctype, PyObject *value,
792 PyObject *traceback)
793 /*[clinic end generated code: output=18d99fdda21b6b5e input=ecf606fa826f19d9]*/
794 {
795 PyErr_Display(NULL, value, traceback);
796 Py_RETURN_NONE;
797 }
798
799
800 /*[clinic input]
801 sys.exception
802
803 Return the current exception.
804
805 Return the most recent exception caught by an except clause
806 in the current stack frame or in an older stack frame, or None
807 if no such exception exists.
808 [clinic start generated code]*/
809
810 static PyObject *
sys_exception_impl(PyObject * module)811 sys_exception_impl(PyObject *module)
812 /*[clinic end generated code: output=2381ee2f25953e40 input=c88fbb94b6287431]*/
813 {
814 _PyErr_StackItem *err_info = _PyErr_GetTopmostException(_PyThreadState_GET());
815 if (err_info->exc_value != NULL) {
816 return Py_NewRef(err_info->exc_value);
817 }
818 Py_RETURN_NONE;
819 }
820
821
822 /*[clinic input]
823 sys.exc_info
824
825 Return current exception information: (type, value, traceback).
826
827 Return information about the most recent exception caught by an except
828 clause in the current stack frame or in an older stack frame.
829 [clinic start generated code]*/
830
831 static PyObject *
sys_exc_info_impl(PyObject * module)832 sys_exc_info_impl(PyObject *module)
833 /*[clinic end generated code: output=3afd0940cf3a4d30 input=b5c5bf077788a3e5]*/
834 {
835 _PyErr_StackItem *err_info = _PyErr_GetTopmostException(_PyThreadState_GET());
836 return _PyErr_StackItemToExcInfoTuple(err_info);
837 }
838
839
840 /*[clinic input]
841 sys.unraisablehook
842
843 unraisable: object
844 /
845
846 Handle an unraisable exception.
847
848 The unraisable argument has the following attributes:
849
850 * exc_type: Exception type.
851 * exc_value: Exception value, can be None.
852 * exc_traceback: Exception traceback, can be None.
853 * err_msg: Error message, can be None.
854 * object: Object causing the exception, can be None.
855 [clinic start generated code]*/
856
857 static PyObject *
sys_unraisablehook(PyObject * module,PyObject * unraisable)858 sys_unraisablehook(PyObject *module, PyObject *unraisable)
859 /*[clinic end generated code: output=bb92838b32abaa14 input=ec3af148294af8d3]*/
860 {
861 return _PyErr_WriteUnraisableDefaultHook(unraisable);
862 }
863
864
865 /*[clinic input]
866 sys.exit
867
868 status: object = None
869 /
870
871 Exit the interpreter by raising SystemExit(status).
872
873 If the status is omitted or None, it defaults to zero (i.e., success).
874 If the status is an integer, it will be used as the system exit status.
875 If it is another kind of object, it will be printed and the system
876 exit status will be one (i.e., failure).
877 [clinic start generated code]*/
878
879 static PyObject *
sys_exit_impl(PyObject * module,PyObject * status)880 sys_exit_impl(PyObject *module, PyObject *status)
881 /*[clinic end generated code: output=13870986c1ab2ec0 input=b86ca9497baa94f2]*/
882 {
883 /* Raise SystemExit so callers may catch it or clean up. */
884 PyErr_SetObject(PyExc_SystemExit, status);
885 return NULL;
886 }
887
888
889 static PyObject *
get_utf8_unicode(void)890 get_utf8_unicode(void)
891 {
892 _Py_DECLARE_STR(utf_8, "utf-8");
893 PyObject *ret = &_Py_STR(utf_8);
894 return Py_NewRef(ret);
895 }
896
897 /*[clinic input]
898 sys.getdefaultencoding
899
900 Return the current default encoding used by the Unicode implementation.
901 [clinic start generated code]*/
902
903 static PyObject *
sys_getdefaultencoding_impl(PyObject * module)904 sys_getdefaultencoding_impl(PyObject *module)
905 /*[clinic end generated code: output=256d19dfcc0711e6 input=d416856ddbef6909]*/
906 {
907 return get_utf8_unicode();
908 }
909
910 /*[clinic input]
911 sys.getfilesystemencoding
912
913 Return the encoding used to convert Unicode filenames to OS filenames.
914 [clinic start generated code]*/
915
916 static PyObject *
sys_getfilesystemencoding_impl(PyObject * module)917 sys_getfilesystemencoding_impl(PyObject *module)
918 /*[clinic end generated code: output=1dc4bdbe9be44aa7 input=8475f8649b8c7d8c]*/
919 {
920 PyInterpreterState *interp = _PyInterpreterState_GET();
921 const PyConfig *config = _PyInterpreterState_GetConfig(interp);
922
923 if (wcscmp(config->filesystem_encoding, L"utf-8") == 0) {
924 return get_utf8_unicode();
925 }
926
927 PyObject *u = PyUnicode_FromWideChar(config->filesystem_encoding, -1);
928 if (u == NULL) {
929 return NULL;
930 }
931 _PyUnicode_InternImmortal(interp, &u);
932 return u;
933 }
934
935 /*[clinic input]
936 sys.getfilesystemencodeerrors
937
938 Return the error mode used Unicode to OS filename conversion.
939 [clinic start generated code]*/
940
941 static PyObject *
sys_getfilesystemencodeerrors_impl(PyObject * module)942 sys_getfilesystemencodeerrors_impl(PyObject *module)
943 /*[clinic end generated code: output=ba77b36bbf7c96f5 input=22a1e8365566f1e5]*/
944 {
945 PyInterpreterState *interp = _PyInterpreterState_GET();
946 const PyConfig *config = _PyInterpreterState_GetConfig(interp);
947 PyObject *u = PyUnicode_FromWideChar(config->filesystem_errors, -1);
948 if (u == NULL) {
949 return NULL;
950 }
951 _PyUnicode_InternImmortal(interp, &u);
952 return u;
953 }
954
955 /*[clinic input]
956 sys.intern
957
958 string as s: unicode
959 /
960
961 ``Intern'' the given string.
962
963 This enters the string in the (global) table of interned strings whose
964 purpose is to speed up dictionary lookups. Return the string itself or
965 the previously interned string object with the same value.
966 [clinic start generated code]*/
967
968 static PyObject *
sys_intern_impl(PyObject * module,PyObject * s)969 sys_intern_impl(PyObject *module, PyObject *s)
970 /*[clinic end generated code: output=be680c24f5c9e5d6 input=849483c006924e2f]*/
971 {
972 if (PyUnicode_CheckExact(s)) {
973 PyInterpreterState *interp = _PyInterpreterState_GET();
974 Py_INCREF(s);
975 _PyUnicode_InternMortal(interp, &s);
976 return s;
977 }
978 else {
979 PyErr_Format(PyExc_TypeError,
980 "can't intern %.400s", Py_TYPE(s)->tp_name);
981 return NULL;
982 }
983 }
984
985
986 /*[clinic input]
987 sys._is_interned -> bool
988
989 string: unicode
990 /
991
992 Return True if the given string is "interned".
993 [clinic start generated code]*/
994
995 static int
sys__is_interned_impl(PyObject * module,PyObject * string)996 sys__is_interned_impl(PyObject *module, PyObject *string)
997 /*[clinic end generated code: output=c3678267b4e9d7ed input=039843e17883b606]*/
998 {
999 return PyUnicode_CHECK_INTERNED(string);
1000 }
1001
1002
1003 /*
1004 * Cached interned string objects used for calling the profile and
1005 * trace functions.
1006 */
1007 static PyObject *whatstrings[8] = {
1008 &_Py_ID(call),
1009 &_Py_ID(exception),
1010 &_Py_ID(line),
1011 &_Py_ID(return),
1012 &_Py_ID(c_call),
1013 &_Py_ID(c_exception),
1014 &_Py_ID(c_return),
1015 &_Py_ID(opcode),
1016 };
1017
1018
1019 static PyObject *
call_trampoline(PyThreadState * tstate,PyObject * callback,PyFrameObject * frame,int what,PyObject * arg)1020 call_trampoline(PyThreadState *tstate, PyObject* callback,
1021 PyFrameObject *frame, int what, PyObject *arg)
1022 {
1023 /* call the Python-level function */
1024 if (arg == NULL) {
1025 arg = Py_None;
1026 }
1027 PyObject *args[3] = {(PyObject *)frame, whatstrings[what], arg};
1028 PyObject *result = _PyObject_VectorcallTstate(tstate, callback, args, 3, NULL);
1029
1030 return result;
1031 }
1032
1033 static int
profile_trampoline(PyObject * self,PyFrameObject * frame,int what,PyObject * arg)1034 profile_trampoline(PyObject *self, PyFrameObject *frame,
1035 int what, PyObject *arg)
1036 {
1037 PyThreadState *tstate = _PyThreadState_GET();
1038 PyObject *result = call_trampoline(tstate, self, frame, what, arg);
1039 if (result == NULL) {
1040 _PyEval_SetProfile(tstate, NULL, NULL);
1041 return -1;
1042 }
1043
1044 Py_DECREF(result);
1045 return 0;
1046 }
1047
1048 static int
trace_trampoline(PyObject * self,PyFrameObject * frame,int what,PyObject * arg)1049 trace_trampoline(PyObject *self, PyFrameObject *frame,
1050 int what, PyObject *arg)
1051 {
1052 PyObject *callback;
1053 if (what == PyTrace_CALL) {
1054 callback = self;
1055 }
1056 else {
1057 callback = frame->f_trace;
1058 }
1059 if (callback == NULL) {
1060 return 0;
1061 }
1062
1063 PyThreadState *tstate = _PyThreadState_GET();
1064 PyObject *result = call_trampoline(tstate, callback, frame, what, arg);
1065 if (result == NULL) {
1066 _PyEval_SetTrace(tstate, NULL, NULL);
1067 Py_CLEAR(frame->f_trace);
1068 return -1;
1069 }
1070
1071 if (result != Py_None) {
1072 Py_XSETREF(frame->f_trace, result);
1073 }
1074 else {
1075 Py_DECREF(result);
1076 }
1077 return 0;
1078 }
1079
1080 /*[clinic input]
1081 sys.settrace
1082
1083 function: object
1084 /
1085
1086 Set the global debug tracing function.
1087
1088 It will be called on each function call. See the debugger chapter
1089 in the library manual.
1090 [clinic start generated code]*/
1091
1092 static PyObject *
sys_settrace(PyObject * module,PyObject * function)1093 sys_settrace(PyObject *module, PyObject *function)
1094 /*[clinic end generated code: output=999d12e9d6ec4678 input=8107feb01c5f1c4e]*/
1095 {
1096 PyThreadState *tstate = _PyThreadState_GET();
1097 if (function == Py_None) {
1098 if (_PyEval_SetTrace(tstate, NULL, NULL) < 0) {
1099 return NULL;
1100 }
1101 }
1102 else {
1103 if (_PyEval_SetTrace(tstate, trace_trampoline, function) < 0) {
1104 return NULL;
1105 }
1106 }
1107 Py_RETURN_NONE;
1108 }
1109
1110 /*[clinic input]
1111 sys._settraceallthreads
1112
1113 function as arg: object
1114 /
1115
1116 Set the global debug tracing function in all running threads belonging to the current interpreter.
1117
1118 It will be called on each function call. See the debugger chapter
1119 in the library manual.
1120 [clinic start generated code]*/
1121
1122 static PyObject *
sys__settraceallthreads(PyObject * module,PyObject * arg)1123 sys__settraceallthreads(PyObject *module, PyObject *arg)
1124 /*[clinic end generated code: output=161cca30207bf3ca input=d4bde1f810d73675]*/
1125 {
1126 PyObject* argument = NULL;
1127 Py_tracefunc func = NULL;
1128
1129 if (arg != Py_None) {
1130 func = trace_trampoline;
1131 argument = arg;
1132 }
1133
1134
1135 PyEval_SetTraceAllThreads(func, argument);
1136
1137 Py_RETURN_NONE;
1138 }
1139
1140 /*[clinic input]
1141 sys.gettrace
1142
1143 Return the global debug tracing function set with sys.settrace.
1144
1145 See the debugger chapter in the library manual.
1146 [clinic start generated code]*/
1147
1148 static PyObject *
sys_gettrace_impl(PyObject * module)1149 sys_gettrace_impl(PyObject *module)
1150 /*[clinic end generated code: output=e97e3a4d8c971b6e input=373b51bb2147f4d8]*/
1151 {
1152 PyThreadState *tstate = _PyThreadState_GET();
1153 PyObject *temp = tstate->c_traceobj;
1154
1155 if (temp == NULL)
1156 temp = Py_None;
1157 return Py_NewRef(temp);
1158 }
1159
1160 /*[clinic input]
1161 sys.setprofile
1162
1163 function: object
1164 /
1165
1166 Set the profiling function.
1167
1168 It will be called on each function call and return. See the profiler
1169 chapter in the library manual.
1170 [clinic start generated code]*/
1171
1172 static PyObject *
sys_setprofile(PyObject * module,PyObject * function)1173 sys_setprofile(PyObject *module, PyObject *function)
1174 /*[clinic end generated code: output=1c3503105939db9c input=055d0d7961413a62]*/
1175 {
1176 PyThreadState *tstate = _PyThreadState_GET();
1177 if (function == Py_None) {
1178 if (_PyEval_SetProfile(tstate, NULL, NULL) < 0) {
1179 return NULL;
1180 }
1181 }
1182 else {
1183 if (_PyEval_SetProfile(tstate, profile_trampoline, function) < 0) {
1184 return NULL;
1185 }
1186 }
1187 Py_RETURN_NONE;
1188 }
1189
1190 /*[clinic input]
1191 sys._setprofileallthreads
1192
1193 function as arg: object
1194 /
1195
1196 Set the profiling function in all running threads belonging to the current interpreter.
1197
1198 It will be called on each function call and return. See the profiler
1199 chapter in the library manual.
1200 [clinic start generated code]*/
1201
1202 static PyObject *
sys__setprofileallthreads(PyObject * module,PyObject * arg)1203 sys__setprofileallthreads(PyObject *module, PyObject *arg)
1204 /*[clinic end generated code: output=2d61319e27b309fe input=a10589439ba20cee]*/
1205 {
1206 PyObject* argument = NULL;
1207 Py_tracefunc func = NULL;
1208
1209 if (arg != Py_None) {
1210 func = profile_trampoline;
1211 argument = arg;
1212 }
1213
1214 PyEval_SetProfileAllThreads(func, argument);
1215
1216 Py_RETURN_NONE;
1217 }
1218
1219 /*[clinic input]
1220 sys.getprofile
1221
1222 Return the profiling function set with sys.setprofile.
1223
1224 See the profiler chapter in the library manual.
1225 [clinic start generated code]*/
1226
1227 static PyObject *
sys_getprofile_impl(PyObject * module)1228 sys_getprofile_impl(PyObject *module)
1229 /*[clinic end generated code: output=579b96b373448188 input=1b3209d89a32965d]*/
1230 {
1231 PyThreadState *tstate = _PyThreadState_GET();
1232 PyObject *temp = tstate->c_profileobj;
1233
1234 if (temp == NULL)
1235 temp = Py_None;
1236 return Py_NewRef(temp);
1237 }
1238
1239
1240 /*[clinic input]
1241 sys.setswitchinterval
1242
1243 interval: double
1244 /
1245
1246 Set the ideal thread switching delay inside the Python interpreter.
1247
1248 The actual frequency of switching threads can be lower if the
1249 interpreter executes long sequences of uninterruptible code
1250 (this is implementation-specific and workload-dependent).
1251
1252 The parameter must represent the desired switching delay in seconds
1253 A typical value is 0.005 (5 milliseconds).
1254 [clinic start generated code]*/
1255
1256 static PyObject *
sys_setswitchinterval_impl(PyObject * module,double interval)1257 sys_setswitchinterval_impl(PyObject *module, double interval)
1258 /*[clinic end generated code: output=65a19629e5153983 input=561b477134df91d9]*/
1259 {
1260 if (interval <= 0.0) {
1261 PyErr_SetString(PyExc_ValueError,
1262 "switch interval must be strictly positive");
1263 return NULL;
1264 }
1265 _PyEval_SetSwitchInterval((unsigned long) (1e6 * interval));
1266 Py_RETURN_NONE;
1267 }
1268
1269
1270 /*[clinic input]
1271 sys.getswitchinterval -> double
1272
1273 Return the current thread switch interval; see sys.setswitchinterval().
1274 [clinic start generated code]*/
1275
1276 static double
sys_getswitchinterval_impl(PyObject * module)1277 sys_getswitchinterval_impl(PyObject *module)
1278 /*[clinic end generated code: output=a38c277c85b5096d input=bdf9d39c0ebbbb6f]*/
1279 {
1280 return 1e-6 * _PyEval_GetSwitchInterval();
1281 }
1282
1283 /*[clinic input]
1284 sys.setrecursionlimit
1285
1286 limit as new_limit: int
1287 /
1288
1289 Set the maximum depth of the Python interpreter stack to n.
1290
1291 This limit prevents infinite recursion from causing an overflow of the C
1292 stack and crashing Python. The highest possible limit is platform-
1293 dependent.
1294 [clinic start generated code]*/
1295
1296 static PyObject *
sys_setrecursionlimit_impl(PyObject * module,int new_limit)1297 sys_setrecursionlimit_impl(PyObject *module, int new_limit)
1298 /*[clinic end generated code: output=35e1c64754800ace input=b0f7a23393924af3]*/
1299 {
1300 PyThreadState *tstate = _PyThreadState_GET();
1301
1302 if (new_limit < 1) {
1303 _PyErr_SetString(tstate, PyExc_ValueError,
1304 "recursion limit must be greater or equal than 1");
1305 return NULL;
1306 }
1307
1308 /* Reject too low new limit if the current recursion depth is higher than
1309 the new low-water mark. */
1310 int depth = tstate->py_recursion_limit - tstate->py_recursion_remaining;
1311 if (depth >= new_limit) {
1312 _PyErr_Format(tstate, PyExc_RecursionError,
1313 "cannot set the recursion limit to %i at "
1314 "the recursion depth %i: the limit is too low",
1315 new_limit, depth);
1316 return NULL;
1317 }
1318
1319 Py_SetRecursionLimit(new_limit);
1320 Py_RETURN_NONE;
1321 }
1322
1323 /*[clinic input]
1324 sys.set_coroutine_origin_tracking_depth
1325
1326 depth: int
1327
1328 Enable or disable origin tracking for coroutine objects in this thread.
1329
1330 Coroutine objects will track 'depth' frames of traceback information
1331 about where they came from, available in their cr_origin attribute.
1332
1333 Set a depth of 0 to disable.
1334 [clinic start generated code]*/
1335
1336 static PyObject *
sys_set_coroutine_origin_tracking_depth_impl(PyObject * module,int depth)1337 sys_set_coroutine_origin_tracking_depth_impl(PyObject *module, int depth)
1338 /*[clinic end generated code: output=0a2123c1cc6759c5 input=a1d0a05f89d2c426]*/
1339 {
1340 if (_PyEval_SetCoroutineOriginTrackingDepth(depth) < 0) {
1341 return NULL;
1342 }
1343 Py_RETURN_NONE;
1344 }
1345
1346 /*[clinic input]
1347 sys.get_coroutine_origin_tracking_depth -> int
1348
1349 Check status of origin tracking for coroutine objects in this thread.
1350 [clinic start generated code]*/
1351
1352 static int
sys_get_coroutine_origin_tracking_depth_impl(PyObject * module)1353 sys_get_coroutine_origin_tracking_depth_impl(PyObject *module)
1354 /*[clinic end generated code: output=3699f7be95a3afb8 input=335266a71205b61a]*/
1355 {
1356 return _PyEval_GetCoroutineOriginTrackingDepth();
1357 }
1358
1359 static PyTypeObject AsyncGenHooksType;
1360
1361 PyDoc_STRVAR(asyncgen_hooks_doc,
1362 "asyncgen_hooks\n\
1363 \n\
1364 A named tuple providing information about asynchronous\n\
1365 generators hooks. The attributes are read only.");
1366
1367 static PyStructSequence_Field asyncgen_hooks_fields[] = {
1368 {"firstiter", "Hook to intercept first iteration"},
1369 {"finalizer", "Hook to intercept finalization"},
1370 {0}
1371 };
1372
1373 static PyStructSequence_Desc asyncgen_hooks_desc = {
1374 "asyncgen_hooks", /* name */
1375 asyncgen_hooks_doc, /* doc */
1376 asyncgen_hooks_fields , /* fields */
1377 2
1378 };
1379
1380 static PyObject *
sys_set_asyncgen_hooks(PyObject * self,PyObject * args,PyObject * kw)1381 sys_set_asyncgen_hooks(PyObject *self, PyObject *args, PyObject *kw)
1382 {
1383 static char *keywords[] = {"firstiter", "finalizer", NULL};
1384 PyObject *firstiter = NULL;
1385 PyObject *finalizer = NULL;
1386
1387 if (!PyArg_ParseTupleAndKeywords(
1388 args, kw, "|OO", keywords,
1389 &firstiter, &finalizer)) {
1390 return NULL;
1391 }
1392
1393 if (finalizer && finalizer != Py_None) {
1394 if (!PyCallable_Check(finalizer)) {
1395 PyErr_Format(PyExc_TypeError,
1396 "callable finalizer expected, got %.50s",
1397 Py_TYPE(finalizer)->tp_name);
1398 return NULL;
1399 }
1400 }
1401
1402 if (firstiter && firstiter != Py_None) {
1403 if (!PyCallable_Check(firstiter)) {
1404 PyErr_Format(PyExc_TypeError,
1405 "callable firstiter expected, got %.50s",
1406 Py_TYPE(firstiter)->tp_name);
1407 return NULL;
1408 }
1409 }
1410
1411 PyObject *cur_finalizer = _PyEval_GetAsyncGenFinalizer();
1412
1413 if (finalizer && finalizer != Py_None) {
1414 if (_PyEval_SetAsyncGenFinalizer(finalizer) < 0) {
1415 return NULL;
1416 }
1417 }
1418 else if (finalizer == Py_None && _PyEval_SetAsyncGenFinalizer(NULL) < 0) {
1419 return NULL;
1420 }
1421
1422 if (firstiter && firstiter != Py_None) {
1423 if (_PyEval_SetAsyncGenFirstiter(firstiter) < 0) {
1424 goto error;
1425 }
1426 }
1427 else if (firstiter == Py_None && _PyEval_SetAsyncGenFirstiter(NULL) < 0) {
1428 goto error;
1429 }
1430
1431 Py_RETURN_NONE;
1432
1433 error:
1434 _PyEval_SetAsyncGenFinalizer(cur_finalizer);
1435 return NULL;
1436 }
1437
1438 PyDoc_STRVAR(set_asyncgen_hooks_doc,
1439 "set_asyncgen_hooks([firstiter] [, finalizer])\n\
1440 \n\
1441 Set a finalizer for async generators objects."
1442 );
1443
1444 /*[clinic input]
1445 sys.get_asyncgen_hooks
1446
1447 Return the installed asynchronous generators hooks.
1448
1449 This returns a namedtuple of the form (firstiter, finalizer).
1450 [clinic start generated code]*/
1451
1452 static PyObject *
sys_get_asyncgen_hooks_impl(PyObject * module)1453 sys_get_asyncgen_hooks_impl(PyObject *module)
1454 /*[clinic end generated code: output=53a253707146f6cf input=3676b9ea62b14625]*/
1455 {
1456 PyObject *res;
1457 PyObject *firstiter = _PyEval_GetAsyncGenFirstiter();
1458 PyObject *finalizer = _PyEval_GetAsyncGenFinalizer();
1459
1460 res = PyStructSequence_New(&AsyncGenHooksType);
1461 if (res == NULL) {
1462 return NULL;
1463 }
1464
1465 if (firstiter == NULL) {
1466 firstiter = Py_None;
1467 }
1468
1469 if (finalizer == NULL) {
1470 finalizer = Py_None;
1471 }
1472
1473 PyStructSequence_SET_ITEM(res, 0, Py_NewRef(firstiter));
1474 PyStructSequence_SET_ITEM(res, 1, Py_NewRef(finalizer));
1475
1476 return res;
1477 }
1478
1479
1480 static PyTypeObject Hash_InfoType;
1481
1482 PyDoc_STRVAR(hash_info_doc,
1483 "hash_info\n\
1484 \n\
1485 A named tuple providing parameters used for computing\n\
1486 hashes. The attributes are read only.");
1487
1488 static PyStructSequence_Field hash_info_fields[] = {
1489 {"width", "width of the type used for hashing, in bits"},
1490 {"modulus", "prime number giving the modulus on which the hash "
1491 "function is based"},
1492 {"inf", "value to be used for hash of a positive infinity"},
1493 {"nan", "value to be used for hash of a nan"},
1494 {"imag", "multiplier used for the imaginary part of a complex number"},
1495 {"algorithm", "name of the algorithm for hashing of str, bytes and "
1496 "memoryviews"},
1497 {"hash_bits", "internal output size of hash algorithm"},
1498 {"seed_bits", "seed size of hash algorithm"},
1499 {"cutoff", "small string optimization cutoff"},
1500 {NULL, NULL}
1501 };
1502
1503 static PyStructSequence_Desc hash_info_desc = {
1504 "sys.hash_info",
1505 hash_info_doc,
1506 hash_info_fields,
1507 9,
1508 };
1509
1510 static PyObject *
get_hash_info(PyThreadState * tstate)1511 get_hash_info(PyThreadState *tstate)
1512 {
1513 PyObject *hash_info;
1514 int field = 0;
1515 PyHash_FuncDef *hashfunc;
1516 hash_info = PyStructSequence_New(&Hash_InfoType);
1517 if (hash_info == NULL) {
1518 return NULL;
1519 }
1520 hashfunc = PyHash_GetFuncDef();
1521
1522 #define SET_HASH_INFO_ITEM(CALL) \
1523 do { \
1524 PyObject *item = (CALL); \
1525 if (item == NULL) { \
1526 Py_CLEAR(hash_info); \
1527 return NULL; \
1528 } \
1529 PyStructSequence_SET_ITEM(hash_info, field++, item); \
1530 } while(0)
1531
1532 SET_HASH_INFO_ITEM(PyLong_FromLong(8 * sizeof(Py_hash_t)));
1533 SET_HASH_INFO_ITEM(PyLong_FromSsize_t(_PyHASH_MODULUS));
1534 SET_HASH_INFO_ITEM(PyLong_FromLong(_PyHASH_INF));
1535 SET_HASH_INFO_ITEM(PyLong_FromLong(0)); // This is no longer used
1536 SET_HASH_INFO_ITEM(PyLong_FromLong(_PyHASH_IMAG));
1537 SET_HASH_INFO_ITEM(PyUnicode_FromString(hashfunc->name));
1538 SET_HASH_INFO_ITEM(PyLong_FromLong(hashfunc->hash_bits));
1539 SET_HASH_INFO_ITEM(PyLong_FromLong(hashfunc->seed_bits));
1540 SET_HASH_INFO_ITEM(PyLong_FromLong(Py_HASH_CUTOFF));
1541
1542 #undef SET_HASH_INFO_ITEM
1543
1544 return hash_info;
1545 }
1546 /*[clinic input]
1547 sys.getrecursionlimit
1548
1549 Return the current value of the recursion limit.
1550
1551 The recursion limit is the maximum depth of the Python interpreter
1552 stack. This limit prevents infinite recursion from causing an overflow
1553 of the C stack and crashing Python.
1554 [clinic start generated code]*/
1555
1556 static PyObject *
sys_getrecursionlimit_impl(PyObject * module)1557 sys_getrecursionlimit_impl(PyObject *module)
1558 /*[clinic end generated code: output=d571fb6b4549ef2e input=1c6129fd2efaeea8]*/
1559 {
1560 return PyLong_FromLong(Py_GetRecursionLimit());
1561 }
1562
1563 #ifdef MS_WINDOWS
1564
1565 static PyTypeObject WindowsVersionType = {0, 0, 0, 0, 0, 0};
1566
1567 static PyStructSequence_Field windows_version_fields[] = {
1568 {"major", "Major version number"},
1569 {"minor", "Minor version number"},
1570 {"build", "Build number"},
1571 {"platform", "Operating system platform"},
1572 {"service_pack", "Latest Service Pack installed on the system"},
1573 {"service_pack_major", "Service Pack major version number"},
1574 {"service_pack_minor", "Service Pack minor version number"},
1575 {"suite_mask", "Bit mask identifying available product suites"},
1576 {"product_type", "System product type"},
1577 {"platform_version", "Diagnostic version number"},
1578 {0}
1579 };
1580
1581 static PyStructSequence_Desc windows_version_desc = {
1582 "sys.getwindowsversion", /* name */
1583 sys_getwindowsversion__doc__, /* doc */
1584 windows_version_fields, /* fields */
1585 5 /* For backward compatibility,
1586 only the first 5 items are accessible
1587 via indexing, the rest are name only */
1588 };
1589
1590 static PyObject *
_sys_getwindowsversion_from_kernel32(void)1591 _sys_getwindowsversion_from_kernel32(void)
1592 {
1593 #ifndef MS_WINDOWS_DESKTOP
1594 return NULL;
1595 #else
1596 HANDLE hKernel32;
1597 wchar_t kernel32_path[MAX_PATH];
1598 LPVOID verblock;
1599 DWORD verblock_size;
1600 VS_FIXEDFILEINFO *ffi;
1601 UINT ffi_len;
1602 DWORD realMajor, realMinor, realBuild;
1603
1604 Py_BEGIN_ALLOW_THREADS
1605 hKernel32 = GetModuleHandleW(L"kernel32.dll");
1606 Py_END_ALLOW_THREADS
1607 if (!hKernel32 || !GetModuleFileNameW(hKernel32, kernel32_path, MAX_PATH)) {
1608 PyErr_SetFromWindowsErr(0);
1609 return NULL;
1610 }
1611 verblock_size = GetFileVersionInfoSizeW(kernel32_path, NULL);
1612 if (!verblock_size) {
1613 PyErr_SetFromWindowsErr(0);
1614 return NULL;
1615 }
1616 verblock = PyMem_RawMalloc(verblock_size);
1617 if (!verblock ||
1618 !GetFileVersionInfoW(kernel32_path, 0, verblock_size, verblock) ||
1619 !VerQueryValueW(verblock, L"", (LPVOID)&ffi, &ffi_len)) {
1620 PyErr_SetFromWindowsErr(0);
1621 return NULL;
1622 }
1623
1624 realMajor = HIWORD(ffi->dwProductVersionMS);
1625 realMinor = LOWORD(ffi->dwProductVersionMS);
1626 realBuild = HIWORD(ffi->dwProductVersionLS);
1627 PyMem_RawFree(verblock);
1628 return Py_BuildValue("(kkk)", realMajor, realMinor, realBuild);
1629 #endif /* !MS_WINDOWS_DESKTOP */
1630 }
1631
1632 /* Disable deprecation warnings about GetVersionEx as the result is
1633 being passed straight through to the caller, who is responsible for
1634 using it correctly. */
1635 #pragma warning(push)
1636 #pragma warning(disable:4996)
1637
1638 /*[clinic input]
1639 sys.getwindowsversion
1640
1641 Return info about the running version of Windows as a named tuple.
1642
1643 The members are named: major, minor, build, platform, service_pack,
1644 service_pack_major, service_pack_minor, suite_mask, product_type and
1645 platform_version. For backward compatibility, only the first 5 items
1646 are available by indexing. All elements are numbers, except
1647 service_pack and platform_type which are strings, and platform_version
1648 which is a 3-tuple. Platform is always 2. Product_type may be 1 for a
1649 workstation, 2 for a domain controller, 3 for a server.
1650 Platform_version is a 3-tuple containing a version number that is
1651 intended for identifying the OS rather than feature detection.
1652 [clinic start generated code]*/
1653
1654 static PyObject *
sys_getwindowsversion_impl(PyObject * module)1655 sys_getwindowsversion_impl(PyObject *module)
1656 /*[clinic end generated code: output=1ec063280b932857 input=73a228a328fee63a]*/
1657 {
1658 PyObject *version;
1659 int pos = 0;
1660 OSVERSIONINFOEXW ver;
1661
1662 if (PyObject_GetOptionalAttrString(module, "_cached_windows_version", &version) < 0) {
1663 return NULL;
1664 };
1665 if (version && PyObject_TypeCheck(version, &WindowsVersionType)) {
1666 return version;
1667 }
1668 Py_XDECREF(version);
1669
1670 ver.dwOSVersionInfoSize = sizeof(ver);
1671 if (!GetVersionExW((OSVERSIONINFOW*) &ver))
1672 return PyErr_SetFromWindowsErr(0);
1673
1674 version = PyStructSequence_New(&WindowsVersionType);
1675 if (version == NULL)
1676 return NULL;
1677
1678 #define SET_VERSION_INFO(CALL) \
1679 do { \
1680 PyObject *item = (CALL); \
1681 if (item == NULL) { \
1682 goto error; \
1683 } \
1684 PyStructSequence_SET_ITEM(version, pos++, item); \
1685 } while(0)
1686
1687 SET_VERSION_INFO(PyLong_FromLong(ver.dwMajorVersion));
1688 SET_VERSION_INFO(PyLong_FromLong(ver.dwMinorVersion));
1689 SET_VERSION_INFO(PyLong_FromLong(ver.dwBuildNumber));
1690 SET_VERSION_INFO(PyLong_FromLong(ver.dwPlatformId));
1691 SET_VERSION_INFO(PyUnicode_FromWideChar(ver.szCSDVersion, -1));
1692 SET_VERSION_INFO(PyLong_FromLong(ver.wServicePackMajor));
1693 SET_VERSION_INFO(PyLong_FromLong(ver.wServicePackMinor));
1694 SET_VERSION_INFO(PyLong_FromLong(ver.wSuiteMask));
1695 SET_VERSION_INFO(PyLong_FromLong(ver.wProductType));
1696
1697 // GetVersion will lie if we are running in a compatibility mode.
1698 // We need to read the version info from a system file resource
1699 // to accurately identify the OS version. If we fail for any reason,
1700 // just return whatever GetVersion said.
1701 PyObject *realVersion = _sys_getwindowsversion_from_kernel32();
1702 if (!realVersion) {
1703 if (!PyErr_ExceptionMatches(PyExc_WindowsError)) {
1704 return NULL;
1705 }
1706
1707 PyErr_Clear();
1708 realVersion = Py_BuildValue("(kkk)",
1709 ver.dwMajorVersion,
1710 ver.dwMinorVersion,
1711 ver.dwBuildNumber
1712 );
1713 }
1714
1715 SET_VERSION_INFO(realVersion);
1716
1717 #undef SET_VERSION_INFO
1718
1719 if (PyObject_SetAttrString(module, "_cached_windows_version", version) < 0) {
1720 goto error;
1721 }
1722
1723 return version;
1724
1725 error:
1726 Py_DECREF(version);
1727 return NULL;
1728 }
1729
1730 #pragma warning(pop)
1731
1732 /*[clinic input]
1733 sys._enablelegacywindowsfsencoding
1734
1735 Changes the default filesystem encoding to mbcs:replace.
1736
1737 This is done for consistency with earlier versions of Python. See PEP
1738 529 for more information.
1739
1740 This is equivalent to defining the PYTHONLEGACYWINDOWSFSENCODING
1741 environment variable before launching Python.
1742 [clinic start generated code]*/
1743
1744 static PyObject *
sys__enablelegacywindowsfsencoding_impl(PyObject * module)1745 sys__enablelegacywindowsfsencoding_impl(PyObject *module)
1746 /*[clinic end generated code: output=f5c3855b45e24fe9 input=2bfa931a20704492]*/
1747 {
1748 if (PyErr_WarnEx(PyExc_DeprecationWarning,
1749 "sys._enablelegacywindowsfsencoding() is deprecated and will be "
1750 "removed in Python 3.16. Use PYTHONLEGACYWINDOWSFSENCODING "
1751 "instead.", 1))
1752 {
1753 return NULL;
1754 }
1755 if (_PyUnicode_EnableLegacyWindowsFSEncoding() < 0) {
1756 return NULL;
1757 }
1758 Py_RETURN_NONE;
1759 }
1760
1761 #endif /* MS_WINDOWS */
1762
1763 #ifdef HAVE_DLOPEN
1764
1765 /*[clinic input]
1766 sys.setdlopenflags
1767
1768 flags as new_val: int
1769 /
1770
1771 Set the flags used by the interpreter for dlopen calls.
1772
1773 This is used, for example, when the interpreter loads extension
1774 modules. Among other things, this will enable a lazy resolving of
1775 symbols when importing a module, if called as sys.setdlopenflags(0).
1776 To share symbols across extension modules, call as
1777 sys.setdlopenflags(os.RTLD_GLOBAL). Symbolic names for the flag
1778 modules can be found in the os module (RTLD_xxx constants, e.g.
1779 os.RTLD_LAZY).
1780 [clinic start generated code]*/
1781
1782 static PyObject *
sys_setdlopenflags_impl(PyObject * module,int new_val)1783 sys_setdlopenflags_impl(PyObject *module, int new_val)
1784 /*[clinic end generated code: output=ec918b7fe0a37281 input=4c838211e857a77f]*/
1785 {
1786 PyInterpreterState *interp = _PyInterpreterState_GET();
1787 _PyImport_SetDLOpenFlags(interp, new_val);
1788 Py_RETURN_NONE;
1789 }
1790
1791
1792 /*[clinic input]
1793 sys.getdlopenflags
1794
1795 Return the current value of the flags that are used for dlopen calls.
1796
1797 The flag constants are defined in the os module.
1798 [clinic start generated code]*/
1799
1800 static PyObject *
sys_getdlopenflags_impl(PyObject * module)1801 sys_getdlopenflags_impl(PyObject *module)
1802 /*[clinic end generated code: output=e92cd1bc5005da6e input=dc4ea0899c53b4b6]*/
1803 {
1804 PyInterpreterState *interp = _PyInterpreterState_GET();
1805 return PyLong_FromLong(
1806 _PyImport_GetDLOpenFlags(interp));
1807 }
1808
1809 #endif /* HAVE_DLOPEN */
1810
1811 #ifdef USE_MALLOPT
1812 /* Link with -lmalloc (or -lmpc) on an SGI */
1813 #include <malloc.h>
1814
1815 /*[clinic input]
1816 sys.mdebug
1817
1818 flag: int
1819 /
1820 [clinic start generated code]*/
1821
1822 static PyObject *
sys_mdebug_impl(PyObject * module,int flag)1823 sys_mdebug_impl(PyObject *module, int flag)
1824 /*[clinic end generated code: output=5431d545847c3637 input=151d150ae1636f8a]*/
1825 {
1826 int flag;
1827 mallopt(M_DEBUG, flag);
1828 Py_RETURN_NONE;
1829 }
1830 #endif /* USE_MALLOPT */
1831
1832
1833 /*[clinic input]
1834 sys.get_int_max_str_digits
1835
1836 Return the maximum string digits limit for non-binary int<->str conversions.
1837 [clinic start generated code]*/
1838
1839 static PyObject *
sys_get_int_max_str_digits_impl(PyObject * module)1840 sys_get_int_max_str_digits_impl(PyObject *module)
1841 /*[clinic end generated code: output=0042f5e8ae0e8631 input=61bf9f99bc8b112d]*/
1842 {
1843 PyInterpreterState *interp = _PyInterpreterState_GET();
1844 return PyLong_FromLong(interp->long_state.max_str_digits);
1845 }
1846
1847 /*[clinic input]
1848 sys.set_int_max_str_digits
1849
1850 maxdigits: int
1851
1852 Set the maximum string digits limit for non-binary int<->str conversions.
1853 [clinic start generated code]*/
1854
1855 static PyObject *
sys_set_int_max_str_digits_impl(PyObject * module,int maxdigits)1856 sys_set_int_max_str_digits_impl(PyObject *module, int maxdigits)
1857 /*[clinic end generated code: output=734d4c2511f2a56d input=d7e3f325db6910c5]*/
1858 {
1859 PyThreadState *tstate = _PyThreadState_GET();
1860 if ((!maxdigits) || (maxdigits >= _PY_LONG_MAX_STR_DIGITS_THRESHOLD)) {
1861 tstate->interp->long_state.max_str_digits = maxdigits;
1862 Py_RETURN_NONE;
1863 } else {
1864 PyErr_Format(
1865 PyExc_ValueError, "maxdigits must be 0 or larger than %d",
1866 _PY_LONG_MAX_STR_DIGITS_THRESHOLD);
1867 return NULL;
1868 }
1869 }
1870
1871 size_t
_PySys_GetSizeOf(PyObject * o)1872 _PySys_GetSizeOf(PyObject *o)
1873 {
1874 PyObject *res = NULL;
1875 PyObject *method;
1876 Py_ssize_t size;
1877 PyThreadState *tstate = _PyThreadState_GET();
1878
1879 /* Make sure the type is initialized. float gets initialized late */
1880 if (PyType_Ready(Py_TYPE(o)) < 0) {
1881 return (size_t)-1;
1882 }
1883
1884 method = _PyObject_LookupSpecial(o, &_Py_ID(__sizeof__));
1885 if (method == NULL) {
1886 if (!_PyErr_Occurred(tstate)) {
1887 _PyErr_Format(tstate, PyExc_TypeError,
1888 "Type %.100s doesn't define __sizeof__",
1889 Py_TYPE(o)->tp_name);
1890 }
1891 }
1892 else {
1893 res = _PyObject_CallNoArgs(method);
1894 Py_DECREF(method);
1895 }
1896
1897 if (res == NULL)
1898 return (size_t)-1;
1899
1900 size = PyLong_AsSsize_t(res);
1901 Py_DECREF(res);
1902 if (size == -1 && _PyErr_Occurred(tstate))
1903 return (size_t)-1;
1904
1905 if (size < 0) {
1906 _PyErr_SetString(tstate, PyExc_ValueError,
1907 "__sizeof__() should return >= 0");
1908 return (size_t)-1;
1909 }
1910
1911 size_t presize = 0;
1912 if (!Py_IS_TYPE(o, &PyType_Type) ||
1913 PyType_HasFeature((PyTypeObject *)o, Py_TPFLAGS_HEAPTYPE))
1914 {
1915 /* Add the size of the pre-header if "o" is not a static type */
1916 presize = _PyType_PreHeaderSize(Py_TYPE(o));
1917 }
1918
1919 return (size_t)size + presize;
1920 }
1921
1922 static PyObject *
sys_getsizeof(PyObject * self,PyObject * args,PyObject * kwds)1923 sys_getsizeof(PyObject *self, PyObject *args, PyObject *kwds)
1924 {
1925 static char *kwlist[] = {"object", "default", 0};
1926 size_t size;
1927 PyObject *o, *dflt = NULL;
1928 PyThreadState *tstate = _PyThreadState_GET();
1929
1930 if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|O:getsizeof",
1931 kwlist, &o, &dflt)) {
1932 return NULL;
1933 }
1934
1935 size = _PySys_GetSizeOf(o);
1936
1937 if (size == (size_t)-1 && _PyErr_Occurred(tstate)) {
1938 /* Has a default value been given */
1939 if (dflt != NULL && _PyErr_ExceptionMatches(tstate, PyExc_TypeError)) {
1940 _PyErr_Clear(tstate);
1941 return Py_NewRef(dflt);
1942 }
1943 else
1944 return NULL;
1945 }
1946
1947 return PyLong_FromSize_t(size);
1948 }
1949
1950 PyDoc_STRVAR(getsizeof_doc,
1951 "getsizeof(object [, default]) -> int\n\
1952 \n\
1953 Return the size of object in bytes.");
1954
1955 /*[clinic input]
1956 sys.getrefcount -> Py_ssize_t
1957
1958 object: object
1959 /
1960
1961 Return the reference count of object.
1962
1963 The count returned is generally one higher than you might expect,
1964 because it includes the (temporary) reference as an argument to
1965 getrefcount().
1966 [clinic start generated code]*/
1967
1968 static Py_ssize_t
sys_getrefcount_impl(PyObject * module,PyObject * object)1969 sys_getrefcount_impl(PyObject *module, PyObject *object)
1970 /*[clinic end generated code: output=5fd477f2264b85b2 input=bf474efd50a21535]*/
1971 {
1972 return Py_REFCNT(object);
1973 }
1974
1975 #ifdef Py_REF_DEBUG
1976 /*[clinic input]
1977 sys.gettotalrefcount -> Py_ssize_t
1978 [clinic start generated code]*/
1979
1980 static Py_ssize_t
sys_gettotalrefcount_impl(PyObject * module)1981 sys_gettotalrefcount_impl(PyObject *module)
1982 /*[clinic end generated code: output=4103886cf17c25bc input=53b744faa5d2e4f6]*/
1983 {
1984 /* It may make sense to return the total for the current interpreter
1985 or have a second function that does so. */
1986 return _Py_GetGlobalRefTotal();
1987 }
1988
1989 #endif /* Py_REF_DEBUG */
1990
1991 /*[clinic input]
1992 sys.getallocatedblocks -> Py_ssize_t
1993
1994 Return the number of memory blocks currently allocated.
1995 [clinic start generated code]*/
1996
1997 static Py_ssize_t
sys_getallocatedblocks_impl(PyObject * module)1998 sys_getallocatedblocks_impl(PyObject *module)
1999 /*[clinic end generated code: output=f0c4e873f0b6dcf7 input=dab13ee346a0673e]*/
2000 {
2001 // It might make sense to return the count
2002 // for just the current interpreter.
2003 return _Py_GetGlobalAllocatedBlocks();
2004 }
2005
2006 /*[clinic input]
2007 sys.getunicodeinternedsize -> Py_ssize_t
2008
2009 *
2010 _only_immortal: bool = False
2011
2012 Return the number of elements of the unicode interned dictionary
2013 [clinic start generated code]*/
2014
2015 static Py_ssize_t
sys_getunicodeinternedsize_impl(PyObject * module,int _only_immortal)2016 sys_getunicodeinternedsize_impl(PyObject *module, int _only_immortal)
2017 /*[clinic end generated code: output=29a6377a94a14f70 input=0330b3408dd5bcc6]*/
2018 {
2019 if (_only_immortal) {
2020 return _PyUnicode_InternedSize_Immortal();
2021 }
2022 else {
2023 return _PyUnicode_InternedSize();
2024 }
2025 }
2026
2027 /*[clinic input]
2028 sys._getframe
2029
2030 depth: int = 0
2031 /
2032
2033 Return a frame object from the call stack.
2034
2035 If optional integer depth is given, return the frame object that many
2036 calls below the top of the stack. If that is deeper than the call
2037 stack, ValueError is raised. The default for depth is zero, returning
2038 the frame at the top of the call stack.
2039
2040 This function should be used for internal and specialized purposes
2041 only.
2042 [clinic start generated code]*/
2043
2044 static PyObject *
sys__getframe_impl(PyObject * module,int depth)2045 sys__getframe_impl(PyObject *module, int depth)
2046 /*[clinic end generated code: output=d438776c04d59804 input=c1be8a6464b11ee5]*/
2047 {
2048 PyThreadState *tstate = _PyThreadState_GET();
2049 _PyInterpreterFrame *frame = tstate->current_frame;
2050
2051 if (frame != NULL) {
2052 while (depth > 0) {
2053 frame = _PyFrame_GetFirstComplete(frame->previous);
2054 if (frame == NULL) {
2055 break;
2056 }
2057 --depth;
2058 }
2059 }
2060 if (frame == NULL) {
2061 _PyErr_SetString(tstate, PyExc_ValueError,
2062 "call stack is not deep enough");
2063 return NULL;
2064 }
2065
2066 PyObject *pyFrame = Py_XNewRef((PyObject *)_PyFrame_GetFrameObject(frame));
2067 if (pyFrame && _PySys_Audit(tstate, "sys._getframe", "(O)", pyFrame) < 0) {
2068 Py_DECREF(pyFrame);
2069 return NULL;
2070 }
2071 return pyFrame;
2072 }
2073
2074 /*[clinic input]
2075 sys._current_frames
2076
2077 Return a dict mapping each thread's thread id to its current stack frame.
2078
2079 This function should be used for specialized purposes only.
2080 [clinic start generated code]*/
2081
2082 static PyObject *
sys__current_frames_impl(PyObject * module)2083 sys__current_frames_impl(PyObject *module)
2084 /*[clinic end generated code: output=d2a41ac0a0a3809a input=2a9049c5f5033691]*/
2085 {
2086 return _PyThread_CurrentFrames();
2087 }
2088
2089 /*[clinic input]
2090 sys._current_exceptions
2091
2092 Return a dict mapping each thread's identifier to its current raised exception.
2093
2094 This function should be used for specialized purposes only.
2095 [clinic start generated code]*/
2096
2097 static PyObject *
sys__current_exceptions_impl(PyObject * module)2098 sys__current_exceptions_impl(PyObject *module)
2099 /*[clinic end generated code: output=2ccfd838c746f0ba input=0e91818fbf2edc1f]*/
2100 {
2101 return _PyThread_CurrentExceptions();
2102 }
2103
2104 /*[clinic input]
2105 sys.call_tracing
2106
2107 func: object
2108 args as funcargs: object(subclass_of='&PyTuple_Type')
2109 /
2110
2111 Call func(*args), while tracing is enabled.
2112
2113 The tracing state is saved, and restored afterwards. This is intended
2114 to be called from a debugger from a checkpoint, to recursively debug
2115 some other code.
2116 [clinic start generated code]*/
2117
2118 static PyObject *
sys_call_tracing_impl(PyObject * module,PyObject * func,PyObject * funcargs)2119 sys_call_tracing_impl(PyObject *module, PyObject *func, PyObject *funcargs)
2120 /*[clinic end generated code: output=7e4999853cd4e5a6 input=5102e8b11049f92f]*/
2121 {
2122 return _PyEval_CallTracing(func, funcargs);
2123 }
2124
2125 /*[clinic input]
2126 sys._debugmallocstats
2127
2128 Print summary info to stderr about the state of pymalloc's structures.
2129
2130 In Py_DEBUG mode, also perform some expensive internal consistency
2131 checks.
2132 [clinic start generated code]*/
2133
2134 static PyObject *
sys__debugmallocstats_impl(PyObject * module)2135 sys__debugmallocstats_impl(PyObject *module)
2136 /*[clinic end generated code: output=ec3565f8c7cee46a input=33c0c9c416f98424]*/
2137 {
2138 #ifdef WITH_PYMALLOC
2139 if (_PyObject_DebugMallocStats(stderr)) {
2140 fputc('\n', stderr);
2141 }
2142 #endif
2143 _PyObject_DebugTypeStats(stderr);
2144
2145 Py_RETURN_NONE;
2146 }
2147
2148 #ifdef Py_TRACE_REFS
2149 /* Defined in objects.c because it uses static globals in that file */
2150 extern PyObject *_Py_GetObjects(PyObject *, PyObject *);
2151 #endif
2152
2153
2154 /*[clinic input]
2155 sys._clear_type_cache
2156
2157 Clear the internal type lookup cache.
2158 [clinic start generated code]*/
2159
2160 static PyObject *
sys__clear_type_cache_impl(PyObject * module)2161 sys__clear_type_cache_impl(PyObject *module)
2162 /*[clinic end generated code: output=20e48ca54a6f6971 input=127f3e04a8d9b555]*/
2163 {
2164 PyType_ClearCache();
2165 Py_RETURN_NONE;
2166 }
2167
2168 /*[clinic input]
2169 sys._clear_internal_caches
2170
2171 Clear all internal performance-related caches.
2172 [clinic start generated code]*/
2173
2174 static PyObject *
sys__clear_internal_caches_impl(PyObject * module)2175 sys__clear_internal_caches_impl(PyObject *module)
2176 /*[clinic end generated code: output=0ee128670a4966d6 input=253e741ca744f6e8]*/
2177 {
2178 #ifdef _Py_TIER2
2179 PyInterpreterState *interp = _PyInterpreterState_GET();
2180 _Py_Executors_InvalidateAll(interp, 0);
2181 #endif
2182 PyType_ClearCache();
2183 Py_RETURN_NONE;
2184 }
2185
2186 /* Note that, for now, we do not have a per-interpreter equivalent
2187 for sys.is_finalizing(). */
2188
2189 /*[clinic input]
2190 sys.is_finalizing
2191
2192 Return True if Python is exiting.
2193 [clinic start generated code]*/
2194
2195 static PyObject *
sys_is_finalizing_impl(PyObject * module)2196 sys_is_finalizing_impl(PyObject *module)
2197 /*[clinic end generated code: output=735b5ff7962ab281 input=f0df747a039948a5]*/
2198 {
2199 return PyBool_FromLong(Py_IsFinalizing());
2200 }
2201
2202
2203 #ifdef Py_STATS
2204 /*[clinic input]
2205 sys._stats_on
2206
2207 Turns on stats gathering (stats gathering is off by default).
2208 [clinic start generated code]*/
2209
2210 static PyObject *
sys__stats_on_impl(PyObject * module)2211 sys__stats_on_impl(PyObject *module)
2212 /*[clinic end generated code: output=aca53eafcbb4d9fe input=43b5bfe145299e55]*/
2213 {
2214 _Py_StatsOn();
2215 Py_RETURN_NONE;
2216 }
2217
2218 /*[clinic input]
2219 sys._stats_off
2220
2221 Turns off stats gathering (stats gathering is off by default).
2222 [clinic start generated code]*/
2223
2224 static PyObject *
sys__stats_off_impl(PyObject * module)2225 sys__stats_off_impl(PyObject *module)
2226 /*[clinic end generated code: output=1534c1ee63812214 input=d1a84c60c56cbce2]*/
2227 {
2228 _Py_StatsOff();
2229 Py_RETURN_NONE;
2230 }
2231
2232 /*[clinic input]
2233 sys._stats_clear
2234
2235 Clears the stats.
2236 [clinic start generated code]*/
2237
2238 static PyObject *
sys__stats_clear_impl(PyObject * module)2239 sys__stats_clear_impl(PyObject *module)
2240 /*[clinic end generated code: output=fb65a2525ee50604 input=3e03f2654f44da96]*/
2241 {
2242 _Py_StatsClear();
2243 Py_RETURN_NONE;
2244 }
2245
2246 /*[clinic input]
2247 sys._stats_dump -> bool
2248
2249 Dump stats to file, and clears the stats.
2250
2251 Return False if no statistics were not dumped because stats gathering was off.
2252 [clinic start generated code]*/
2253
2254 static int
sys__stats_dump_impl(PyObject * module)2255 sys__stats_dump_impl(PyObject *module)
2256 /*[clinic end generated code: output=6e346b4ba0de4489 input=31a489e39418b2a5]*/
2257 {
2258 int res = _Py_PrintSpecializationStats(1);
2259 _Py_StatsClear();
2260 return res;
2261 }
2262 #endif // Py_STATS
2263
2264
2265 #ifdef ANDROID_API_LEVEL
2266 /*[clinic input]
2267 sys.getandroidapilevel
2268
2269 Return the build time API version of Android as an integer.
2270 [clinic start generated code]*/
2271
2272 static PyObject *
sys_getandroidapilevel_impl(PyObject * module)2273 sys_getandroidapilevel_impl(PyObject *module)
2274 /*[clinic end generated code: output=214abf183a1c70c1 input=3e6d6c9fcdd24ac6]*/
2275 {
2276 return PyLong_FromLong(ANDROID_API_LEVEL);
2277 }
2278 #endif /* ANDROID_API_LEVEL */
2279
2280 /*[clinic input]
2281 sys.activate_stack_trampoline
2282
2283 backend: str
2284 /
2285
2286 Activate stack profiler trampoline *backend*.
2287 [clinic start generated code]*/
2288
2289 static PyObject *
sys_activate_stack_trampoline_impl(PyObject * module,const char * backend)2290 sys_activate_stack_trampoline_impl(PyObject *module, const char *backend)
2291 /*[clinic end generated code: output=5783cdeb51874b43 input=a12df928758a82b4]*/
2292 {
2293 #ifdef PY_HAVE_PERF_TRAMPOLINE
2294 if (strcmp(backend, "perf") == 0) {
2295 _PyPerf_Callbacks cur_cb;
2296 _PyPerfTrampoline_GetCallbacks(&cur_cb);
2297 if (cur_cb.write_state != _Py_perfmap_callbacks.write_state) {
2298 if (_PyPerfTrampoline_SetCallbacks(&_Py_perfmap_callbacks) < 0 ) {
2299 PyErr_SetString(PyExc_ValueError, "can't activate perf trampoline");
2300 return NULL;
2301 }
2302 }
2303 else if (strcmp(backend, "perf_jit") == 0) {
2304 _PyPerf_Callbacks cur_cb;
2305 _PyPerfTrampoline_GetCallbacks(&cur_cb);
2306 if (cur_cb.write_state != _Py_perfmap_jit_callbacks.write_state) {
2307 if (_PyPerfTrampoline_SetCallbacks(&_Py_perfmap_jit_callbacks) < 0 ) {
2308 PyErr_SetString(PyExc_ValueError, "can't activate perf jit trampoline");
2309 return NULL;
2310 }
2311 }
2312 }
2313 }
2314 else {
2315 PyErr_Format(PyExc_ValueError, "invalid backend: %s", backend);
2316 return NULL;
2317 }
2318 if (_PyPerfTrampoline_Init(1) < 0) {
2319 return NULL;
2320 }
2321 Py_RETURN_NONE;
2322 #else
2323 PyErr_SetString(PyExc_ValueError, "perf trampoline not available");
2324 return NULL;
2325 #endif
2326 }
2327
2328
2329 /*[clinic input]
2330 sys.deactivate_stack_trampoline
2331
2332 Deactivate the current stack profiler trampoline backend.
2333
2334 If no stack profiler is activated, this function has no effect.
2335 [clinic start generated code]*/
2336
2337 static PyObject *
sys_deactivate_stack_trampoline_impl(PyObject * module)2338 sys_deactivate_stack_trampoline_impl(PyObject *module)
2339 /*[clinic end generated code: output=b50da25465df0ef1 input=9f629a6be9fe7fc8]*/
2340 {
2341 if (_PyPerfTrampoline_Init(0) < 0) {
2342 return NULL;
2343 }
2344 Py_RETURN_NONE;
2345 }
2346
2347 /*[clinic input]
2348 sys.is_stack_trampoline_active
2349
2350 Return *True* if a stack profiler trampoline is active.
2351 [clinic start generated code]*/
2352
2353 static PyObject *
sys_is_stack_trampoline_active_impl(PyObject * module)2354 sys_is_stack_trampoline_active_impl(PyObject *module)
2355 /*[clinic end generated code: output=ab2746de0ad9d293 input=29616b7bf6a0b703]*/
2356 {
2357 #ifdef PY_HAVE_PERF_TRAMPOLINE
2358 if (_PyIsPerfTrampolineActive()) {
2359 Py_RETURN_TRUE;
2360 }
2361 #endif
2362 Py_RETURN_FALSE;
2363 }
2364
2365
2366 /*[clinic input]
2367 sys._getframemodulename
2368
2369 depth: int = 0
2370
2371 Return the name of the module for a calling frame.
2372
2373 The default depth returns the module containing the call to this API.
2374 A more typical use in a library will pass a depth of 1 to get the user's
2375 module rather than the library module.
2376
2377 If no frame, module, or name can be found, returns None.
2378 [clinic start generated code]*/
2379
2380 static PyObject *
sys__getframemodulename_impl(PyObject * module,int depth)2381 sys__getframemodulename_impl(PyObject *module, int depth)
2382 /*[clinic end generated code: output=1d70ef691f09d2db input=d4f1a8ed43b8fb46]*/
2383 {
2384 if (PySys_Audit("sys._getframemodulename", "i", depth) < 0) {
2385 return NULL;
2386 }
2387 _PyInterpreterFrame *f = _PyThreadState_GET()->current_frame;
2388 while (f && (_PyFrame_IsIncomplete(f) || depth-- > 0)) {
2389 f = f->previous;
2390 }
2391 if (f == NULL || f->f_funcobj == NULL) {
2392 Py_RETURN_NONE;
2393 }
2394 PyObject *r = PyFunction_GetModule(f->f_funcobj);
2395 if (!r) {
2396 PyErr_Clear();
2397 r = Py_None;
2398 }
2399 return Py_NewRef(r);
2400 }
2401
2402 /*[clinic input]
2403 sys._get_cpu_count_config -> int
2404
2405 Private function for getting PyConfig.cpu_count
2406 [clinic start generated code]*/
2407
2408 static int
sys__get_cpu_count_config_impl(PyObject * module)2409 sys__get_cpu_count_config_impl(PyObject *module)
2410 /*[clinic end generated code: output=36611bb5efad16dc input=523e1ade2204084e]*/
2411 {
2412 const PyConfig *config = _Py_GetConfig();
2413 return config->cpu_count;
2414 }
2415
2416 /*[clinic input]
2417 sys._baserepl
2418
2419 Private function for getting the base REPL
2420 [clinic start generated code]*/
2421
2422 static PyObject *
sys__baserepl_impl(PyObject * module)2423 sys__baserepl_impl(PyObject *module)
2424 /*[clinic end generated code: output=f19a36375ebe0a45 input=ade0ebb9fab56f3c]*/
2425 {
2426 PyCompilerFlags cf = _PyCompilerFlags_INIT;
2427 PyRun_AnyFileExFlags(stdin, "<stdin>", 0, &cf);
2428 Py_RETURN_NONE;
2429 }
2430
2431 /*[clinic input]
2432 sys._is_gil_enabled -> bool
2433
2434 Return True if the GIL is currently enabled and False otherwise.
2435 [clinic start generated code]*/
2436
2437 static int
sys__is_gil_enabled_impl(PyObject * module)2438 sys__is_gil_enabled_impl(PyObject *module)
2439 /*[clinic end generated code: output=57732cf53f5b9120 input=7e9c47f15a00e809]*/
2440 {
2441 #ifdef Py_GIL_DISABLED
2442 return _PyEval_IsGILEnabled(_PyThreadState_GET());
2443 #else
2444 return 1;
2445 #endif
2446 }
2447
2448
2449 static PerfMapState perf_map_state;
2450
PyUnstable_PerfMapState_Init(void)2451 PyAPI_FUNC(int) PyUnstable_PerfMapState_Init(void) {
2452 #ifndef MS_WINDOWS
2453 char filename[100];
2454 pid_t pid = getpid();
2455 // Use nofollow flag to prevent symlink attacks.
2456 int flags = O_WRONLY | O_CREAT | O_APPEND | O_NOFOLLOW;
2457 #ifdef O_CLOEXEC
2458 flags |= O_CLOEXEC;
2459 #endif
2460 snprintf(filename, sizeof(filename) - 1, "/tmp/perf-%jd.map",
2461 (intmax_t)pid);
2462 int fd = open(filename, flags, 0600);
2463 if (fd == -1) {
2464 return -1;
2465 }
2466 else{
2467 perf_map_state.perf_map = fdopen(fd, "a");
2468 if (perf_map_state.perf_map == NULL) {
2469 close(fd);
2470 return -1;
2471 }
2472 }
2473 perf_map_state.map_lock = PyThread_allocate_lock();
2474 if (perf_map_state.map_lock == NULL) {
2475 fclose(perf_map_state.perf_map);
2476 return -2;
2477 }
2478 #endif
2479 return 0;
2480 }
2481
PyUnstable_WritePerfMapEntry(const void * code_addr,unsigned int code_size,const char * entry_name)2482 PyAPI_FUNC(int) PyUnstable_WritePerfMapEntry(
2483 const void *code_addr,
2484 unsigned int code_size,
2485 const char *entry_name
2486 ) {
2487 #ifndef MS_WINDOWS
2488 if (perf_map_state.perf_map == NULL) {
2489 int ret = PyUnstable_PerfMapState_Init();
2490 if (ret != 0){
2491 return ret;
2492 }
2493 }
2494 PyThread_acquire_lock(perf_map_state.map_lock, 1);
2495 fprintf(perf_map_state.perf_map, "%" PRIxPTR " %x %s\n", (uintptr_t) code_addr, code_size, entry_name);
2496 fflush(perf_map_state.perf_map);
2497 PyThread_release_lock(perf_map_state.map_lock);
2498 #endif
2499 return 0;
2500 }
2501
PyUnstable_PerfMapState_Fini(void)2502 PyAPI_FUNC(void) PyUnstable_PerfMapState_Fini(void) {
2503 #ifndef MS_WINDOWS
2504 if (perf_map_state.perf_map != NULL) {
2505 // close the file
2506 PyThread_acquire_lock(perf_map_state.map_lock, 1);
2507 fclose(perf_map_state.perf_map);
2508 PyThread_release_lock(perf_map_state.map_lock);
2509
2510 // clean up the lock and state
2511 PyThread_free_lock(perf_map_state.map_lock);
2512 perf_map_state.perf_map = NULL;
2513 }
2514 #endif
2515 }
2516
PyUnstable_CopyPerfMapFile(const char * parent_filename)2517 PyAPI_FUNC(int) PyUnstable_CopyPerfMapFile(const char* parent_filename) {
2518 #ifndef MS_WINDOWS
2519 FILE* from = fopen(parent_filename, "r");
2520 if (!from) {
2521 return -1;
2522 }
2523 if (perf_map_state.perf_map == NULL) {
2524 int ret = PyUnstable_PerfMapState_Init();
2525 if (ret != 0) {
2526 return ret;
2527 }
2528 }
2529 char buf[4096];
2530 PyThread_acquire_lock(perf_map_state.map_lock, 1);
2531 int fflush_result = 0, result = 0;
2532 while (1) {
2533 size_t bytes_read = fread(buf, 1, sizeof(buf), from);
2534 size_t bytes_written = fwrite(buf, 1, bytes_read, perf_map_state.perf_map);
2535 fflush_result = fflush(perf_map_state.perf_map);
2536 if (fflush_result != 0 || bytes_read == 0 || bytes_written < bytes_read) {
2537 result = -1;
2538 goto close_and_release;
2539 }
2540 if (bytes_read < sizeof(buf) && feof(from)) {
2541 goto close_and_release;
2542 }
2543 }
2544 close_and_release:
2545 fclose(from);
2546 PyThread_release_lock(perf_map_state.map_lock);
2547 return result;
2548 #endif
2549 return 0;
2550 }
2551
2552
2553 static PyMethodDef sys_methods[] = {
2554 /* Might as well keep this in alphabetic order */
2555 SYS_ADDAUDITHOOK_METHODDEF
2556 {"audit", _PyCFunction_CAST(sys_audit), METH_FASTCALL, audit_doc },
2557 {"breakpointhook", _PyCFunction_CAST(sys_breakpointhook),
2558 METH_FASTCALL | METH_KEYWORDS, breakpointhook_doc},
2559 SYS__CLEAR_INTERNAL_CACHES_METHODDEF
2560 SYS__CLEAR_TYPE_CACHE_METHODDEF
2561 SYS__CURRENT_FRAMES_METHODDEF
2562 SYS__CURRENT_EXCEPTIONS_METHODDEF
2563 SYS_DISPLAYHOOK_METHODDEF
2564 SYS_EXCEPTION_METHODDEF
2565 SYS_EXC_INFO_METHODDEF
2566 SYS_EXCEPTHOOK_METHODDEF
2567 SYS_EXIT_METHODDEF
2568 SYS_GETDEFAULTENCODING_METHODDEF
2569 SYS_GETDLOPENFLAGS_METHODDEF
2570 SYS_GETALLOCATEDBLOCKS_METHODDEF
2571 SYS_GETUNICODEINTERNEDSIZE_METHODDEF
2572 SYS_GETFILESYSTEMENCODING_METHODDEF
2573 SYS_GETFILESYSTEMENCODEERRORS_METHODDEF
2574 #ifdef Py_TRACE_REFS
2575 {"getobjects", _Py_GetObjects, METH_VARARGS},
2576 #endif
2577 SYS_GETTOTALREFCOUNT_METHODDEF
2578 SYS_GETREFCOUNT_METHODDEF
2579 SYS_GETRECURSIONLIMIT_METHODDEF
2580 {"getsizeof", _PyCFunction_CAST(sys_getsizeof),
2581 METH_VARARGS | METH_KEYWORDS, getsizeof_doc},
2582 SYS__GETFRAME_METHODDEF
2583 SYS__GETFRAMEMODULENAME_METHODDEF
2584 SYS_GETWINDOWSVERSION_METHODDEF
2585 SYS__ENABLELEGACYWINDOWSFSENCODING_METHODDEF
2586 SYS_INTERN_METHODDEF
2587 SYS__IS_INTERNED_METHODDEF
2588 SYS_IS_FINALIZING_METHODDEF
2589 SYS_MDEBUG_METHODDEF
2590 SYS_SETSWITCHINTERVAL_METHODDEF
2591 SYS_GETSWITCHINTERVAL_METHODDEF
2592 SYS_SETDLOPENFLAGS_METHODDEF
2593 SYS_SETPROFILE_METHODDEF
2594 SYS__SETPROFILEALLTHREADS_METHODDEF
2595 SYS_GETPROFILE_METHODDEF
2596 SYS_SETRECURSIONLIMIT_METHODDEF
2597 SYS_SETTRACE_METHODDEF
2598 SYS__SETTRACEALLTHREADS_METHODDEF
2599 SYS_GETTRACE_METHODDEF
2600 SYS_CALL_TRACING_METHODDEF
2601 SYS__DEBUGMALLOCSTATS_METHODDEF
2602 SYS_SET_COROUTINE_ORIGIN_TRACKING_DEPTH_METHODDEF
2603 SYS_GET_COROUTINE_ORIGIN_TRACKING_DEPTH_METHODDEF
2604 {"set_asyncgen_hooks", _PyCFunction_CAST(sys_set_asyncgen_hooks),
2605 METH_VARARGS | METH_KEYWORDS, set_asyncgen_hooks_doc},
2606 SYS_GET_ASYNCGEN_HOOKS_METHODDEF
2607 SYS_GETANDROIDAPILEVEL_METHODDEF
2608 SYS_ACTIVATE_STACK_TRAMPOLINE_METHODDEF
2609 SYS_DEACTIVATE_STACK_TRAMPOLINE_METHODDEF
2610 SYS_IS_STACK_TRAMPOLINE_ACTIVE_METHODDEF
2611 SYS_UNRAISABLEHOOK_METHODDEF
2612 SYS_GET_INT_MAX_STR_DIGITS_METHODDEF
2613 SYS_SET_INT_MAX_STR_DIGITS_METHODDEF
2614 SYS__BASEREPL_METHODDEF
2615 #ifdef Py_STATS
2616 SYS__STATS_ON_METHODDEF
2617 SYS__STATS_OFF_METHODDEF
2618 SYS__STATS_CLEAR_METHODDEF
2619 SYS__STATS_DUMP_METHODDEF
2620 #endif
2621 SYS__GET_CPU_COUNT_CONFIG_METHODDEF
2622 SYS__IS_GIL_ENABLED_METHODDEF
2623 {NULL, NULL} // sentinel
2624 };
2625
2626
2627 static PyObject *
list_builtin_module_names(void)2628 list_builtin_module_names(void)
2629 {
2630 PyObject *list = _PyImport_GetBuiltinModuleNames();
2631 if (list == NULL) {
2632 return NULL;
2633 }
2634 if (PyList_Sort(list) != 0) {
2635 goto error;
2636 }
2637 PyObject *tuple = PyList_AsTuple(list);
2638 Py_DECREF(list);
2639 return tuple;
2640
2641 error:
2642 Py_DECREF(list);
2643 return NULL;
2644 }
2645
2646
2647 static PyObject *
list_stdlib_module_names(void)2648 list_stdlib_module_names(void)
2649 {
2650 Py_ssize_t len = Py_ARRAY_LENGTH(_Py_stdlib_module_names);
2651 PyObject *names = PyTuple_New(len);
2652 if (names == NULL) {
2653 return NULL;
2654 }
2655
2656 for (Py_ssize_t i = 0; i < len; i++) {
2657 PyObject *name = PyUnicode_FromString(_Py_stdlib_module_names[i]);
2658 if (name == NULL) {
2659 Py_DECREF(names);
2660 return NULL;
2661 }
2662 PyTuple_SET_ITEM(names, i, name);
2663 }
2664
2665 PyObject *set = PyObject_CallFunction((PyObject *)&PyFrozenSet_Type,
2666 "(O)", names);
2667 Py_DECREF(names);
2668 return set;
2669 }
2670
2671
2672 /* Pre-initialization support for sys.warnoptions and sys._xoptions
2673 *
2674 * Modern internal code paths:
2675 * These APIs get called after _Py_InitializeCore and get to use the
2676 * regular CPython list, dict, and unicode APIs.
2677 *
2678 * Legacy embedding code paths:
2679 * The multi-phase initialization API isn't public yet, so embedding
2680 * apps still need to be able configure sys.warnoptions and sys._xoptions
2681 * before they call Py_Initialize. To support this, we stash copies of
2682 * the supplied wchar * sequences in linked lists, and then migrate the
2683 * contents of those lists to the sys module in _PyInitializeCore.
2684 *
2685 */
2686
2687 struct _preinit_entry {
2688 wchar_t *value;
2689 struct _preinit_entry *next;
2690 };
2691
2692 typedef struct _preinit_entry *_Py_PreInitEntry;
2693
2694 static _Py_PreInitEntry _preinit_warnoptions = NULL;
2695 static _Py_PreInitEntry _preinit_xoptions = NULL;
2696
2697 static _Py_PreInitEntry
_alloc_preinit_entry(const wchar_t * value)2698 _alloc_preinit_entry(const wchar_t *value)
2699 {
2700 /* To get this to work, we have to initialize the runtime implicitly */
2701 _PyRuntime_Initialize();
2702
2703 /* Force default allocator, so we can ensure that it also gets used to
2704 * destroy the linked list in _clear_preinit_entries.
2705 */
2706 PyMemAllocatorEx old_alloc;
2707 _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
2708
2709 _Py_PreInitEntry node = PyMem_RawCalloc(1, sizeof(*node));
2710 if (node != NULL) {
2711 node->value = _PyMem_RawWcsdup(value);
2712 if (node->value == NULL) {
2713 PyMem_RawFree(node);
2714 node = NULL;
2715 };
2716 };
2717
2718 PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
2719 return node;
2720 }
2721
2722 static int
_append_preinit_entry(_Py_PreInitEntry * optionlist,const wchar_t * value)2723 _append_preinit_entry(_Py_PreInitEntry *optionlist, const wchar_t *value)
2724 {
2725 _Py_PreInitEntry new_entry = _alloc_preinit_entry(value);
2726 if (new_entry == NULL) {
2727 return -1;
2728 }
2729 /* We maintain the linked list in this order so it's easy to play back
2730 * the add commands in the same order later on in _Py_InitializeCore
2731 */
2732 _Py_PreInitEntry last_entry = *optionlist;
2733 if (last_entry == NULL) {
2734 *optionlist = new_entry;
2735 } else {
2736 while (last_entry->next != NULL) {
2737 last_entry = last_entry->next;
2738 }
2739 last_entry->next = new_entry;
2740 }
2741 return 0;
2742 }
2743
2744 static void
_clear_preinit_entries(_Py_PreInitEntry * optionlist)2745 _clear_preinit_entries(_Py_PreInitEntry *optionlist)
2746 {
2747 _Py_PreInitEntry current = *optionlist;
2748 *optionlist = NULL;
2749 /* Deallocate the nodes and their contents using the default allocator */
2750 PyMemAllocatorEx old_alloc;
2751 _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
2752 while (current != NULL) {
2753 _Py_PreInitEntry next = current->next;
2754 PyMem_RawFree(current->value);
2755 PyMem_RawFree(current);
2756 current = next;
2757 }
2758 PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
2759 }
2760
2761
2762 PyStatus
_PySys_ReadPreinitWarnOptions(PyWideStringList * options)2763 _PySys_ReadPreinitWarnOptions(PyWideStringList *options)
2764 {
2765 PyStatus status;
2766 _Py_PreInitEntry entry;
2767
2768 for (entry = _preinit_warnoptions; entry != NULL; entry = entry->next) {
2769 status = PyWideStringList_Append(options, entry->value);
2770 if (_PyStatus_EXCEPTION(status)) {
2771 return status;
2772 }
2773 }
2774
2775 _clear_preinit_entries(&_preinit_warnoptions);
2776 return _PyStatus_OK();
2777 }
2778
2779
2780 PyStatus
_PySys_ReadPreinitXOptions(PyConfig * config)2781 _PySys_ReadPreinitXOptions(PyConfig *config)
2782 {
2783 PyStatus status;
2784 _Py_PreInitEntry entry;
2785
2786 for (entry = _preinit_xoptions; entry != NULL; entry = entry->next) {
2787 status = PyWideStringList_Append(&config->xoptions, entry->value);
2788 if (_PyStatus_EXCEPTION(status)) {
2789 return status;
2790 }
2791 }
2792
2793 _clear_preinit_entries(&_preinit_xoptions);
2794 return _PyStatus_OK();
2795 }
2796
2797
2798 static PyObject *
get_warnoptions(PyThreadState * tstate)2799 get_warnoptions(PyThreadState *tstate)
2800 {
2801 PyObject *warnoptions = _PySys_GetAttr(tstate, &_Py_ID(warnoptions));
2802 if (warnoptions == NULL || !PyList_Check(warnoptions)) {
2803 /* PEP432 TODO: we can reach this if warnoptions is NULL in the main
2804 * interpreter config. When that happens, we need to properly set
2805 * the `warnoptions` reference in the main interpreter config as well.
2806 *
2807 * For Python 3.7, we shouldn't be able to get here due to the
2808 * combination of how _PyMainInterpreter_ReadConfig and _PySys_EndInit
2809 * work, but we expect 3.8+ to make the _PyMainInterpreter_ReadConfig
2810 * call optional for embedding applications, thus making this
2811 * reachable again.
2812 */
2813 warnoptions = PyList_New(0);
2814 if (warnoptions == NULL) {
2815 return NULL;
2816 }
2817 if (sys_set_object(tstate->interp, &_Py_ID(warnoptions), warnoptions)) {
2818 Py_DECREF(warnoptions);
2819 return NULL;
2820 }
2821 Py_DECREF(warnoptions);
2822 }
2823 return warnoptions;
2824 }
2825
2826 void
PySys_ResetWarnOptions(void)2827 PySys_ResetWarnOptions(void)
2828 {
2829 PyThreadState *tstate = _PyThreadState_GET();
2830 if (tstate == NULL) {
2831 _clear_preinit_entries(&_preinit_warnoptions);
2832 return;
2833 }
2834
2835 PyObject *warnoptions = _PySys_GetAttr(tstate, &_Py_ID(warnoptions));
2836 if (warnoptions == NULL || !PyList_Check(warnoptions))
2837 return;
2838 PyList_SetSlice(warnoptions, 0, PyList_GET_SIZE(warnoptions), NULL);
2839 }
2840
2841 static int
_PySys_AddWarnOptionWithError(PyThreadState * tstate,PyObject * option)2842 _PySys_AddWarnOptionWithError(PyThreadState *tstate, PyObject *option)
2843 {
2844 PyObject *warnoptions = get_warnoptions(tstate);
2845 if (warnoptions == NULL) {
2846 return -1;
2847 }
2848 if (PyList_Append(warnoptions, option)) {
2849 return -1;
2850 }
2851 return 0;
2852 }
2853
2854 // Removed in Python 3.13 API, but kept for the stable ABI
2855 PyAPI_FUNC(void)
PySys_AddWarnOptionUnicode(PyObject * option)2856 PySys_AddWarnOptionUnicode(PyObject *option)
2857 {
2858 PyThreadState *tstate = _PyThreadState_GET();
2859 if (_PySys_AddWarnOptionWithError(tstate, option) < 0) {
2860 /* No return value, therefore clear error state if possible */
2861 if (tstate) {
2862 _PyErr_Clear(tstate);
2863 }
2864 }
2865 }
2866
2867 // Removed in Python 3.13 API, but kept for the stable ABI
2868 PyAPI_FUNC(void)
PySys_AddWarnOption(const wchar_t * s)2869 PySys_AddWarnOption(const wchar_t *s)
2870 {
2871 PyThreadState *tstate = _PyThreadState_GET();
2872 if (tstate == NULL) {
2873 _append_preinit_entry(&_preinit_warnoptions, s);
2874 return;
2875 }
2876 PyObject *unicode;
2877 unicode = PyUnicode_FromWideChar(s, -1);
2878 if (unicode == NULL)
2879 return;
2880 _Py_COMP_DIAG_PUSH
2881 _Py_COMP_DIAG_IGNORE_DEPR_DECLS
2882 PySys_AddWarnOptionUnicode(unicode);
2883 _Py_COMP_DIAG_POP
2884 Py_DECREF(unicode);
2885 }
2886
2887 // Removed in Python 3.13 API, but kept for the stable ABI
2888 PyAPI_FUNC(int)
PySys_HasWarnOptions(void)2889 PySys_HasWarnOptions(void)
2890 {
2891 PyThreadState *tstate = _PyThreadState_GET();
2892 PyObject *warnoptions = _PySys_GetAttr(tstate, &_Py_ID(warnoptions));
2893 return (warnoptions != NULL && PyList_Check(warnoptions)
2894 && PyList_GET_SIZE(warnoptions) > 0);
2895 }
2896
2897 static PyObject *
get_xoptions(PyThreadState * tstate)2898 get_xoptions(PyThreadState *tstate)
2899 {
2900 PyObject *xoptions = _PySys_GetAttr(tstate, &_Py_ID(_xoptions));
2901 if (xoptions == NULL || !PyDict_Check(xoptions)) {
2902 /* PEP432 TODO: we can reach this if xoptions is NULL in the main
2903 * interpreter config. When that happens, we need to properly set
2904 * the `xoptions` reference in the main interpreter config as well.
2905 *
2906 * For Python 3.7, we shouldn't be able to get here due to the
2907 * combination of how _PyMainInterpreter_ReadConfig and _PySys_EndInit
2908 * work, but we expect 3.8+ to make the _PyMainInterpreter_ReadConfig
2909 * call optional for embedding applications, thus making this
2910 * reachable again.
2911 */
2912 xoptions = PyDict_New();
2913 if (xoptions == NULL) {
2914 return NULL;
2915 }
2916 if (sys_set_object(tstate->interp, &_Py_ID(_xoptions), xoptions)) {
2917 Py_DECREF(xoptions);
2918 return NULL;
2919 }
2920 Py_DECREF(xoptions);
2921 }
2922 return xoptions;
2923 }
2924
2925 static int
_PySys_AddXOptionWithError(const wchar_t * s)2926 _PySys_AddXOptionWithError(const wchar_t *s)
2927 {
2928 PyObject *name = NULL, *value = NULL;
2929
2930 PyThreadState *tstate = _PyThreadState_GET();
2931 PyObject *opts = get_xoptions(tstate);
2932 if (opts == NULL) {
2933 goto error;
2934 }
2935
2936 const wchar_t *name_end = wcschr(s, L'=');
2937 if (!name_end) {
2938 name = PyUnicode_FromWideChar(s, -1);
2939 if (name == NULL) {
2940 goto error;
2941 }
2942 value = Py_NewRef(Py_True);
2943 }
2944 else {
2945 name = PyUnicode_FromWideChar(s, name_end - s);
2946 if (name == NULL) {
2947 goto error;
2948 }
2949 value = PyUnicode_FromWideChar(name_end + 1, -1);
2950 if (value == NULL) {
2951 goto error;
2952 }
2953 }
2954 if (PyDict_SetItem(opts, name, value) < 0) {
2955 goto error;
2956 }
2957 Py_DECREF(name);
2958 Py_DECREF(value);
2959 return 0;
2960
2961 error:
2962 Py_XDECREF(name);
2963 Py_XDECREF(value);
2964 return -1;
2965 }
2966
2967 // Removed in Python 3.13 API, but kept for the stable ABI
2968 PyAPI_FUNC(void)
PySys_AddXOption(const wchar_t * s)2969 PySys_AddXOption(const wchar_t *s)
2970 {
2971 PyThreadState *tstate = _PyThreadState_GET();
2972 if (tstate == NULL) {
2973 _append_preinit_entry(&_preinit_xoptions, s);
2974 return;
2975 }
2976 if (_PySys_AddXOptionWithError(s) < 0) {
2977 /* No return value, therefore clear error state if possible */
2978 _PyErr_Clear(tstate);
2979 }
2980 }
2981
2982 PyObject *
PySys_GetXOptions(void)2983 PySys_GetXOptions(void)
2984 {
2985 PyThreadState *tstate = _PyThreadState_GET();
2986 return get_xoptions(tstate);
2987 }
2988
2989 /* XXX This doc string is too long to be a single string literal in VC++ 5.0.
2990 Two literals concatenated works just fine. If you have a K&R compiler
2991 or other abomination that however *does* understand longer strings,
2992 get rid of the !!! comment in the middle and the quotes that surround it. */
2993 PyDoc_VAR(sys_doc) =
2994 PyDoc_STR(
2995 "This module provides access to some objects used or maintained by the\n\
2996 interpreter and to functions that interact strongly with the interpreter.\n\
2997 \n\
2998 Dynamic objects:\n\
2999 \n\
3000 argv -- command line arguments; argv[0] is the script pathname if known\n\
3001 path -- module search path; path[0] is the script directory, else ''\n\
3002 modules -- dictionary of loaded modules\n\
3003 \n\
3004 displayhook -- called to show results in an interactive session\n\
3005 excepthook -- called to handle any uncaught exception other than SystemExit\n\
3006 To customize printing in an interactive session or to install a custom\n\
3007 top-level exception handler, assign other functions to replace these.\n\
3008 \n\
3009 stdin -- standard input file object; used by input()\n\
3010 stdout -- standard output file object; used by print()\n\
3011 stderr -- standard error object; used for error messages\n\
3012 By assigning other file objects (or objects that behave like files)\n\
3013 to these, it is possible to redirect all of the interpreter's I/O.\n\
3014 \n\
3015 last_exc - the last uncaught exception\n\
3016 Only available in an interactive session after a\n\
3017 traceback has been printed.\n\
3018 last_type -- type of last uncaught exception\n\
3019 last_value -- value of last uncaught exception\n\
3020 last_traceback -- traceback of last uncaught exception\n\
3021 These three are the (deprecated) legacy representation of last_exc.\n\
3022 "
3023 )
3024 /* concatenating string here */
3025 PyDoc_STR(
3026 "\n\
3027 Static objects:\n\
3028 \n\
3029 builtin_module_names -- tuple of module names built into this interpreter\n\
3030 copyright -- copyright notice pertaining to this interpreter\n\
3031 exec_prefix -- prefix used to find the machine-specific Python library\n\
3032 executable -- absolute path of the executable binary of the Python interpreter\n\
3033 float_info -- a named tuple with information about the float implementation.\n\
3034 float_repr_style -- string indicating the style of repr() output for floats\n\
3035 hash_info -- a named tuple with information about the hash algorithm.\n\
3036 hexversion -- version information encoded as a single integer\n\
3037 implementation -- Python implementation information.\n\
3038 int_info -- a named tuple with information about the int implementation.\n\
3039 maxsize -- the largest supported length of containers.\n\
3040 maxunicode -- the value of the largest Unicode code point\n\
3041 platform -- platform identifier\n\
3042 prefix -- prefix used to find the Python library\n\
3043 thread_info -- a named tuple with information about the thread implementation.\n\
3044 version -- the version of this interpreter as a string\n\
3045 version_info -- version information as a named tuple\n\
3046 "
3047 )
3048 #ifdef MS_COREDLL
3049 /* concatenating string here */
3050 PyDoc_STR(
3051 "dllhandle -- [Windows only] integer handle of the Python DLL\n\
3052 winver -- [Windows only] version number of the Python DLL\n\
3053 "
3054 )
3055 #endif /* MS_COREDLL */
3056 #ifdef MS_WINDOWS
3057 /* concatenating string here */
3058 PyDoc_STR(
3059 "_enablelegacywindowsfsencoding -- [Windows only]\n\
3060 "
3061 )
3062 #endif
3063 PyDoc_STR(
3064 "__stdin__ -- the original stdin; don't touch!\n\
3065 __stdout__ -- the original stdout; don't touch!\n\
3066 __stderr__ -- the original stderr; don't touch!\n\
3067 __displayhook__ -- the original displayhook; don't touch!\n\
3068 __excepthook__ -- the original excepthook; don't touch!\n\
3069 \n\
3070 Functions:\n\
3071 \n\
3072 displayhook() -- print an object to the screen, and save it in builtins._\n\
3073 excepthook() -- print an exception and its traceback to sys.stderr\n\
3074 exception() -- return the current thread's active exception\n\
3075 exc_info() -- return information about the current thread's active exception\n\
3076 exit() -- exit the interpreter by raising SystemExit\n\
3077 getdlopenflags() -- returns flags to be used for dlopen() calls\n\
3078 getprofile() -- get the global profiling function\n\
3079 getrefcount() -- return the reference count for an object (plus one :-)\n\
3080 getrecursionlimit() -- return the max recursion depth for the interpreter\n\
3081 getsizeof() -- return the size of an object in bytes\n\
3082 gettrace() -- get the global debug tracing function\n\
3083 setdlopenflags() -- set the flags to be used for dlopen() calls\n\
3084 setprofile() -- set the global profiling function\n\
3085 setrecursionlimit() -- set the max recursion depth for the interpreter\n\
3086 settrace() -- set the global debug tracing function\n\
3087 "
3088 )
3089 /* end of sys_doc */ ;
3090
3091
3092 PyDoc_STRVAR(flags__doc__,
3093 "sys.flags\n\
3094 \n\
3095 Flags provided through command line arguments or environment vars.");
3096
3097 static PyTypeObject FlagsType;
3098
3099 static PyStructSequence_Field flags_fields[] = {
3100 {"debug", "-d"},
3101 {"inspect", "-i"},
3102 {"interactive", "-i"},
3103 {"optimize", "-O or -OO"},
3104 {"dont_write_bytecode", "-B"},
3105 {"no_user_site", "-s"},
3106 {"no_site", "-S"},
3107 {"ignore_environment", "-E"},
3108 {"verbose", "-v"},
3109 {"bytes_warning", "-b"},
3110 {"quiet", "-q"},
3111 {"hash_randomization", "-R"},
3112 {"isolated", "-I"},
3113 {"dev_mode", "-X dev"},
3114 {"utf8_mode", "-X utf8"},
3115 {"warn_default_encoding", "-X warn_default_encoding"},
3116 {"safe_path", "-P"},
3117 {"int_max_str_digits", "-X int_max_str_digits"},
3118 {"gil", "-X gil"},
3119 {0}
3120 };
3121
3122 static PyStructSequence_Desc flags_desc = {
3123 "sys.flags", /* name */
3124 flags__doc__, /* doc */
3125 flags_fields, /* fields */
3126 18
3127 };
3128
3129 static int
set_flags_from_config(PyInterpreterState * interp,PyObject * flags)3130 set_flags_from_config(PyInterpreterState *interp, PyObject *flags)
3131 {
3132 const PyPreConfig *preconfig = &interp->runtime->preconfig;
3133 const PyConfig *config = _PyInterpreterState_GetConfig(interp);
3134
3135 // _PySys_UpdateConfig() modifies sys.flags in-place:
3136 // Py_XDECREF() is needed in this case.
3137 Py_ssize_t pos = 0;
3138 #define SetFlagObj(expr) \
3139 do { \
3140 PyObject *value = (expr); \
3141 if (value == NULL) { \
3142 return -1; \
3143 } \
3144 Py_XDECREF(PyStructSequence_GET_ITEM(flags, pos)); \
3145 PyStructSequence_SET_ITEM(flags, pos, value); \
3146 pos++; \
3147 } while (0)
3148 #define SetFlag(expr) SetFlagObj(PyLong_FromLong(expr))
3149
3150 SetFlag(config->parser_debug);
3151 SetFlag(config->inspect);
3152 SetFlag(config->interactive);
3153 SetFlag(config->optimization_level);
3154 SetFlag(!config->write_bytecode);
3155 SetFlag(!config->user_site_directory);
3156 SetFlag(!config->site_import);
3157 SetFlag(!config->use_environment);
3158 SetFlag(config->verbose);
3159 SetFlag(config->bytes_warning);
3160 SetFlag(config->quiet);
3161 SetFlag(config->use_hash_seed == 0 || config->hash_seed != 0);
3162 SetFlag(config->isolated);
3163 SetFlagObj(PyBool_FromLong(config->dev_mode));
3164 SetFlag(preconfig->utf8_mode);
3165 SetFlag(config->warn_default_encoding);
3166 SetFlagObj(PyBool_FromLong(config->safe_path));
3167 SetFlag(config->int_max_str_digits);
3168 #ifdef Py_GIL_DISABLED
3169 if (config->enable_gil == _PyConfig_GIL_DEFAULT) {
3170 SetFlagObj(Py_NewRef(Py_None));
3171 }
3172 else {
3173 SetFlag(config->enable_gil);
3174 }
3175 #else
3176 SetFlagObj(PyLong_FromLong(1));
3177 #endif
3178 #undef SetFlagObj
3179 #undef SetFlag
3180 return 0;
3181 }
3182
3183
3184 static PyObject*
make_flags(PyInterpreterState * interp)3185 make_flags(PyInterpreterState *interp)
3186 {
3187 PyObject *flags = PyStructSequence_New(&FlagsType);
3188 if (flags == NULL) {
3189 return NULL;
3190 }
3191
3192 if (set_flags_from_config(interp, flags) < 0) {
3193 Py_DECREF(flags);
3194 return NULL;
3195 }
3196 return flags;
3197 }
3198
3199
3200 PyDoc_STRVAR(version_info__doc__,
3201 "sys.version_info\n\
3202 \n\
3203 Version information as a named tuple.");
3204
3205 static PyTypeObject VersionInfoType;
3206
3207 static PyStructSequence_Field version_info_fields[] = {
3208 {"major", "Major release number"},
3209 {"minor", "Minor release number"},
3210 {"micro", "Patch release number"},
3211 {"releaselevel", "'alpha', 'beta', 'candidate', or 'final'"},
3212 {"serial", "Serial release number"},
3213 {0}
3214 };
3215
3216 static PyStructSequence_Desc version_info_desc = {
3217 "sys.version_info", /* name */
3218 version_info__doc__, /* doc */
3219 version_info_fields, /* fields */
3220 5
3221 };
3222
3223 static PyObject *
make_version_info(PyThreadState * tstate)3224 make_version_info(PyThreadState *tstate)
3225 {
3226 PyObject *version_info;
3227 char *s;
3228 int pos = 0;
3229
3230 version_info = PyStructSequence_New(&VersionInfoType);
3231 if (version_info == NULL) {
3232 return NULL;
3233 }
3234
3235 /*
3236 * These release level checks are mutually exclusive and cover
3237 * the field, so don't get too fancy with the pre-processor!
3238 */
3239 #if PY_RELEASE_LEVEL == PY_RELEASE_LEVEL_ALPHA
3240 s = "alpha";
3241 #elif PY_RELEASE_LEVEL == PY_RELEASE_LEVEL_BETA
3242 s = "beta";
3243 #elif PY_RELEASE_LEVEL == PY_RELEASE_LEVEL_GAMMA
3244 s = "candidate";
3245 #elif PY_RELEASE_LEVEL == PY_RELEASE_LEVEL_FINAL
3246 s = "final";
3247 #endif
3248
3249 #define SetIntItem(flag) \
3250 PyStructSequence_SET_ITEM(version_info, pos++, PyLong_FromLong(flag))
3251 #define SetStrItem(flag) \
3252 PyStructSequence_SET_ITEM(version_info, pos++, PyUnicode_FromString(flag))
3253
3254 SetIntItem(PY_MAJOR_VERSION);
3255 SetIntItem(PY_MINOR_VERSION);
3256 SetIntItem(PY_MICRO_VERSION);
3257 SetStrItem(s);
3258 SetIntItem(PY_RELEASE_SERIAL);
3259 #undef SetIntItem
3260 #undef SetStrItem
3261
3262 if (_PyErr_Occurred(tstate)) {
3263 Py_CLEAR(version_info);
3264 return NULL;
3265 }
3266 return version_info;
3267 }
3268
3269 /* sys.implementation values */
3270 #define NAME "cpython"
3271 const char *_PySys_ImplName = NAME;
3272 #define MAJOR Py_STRINGIFY(PY_MAJOR_VERSION)
3273 #define MINOR Py_STRINGIFY(PY_MINOR_VERSION)
3274 #define TAG NAME "-" MAJOR MINOR
3275 const char *_PySys_ImplCacheTag = TAG;
3276 #undef NAME
3277 #undef MAJOR
3278 #undef MINOR
3279 #undef TAG
3280
3281 static PyObject *
make_impl_info(PyObject * version_info)3282 make_impl_info(PyObject *version_info)
3283 {
3284 int res;
3285 PyObject *impl_info, *value, *ns;
3286
3287 impl_info = PyDict_New();
3288 if (impl_info == NULL)
3289 return NULL;
3290
3291 /* populate the dict */
3292
3293 value = PyUnicode_FromString(_PySys_ImplName);
3294 if (value == NULL)
3295 goto error;
3296 res = PyDict_SetItemString(impl_info, "name", value);
3297 Py_DECREF(value);
3298 if (res < 0)
3299 goto error;
3300
3301 value = PyUnicode_FromString(_PySys_ImplCacheTag);
3302 if (value == NULL)
3303 goto error;
3304 res = PyDict_SetItemString(impl_info, "cache_tag", value);
3305 Py_DECREF(value);
3306 if (res < 0)
3307 goto error;
3308
3309 res = PyDict_SetItemString(impl_info, "version", version_info);
3310 if (res < 0)
3311 goto error;
3312
3313 value = PyLong_FromLong(PY_VERSION_HEX);
3314 if (value == NULL)
3315 goto error;
3316 res = PyDict_SetItemString(impl_info, "hexversion", value);
3317 Py_DECREF(value);
3318 if (res < 0)
3319 goto error;
3320
3321 #ifdef MULTIARCH
3322 value = PyUnicode_FromString(MULTIARCH);
3323 if (value == NULL)
3324 goto error;
3325 res = PyDict_SetItemString(impl_info, "_multiarch", value);
3326 Py_DECREF(value);
3327 if (res < 0)
3328 goto error;
3329 #endif
3330
3331 /* dict ready */
3332
3333 ns = _PyNamespace_New(impl_info);
3334 Py_DECREF(impl_info);
3335 return ns;
3336
3337 error:
3338 Py_CLEAR(impl_info);
3339 return NULL;
3340 }
3341
3342 #ifdef __EMSCRIPTEN__
3343
3344 PyDoc_STRVAR(emscripten_info__doc__,
3345 "sys._emscripten_info\n\
3346 \n\
3347 WebAssembly Emscripten platform information.");
3348
3349 static PyTypeObject *EmscriptenInfoType;
3350
3351 static PyStructSequence_Field emscripten_info_fields[] = {
3352 {"emscripten_version", "Emscripten version (major, minor, micro)"},
3353 {"runtime", "Runtime (Node.JS version, browser user agent)"},
3354 {"pthreads", "pthread support"},
3355 {"shared_memory", "shared memory support"},
3356 {0}
3357 };
3358
3359 static PyStructSequence_Desc emscripten_info_desc = {
3360 "sys._emscripten_info", /* name */
3361 emscripten_info__doc__ , /* doc */
3362 emscripten_info_fields, /* fields */
3363 4
3364 };
3365
3366 EM_JS(char *, _Py_emscripten_runtime, (void), {
3367 var info;
3368 if (typeof navigator == 'object') {
3369 info = navigator.userAgent;
3370 } else if (typeof process == 'object') {
3371 info = "Node.js ".concat(process.version);
3372 } else {
3373 info = "UNKNOWN";
3374 }
3375 var len = lengthBytesUTF8(info) + 1;
3376 var res = _malloc(len);
3377 if (res) stringToUTF8(info, res, len);
3378 #if __wasm64__
3379 return BigInt(res);
3380 #else
3381 return res;
3382 #endif
3383 });
3384
3385 static PyObject *
make_emscripten_info(void)3386 make_emscripten_info(void)
3387 {
3388 PyObject *emscripten_info = NULL;
3389 PyObject *version = NULL;
3390 char *ua;
3391 int pos = 0;
3392
3393 emscripten_info = PyStructSequence_New(EmscriptenInfoType);
3394 if (emscripten_info == NULL) {
3395 return NULL;
3396 }
3397
3398 version = Py_BuildValue("(iii)",
3399 __EMSCRIPTEN_major__, __EMSCRIPTEN_minor__, __EMSCRIPTEN_tiny__);
3400 if (version == NULL) {
3401 goto error;
3402 }
3403 PyStructSequence_SET_ITEM(emscripten_info, pos++, version);
3404
3405 ua = _Py_emscripten_runtime();
3406 if (ua != NULL) {
3407 PyObject *oua = PyUnicode_DecodeUTF8(ua, strlen(ua), "strict");
3408 free(ua);
3409 if (oua == NULL) {
3410 goto error;
3411 }
3412 PyStructSequence_SET_ITEM(emscripten_info, pos++, oua);
3413 } else {
3414 PyStructSequence_SET_ITEM(emscripten_info, pos++, Py_NewRef(Py_None));
3415 }
3416
3417 #define SetBoolItem(flag) \
3418 PyStructSequence_SET_ITEM(emscripten_info, pos++, PyBool_FromLong(flag))
3419
3420 #ifdef __EMSCRIPTEN_PTHREADS__
3421 SetBoolItem(1);
3422 #else
3423 SetBoolItem(0);
3424 #endif
3425
3426 #ifdef __EMSCRIPTEN_SHARED_MEMORY__
3427 SetBoolItem(1);
3428 #else
3429 SetBoolItem(0);
3430 #endif
3431
3432 #undef SetBoolItem
3433
3434 if (PyErr_Occurred()) {
3435 goto error;
3436 }
3437 return emscripten_info;
3438
3439 error:
3440 Py_CLEAR(emscripten_info);
3441 return NULL;
3442 }
3443
3444 #endif // __EMSCRIPTEN__
3445
3446 static struct PyModuleDef sysmodule = {
3447 PyModuleDef_HEAD_INIT,
3448 "sys",
3449 sys_doc,
3450 -1, /* multiple "initialization" just copies the module dict. */
3451 sys_methods,
3452 NULL,
3453 NULL,
3454 NULL,
3455 NULL
3456 };
3457
3458 /* Updating the sys namespace, returning NULL pointer on error */
3459 #define SET_SYS(key, value) \
3460 do { \
3461 PyObject *v = (value); \
3462 if (v == NULL) { \
3463 goto err_occurred; \
3464 } \
3465 res = PyDict_SetItemString(sysdict, key, v); \
3466 Py_DECREF(v); \
3467 if (res < 0) { \
3468 goto err_occurred; \
3469 } \
3470 } while (0)
3471
3472 #define SET_SYS_FROM_STRING(key, value) \
3473 SET_SYS(key, PyUnicode_FromString(value))
3474
3475 static PyStatus
_PySys_InitCore(PyThreadState * tstate,PyObject * sysdict)3476 _PySys_InitCore(PyThreadState *tstate, PyObject *sysdict)
3477 {
3478 PyObject *version_info;
3479 int res;
3480 PyInterpreterState *interp = tstate->interp;
3481
3482 /* stdin/stdout/stderr are set in pylifecycle.c */
3483
3484 #define COPY_SYS_ATTR(tokey, fromkey) \
3485 SET_SYS(tokey, PyMapping_GetItemString(sysdict, fromkey))
3486
3487 COPY_SYS_ATTR("__displayhook__", "displayhook");
3488 COPY_SYS_ATTR("__excepthook__", "excepthook");
3489 COPY_SYS_ATTR("__breakpointhook__", "breakpointhook");
3490 COPY_SYS_ATTR("__unraisablehook__", "unraisablehook");
3491
3492 #undef COPY_SYS_ATTR
3493
3494 SET_SYS_FROM_STRING("version", Py_GetVersion());
3495 SET_SYS("hexversion", PyLong_FromLong(PY_VERSION_HEX));
3496 SET_SYS("_git", Py_BuildValue("(szz)", "CPython", _Py_gitidentifier(),
3497 _Py_gitversion()));
3498 SET_SYS_FROM_STRING("_framework", _PYTHONFRAMEWORK);
3499 SET_SYS("api_version", PyLong_FromLong(PYTHON_API_VERSION));
3500 SET_SYS_FROM_STRING("copyright", Py_GetCopyright());
3501 SET_SYS_FROM_STRING("platform", Py_GetPlatform());
3502 SET_SYS("maxsize", PyLong_FromSsize_t(PY_SSIZE_T_MAX));
3503 SET_SYS("float_info", PyFloat_GetInfo());
3504 SET_SYS("int_info", PyLong_GetInfo());
3505 /* initialize hash_info */
3506 if (_PyStructSequence_InitBuiltin(interp, &Hash_InfoType,
3507 &hash_info_desc) < 0)
3508 {
3509 goto type_init_failed;
3510 }
3511 SET_SYS("hash_info", get_hash_info(tstate));
3512 SET_SYS("maxunicode", PyLong_FromLong(0x10FFFF));
3513 SET_SYS("builtin_module_names", list_builtin_module_names());
3514 SET_SYS("stdlib_module_names", list_stdlib_module_names());
3515 #if PY_BIG_ENDIAN
3516 SET_SYS_FROM_STRING("byteorder", "big");
3517 #else
3518 SET_SYS_FROM_STRING("byteorder", "little");
3519 #endif
3520
3521 #ifdef MS_COREDLL
3522 SET_SYS("dllhandle", PyLong_FromVoidPtr(PyWin_DLLhModule));
3523 SET_SYS_FROM_STRING("winver", PyWin_DLLVersionString);
3524 #endif
3525 #ifdef ABIFLAGS
3526 SET_SYS_FROM_STRING("abiflags", ABIFLAGS);
3527 #endif
3528
3529 #define ENSURE_INFO_TYPE(TYPE, DESC) \
3530 do { \
3531 if (_PyStructSequence_InitBuiltinWithFlags( \
3532 interp, &TYPE, &DESC, Py_TPFLAGS_DISALLOW_INSTANTIATION) < 0) { \
3533 goto type_init_failed; \
3534 } \
3535 } while (0)
3536
3537 /* version_info */
3538 ENSURE_INFO_TYPE(VersionInfoType, version_info_desc);
3539 version_info = make_version_info(tstate);
3540 SET_SYS("version_info", version_info);
3541
3542 /* implementation */
3543 SET_SYS("implementation", make_impl_info(version_info));
3544
3545 // sys.flags: updated in-place later by _PySys_UpdateConfig()
3546 ENSURE_INFO_TYPE(FlagsType, flags_desc);
3547 SET_SYS("flags", make_flags(tstate->interp));
3548
3549 #if defined(MS_WINDOWS)
3550 /* getwindowsversion */
3551 ENSURE_INFO_TYPE(WindowsVersionType, windows_version_desc);
3552
3553 SET_SYS_FROM_STRING("_vpath", VPATH);
3554 #endif
3555
3556 #undef ENSURE_INFO_TYPE
3557
3558 /* float repr style: 0.03 (short) vs 0.029999999999999999 (legacy) */
3559 #if _PY_SHORT_FLOAT_REPR == 1
3560 SET_SYS_FROM_STRING("float_repr_style", "short");
3561 #else
3562 SET_SYS_FROM_STRING("float_repr_style", "legacy");
3563 #endif
3564
3565 SET_SYS("thread_info", PyThread_GetInfo());
3566
3567 /* initialize asyncgen_hooks */
3568 if (_PyStructSequence_InitBuiltin(interp, &AsyncGenHooksType,
3569 &asyncgen_hooks_desc) < 0)
3570 {
3571 goto type_init_failed;
3572 }
3573
3574 #ifdef __EMSCRIPTEN__
3575 if (EmscriptenInfoType == NULL) {
3576 EmscriptenInfoType = PyStructSequence_NewType(&emscripten_info_desc);
3577 if (EmscriptenInfoType == NULL) {
3578 goto type_init_failed;
3579 }
3580 }
3581 SET_SYS("_emscripten_info", make_emscripten_info());
3582 #endif
3583
3584 /* adding sys.path_hooks and sys.path_importer_cache */
3585 SET_SYS("meta_path", PyList_New(0));
3586 SET_SYS("path_importer_cache", PyDict_New());
3587 SET_SYS("path_hooks", PyList_New(0));
3588
3589 if (_PyErr_Occurred(tstate)) {
3590 goto err_occurred;
3591 }
3592 return _PyStatus_OK();
3593
3594 type_init_failed:
3595 return _PyStatus_ERR("failed to initialize a type");
3596
3597 err_occurred:
3598 return _PyStatus_ERR("can't initialize sys module");
3599 }
3600
3601 static int
sys_add_xoption(PyObject * opts,const wchar_t * s)3602 sys_add_xoption(PyObject *opts, const wchar_t *s)
3603 {
3604 PyObject *name, *value = NULL;
3605
3606 const wchar_t *name_end = wcschr(s, L'=');
3607 if (!name_end) {
3608 name = PyUnicode_FromWideChar(s, -1);
3609 if (name == NULL) {
3610 goto error;
3611 }
3612 value = Py_NewRef(Py_True);
3613 }
3614 else {
3615 name = PyUnicode_FromWideChar(s, name_end - s);
3616 if (name == NULL) {
3617 goto error;
3618 }
3619 value = PyUnicode_FromWideChar(name_end + 1, -1);
3620 if (value == NULL) {
3621 goto error;
3622 }
3623 }
3624 if (PyDict_SetItem(opts, name, value) < 0) {
3625 goto error;
3626 }
3627 Py_DECREF(name);
3628 Py_DECREF(value);
3629 return 0;
3630
3631 error:
3632 Py_XDECREF(name);
3633 Py_XDECREF(value);
3634 return -1;
3635 }
3636
3637
3638 static PyObject*
sys_create_xoptions_dict(const PyConfig * config)3639 sys_create_xoptions_dict(const PyConfig *config)
3640 {
3641 Py_ssize_t nxoption = config->xoptions.length;
3642 wchar_t * const * xoptions = config->xoptions.items;
3643 PyObject *dict = PyDict_New();
3644 if (dict == NULL) {
3645 return NULL;
3646 }
3647
3648 for (Py_ssize_t i=0; i < nxoption; i++) {
3649 const wchar_t *option = xoptions[i];
3650 if (sys_add_xoption(dict, option) < 0) {
3651 Py_DECREF(dict);
3652 return NULL;
3653 }
3654 }
3655
3656 return dict;
3657 }
3658
3659
3660 // Update sys attributes for a new PyConfig configuration.
3661 // This function also adds attributes that _PySys_InitCore() didn't add.
3662 int
_PySys_UpdateConfig(PyThreadState * tstate)3663 _PySys_UpdateConfig(PyThreadState *tstate)
3664 {
3665 PyInterpreterState *interp = tstate->interp;
3666 PyObject *sysdict = interp->sysdict;
3667 const PyConfig *config = _PyInterpreterState_GetConfig(interp);
3668 int res;
3669
3670 #define COPY_LIST(KEY, VALUE) \
3671 SET_SYS(KEY, _PyWideStringList_AsList(&(VALUE)));
3672
3673 #define SET_SYS_FROM_WSTR(KEY, VALUE) \
3674 SET_SYS(KEY, PyUnicode_FromWideChar(VALUE, -1));
3675
3676 #define COPY_WSTR(SYS_ATTR, WSTR) \
3677 if (WSTR != NULL) { \
3678 SET_SYS_FROM_WSTR(SYS_ATTR, WSTR); \
3679 }
3680
3681 if (config->module_search_paths_set) {
3682 COPY_LIST("path", config->module_search_paths);
3683 }
3684
3685 COPY_WSTR("executable", config->executable);
3686 COPY_WSTR("_base_executable", config->base_executable);
3687 COPY_WSTR("prefix", config->prefix);
3688 COPY_WSTR("base_prefix", config->base_prefix);
3689 COPY_WSTR("exec_prefix", config->exec_prefix);
3690 COPY_WSTR("base_exec_prefix", config->base_exec_prefix);
3691 COPY_WSTR("platlibdir", config->platlibdir);
3692
3693 if (config->pycache_prefix != NULL) {
3694 SET_SYS_FROM_WSTR("pycache_prefix", config->pycache_prefix);
3695 } else {
3696 if (PyDict_SetItemString(sysdict, "pycache_prefix", Py_None) < 0) {
3697 return -1;
3698 }
3699 }
3700
3701 COPY_LIST("argv", config->argv);
3702 COPY_LIST("orig_argv", config->orig_argv);
3703 COPY_LIST("warnoptions", config->warnoptions);
3704
3705 SET_SYS("_xoptions", sys_create_xoptions_dict(config));
3706
3707 const wchar_t *stdlibdir = _Py_GetStdlibDir();
3708 if (stdlibdir != NULL) {
3709 SET_SYS_FROM_WSTR("_stdlib_dir", stdlibdir);
3710 }
3711 else {
3712 if (PyDict_SetItemString(sysdict, "_stdlib_dir", Py_None) < 0) {
3713 return -1;
3714 }
3715 }
3716
3717 #undef SET_SYS_FROM_WSTR
3718 #undef COPY_LIST
3719 #undef COPY_WSTR
3720
3721 // sys.flags
3722 PyObject *flags = _PySys_GetObject(interp, "flags"); // borrowed ref
3723 if (flags == NULL) {
3724 if (!_PyErr_Occurred(tstate)) {
3725 _PyErr_SetString(tstate, PyExc_RuntimeError, "lost sys.flags");
3726 }
3727 return -1;
3728 }
3729 if (set_flags_from_config(interp, flags) < 0) {
3730 return -1;
3731 }
3732
3733 SET_SYS("dont_write_bytecode", PyBool_FromLong(!config->write_bytecode));
3734
3735 if (_PyErr_Occurred(tstate)) {
3736 goto err_occurred;
3737 }
3738
3739 return 0;
3740
3741 err_occurred:
3742 return -1;
3743 }
3744
3745 #undef SET_SYS
3746 #undef SET_SYS_FROM_STRING
3747
3748
3749 /* Set up a preliminary stderr printer until we have enough
3750 infrastructure for the io module in place.
3751
3752 Use UTF-8/backslashreplace and ignore EAGAIN errors. */
3753 static PyStatus
_PySys_SetPreliminaryStderr(PyObject * sysdict)3754 _PySys_SetPreliminaryStderr(PyObject *sysdict)
3755 {
3756 PyObject *pstderr = PyFile_NewStdPrinter(fileno(stderr));
3757 if (pstderr == NULL) {
3758 goto error;
3759 }
3760 if (PyDict_SetItem(sysdict, &_Py_ID(stderr), pstderr) < 0) {
3761 goto error;
3762 }
3763 if (PyDict_SetItemString(sysdict, "__stderr__", pstderr) < 0) {
3764 goto error;
3765 }
3766 Py_DECREF(pstderr);
3767 return _PyStatus_OK();
3768
3769 error:
3770 Py_XDECREF(pstderr);
3771 return _PyStatus_ERR("can't set preliminary stderr");
3772 }
3773
3774 PyObject *_Py_CreateMonitoringObject(void);
3775
3776 /* Create sys module without all attributes.
3777 _PySys_UpdateConfig() should be called later to add remaining attributes. */
3778 PyStatus
_PySys_Create(PyThreadState * tstate,PyObject ** sysmod_p)3779 _PySys_Create(PyThreadState *tstate, PyObject **sysmod_p)
3780 {
3781 assert(!_PyErr_Occurred(tstate));
3782
3783 PyInterpreterState *interp = tstate->interp;
3784
3785 PyObject *modules = _PyImport_InitModules(interp);
3786 if (modules == NULL) {
3787 goto error;
3788 }
3789
3790 PyObject *sysmod = _PyModule_CreateInitialized(&sysmodule, PYTHON_API_VERSION);
3791 if (sysmod == NULL) {
3792 return _PyStatus_ERR("failed to create a module object");
3793 }
3794 #ifdef Py_GIL_DISABLED
3795 PyUnstable_Module_SetGIL(sysmod, Py_MOD_GIL_NOT_USED);
3796 #endif
3797
3798 PyObject *sysdict = PyModule_GetDict(sysmod);
3799 if (sysdict == NULL) {
3800 goto error;
3801 }
3802 interp->sysdict = Py_NewRef(sysdict);
3803
3804 interp->sysdict_copy = PyDict_Copy(sysdict);
3805 if (interp->sysdict_copy == NULL) {
3806 goto error;
3807 }
3808
3809 if (PyDict_SetItemString(sysdict, "modules", modules) < 0) {
3810 goto error;
3811 }
3812
3813 PyStatus status = _PySys_SetPreliminaryStderr(sysdict);
3814 if (_PyStatus_EXCEPTION(status)) {
3815 return status;
3816 }
3817
3818 status = _PySys_InitCore(tstate, sysdict);
3819 if (_PyStatus_EXCEPTION(status)) {
3820 return status;
3821 }
3822
3823 if (_PyImport_FixupBuiltin(tstate, sysmod, "sys", modules) < 0) {
3824 goto error;
3825 }
3826
3827 PyObject *monitoring = _Py_CreateMonitoringObject();
3828 if (monitoring == NULL) {
3829 goto error;
3830 }
3831 int err = PyDict_SetItemString(sysdict, "monitoring", monitoring);
3832 Py_DECREF(monitoring);
3833 if (err < 0) {
3834 goto error;
3835 }
3836
3837 assert(!_PyErr_Occurred(tstate));
3838
3839 *sysmod_p = sysmod;
3840 return _PyStatus_OK();
3841
3842 error:
3843 return _PyStatus_ERR("can't initialize sys module");
3844 }
3845
3846
3847 void
_PySys_FiniTypes(PyInterpreterState * interp)3848 _PySys_FiniTypes(PyInterpreterState *interp)
3849 {
3850 _PyStructSequence_FiniBuiltin(interp, &VersionInfoType);
3851 _PyStructSequence_FiniBuiltin(interp, &FlagsType);
3852 #if defined(MS_WINDOWS)
3853 _PyStructSequence_FiniBuiltin(interp, &WindowsVersionType);
3854 #endif
3855 _PyStructSequence_FiniBuiltin(interp, &Hash_InfoType);
3856 _PyStructSequence_FiniBuiltin(interp, &AsyncGenHooksType);
3857 #ifdef __EMSCRIPTEN__
3858 if (_Py_IsMainInterpreter(interp)) {
3859 Py_CLEAR(EmscriptenInfoType);
3860 }
3861 #endif
3862 }
3863
3864
3865 static PyObject *
makepathobject(const wchar_t * path,wchar_t delim)3866 makepathobject(const wchar_t *path, wchar_t delim)
3867 {
3868 int i, n;
3869 const wchar_t *p;
3870 PyObject *v, *w;
3871
3872 n = 1;
3873 p = path;
3874 while ((p = wcschr(p, delim)) != NULL) {
3875 n++;
3876 p++;
3877 }
3878 v = PyList_New(n);
3879 if (v == NULL)
3880 return NULL;
3881 for (i = 0; ; i++) {
3882 p = wcschr(path, delim);
3883 if (p == NULL)
3884 p = path + wcslen(path); /* End of string */
3885 w = PyUnicode_FromWideChar(path, (Py_ssize_t)(p - path));
3886 if (w == NULL) {
3887 Py_DECREF(v);
3888 return NULL;
3889 }
3890 PyList_SET_ITEM(v, i, w);
3891 if (*p == '\0')
3892 break;
3893 path = p+1;
3894 }
3895 return v;
3896 }
3897
3898 // Removed in Python 3.13 API, but kept for the stable ABI
3899 PyAPI_FUNC(void)
PySys_SetPath(const wchar_t * path)3900 PySys_SetPath(const wchar_t *path)
3901 {
3902 PyObject *v;
3903 if ((v = makepathobject(path, DELIM)) == NULL)
3904 Py_FatalError("can't create sys.path");
3905 PyInterpreterState *interp = _PyInterpreterState_GET();
3906 if (sys_set_object(interp, &_Py_ID(path), v) != 0) {
3907 Py_FatalError("can't assign sys.path");
3908 }
3909 Py_DECREF(v);
3910 }
3911
3912 static PyObject *
make_sys_argv(int argc,wchar_t * const * argv)3913 make_sys_argv(int argc, wchar_t * const * argv)
3914 {
3915 PyObject *list = PyList_New(argc);
3916 if (list == NULL) {
3917 return NULL;
3918 }
3919
3920 for (Py_ssize_t i = 0; i < argc; i++) {
3921 PyObject *v = PyUnicode_FromWideChar(argv[i], -1);
3922 if (v == NULL) {
3923 Py_DECREF(list);
3924 return NULL;
3925 }
3926 PyList_SET_ITEM(list, i, v);
3927 }
3928 return list;
3929 }
3930
3931 void
PySys_SetArgvEx(int argc,wchar_t ** argv,int updatepath)3932 PySys_SetArgvEx(int argc, wchar_t **argv, int updatepath)
3933 {
3934 wchar_t* empty_argv[1] = {L""};
3935 PyThreadState *tstate = _PyThreadState_GET();
3936
3937 if (argc < 1 || argv == NULL) {
3938 /* Ensure at least one (empty) argument is seen */
3939 argv = empty_argv;
3940 argc = 1;
3941 }
3942
3943 PyObject *av = make_sys_argv(argc, argv);
3944 if (av == NULL) {
3945 Py_FatalError("no mem for sys.argv");
3946 }
3947 if (sys_set_object_str(tstate->interp, "argv", av) != 0) {
3948 Py_DECREF(av);
3949 Py_FatalError("can't assign sys.argv");
3950 }
3951 Py_DECREF(av);
3952
3953 if (updatepath) {
3954 /* If argv[0] is not '-c' nor '-m', prepend argv[0] to sys.path.
3955 If argv[0] is a symlink, use the real path. */
3956 const PyWideStringList argv_list = {.length = argc, .items = argv};
3957 PyObject *path0 = NULL;
3958 if (_PyPathConfig_ComputeSysPath0(&argv_list, &path0)) {
3959 if (path0 == NULL) {
3960 Py_FatalError("can't compute path0 from argv");
3961 }
3962
3963 PyObject *sys_path = _PySys_GetAttr(tstate, &_Py_ID(path));
3964 if (sys_path != NULL) {
3965 if (PyList_Insert(sys_path, 0, path0) < 0) {
3966 Py_DECREF(path0);
3967 Py_FatalError("can't prepend path0 to sys.path");
3968 }
3969 }
3970 Py_DECREF(path0);
3971 }
3972 }
3973 }
3974
3975 void
PySys_SetArgv(int argc,wchar_t ** argv)3976 PySys_SetArgv(int argc, wchar_t **argv)
3977 {
3978 _Py_COMP_DIAG_PUSH
3979 _Py_COMP_DIAG_IGNORE_DEPR_DECLS
3980 PySys_SetArgvEx(argc, argv, Py_IsolatedFlag == 0);
3981 _Py_COMP_DIAG_POP
3982 }
3983
3984 /* Reimplementation of PyFile_WriteString() no calling indirectly
3985 PyErr_CheckSignals(): avoid the call to PyObject_Str(). */
3986
3987 static int
sys_pyfile_write_unicode(PyObject * unicode,PyObject * file)3988 sys_pyfile_write_unicode(PyObject *unicode, PyObject *file)
3989 {
3990 if (file == NULL)
3991 return -1;
3992 assert(unicode != NULL);
3993 PyObject *result = PyObject_CallMethodOneArg(file, &_Py_ID(write), unicode);
3994 if (result == NULL) {
3995 return -1;
3996 }
3997 Py_DECREF(result);
3998 return 0;
3999 }
4000
4001 static int
sys_pyfile_write(const char * text,PyObject * file)4002 sys_pyfile_write(const char *text, PyObject *file)
4003 {
4004 PyObject *unicode = NULL;
4005 int err;
4006
4007 if (file == NULL)
4008 return -1;
4009
4010 unicode = PyUnicode_FromString(text);
4011 if (unicode == NULL)
4012 return -1;
4013
4014 err = sys_pyfile_write_unicode(unicode, file);
4015 Py_DECREF(unicode);
4016 return err;
4017 }
4018
4019 /* APIs to write to sys.stdout or sys.stderr using a printf-like interface.
4020 Adapted from code submitted by Just van Rossum.
4021
4022 PySys_WriteStdout(format, ...)
4023 PySys_WriteStderr(format, ...)
4024
4025 The first function writes to sys.stdout; the second to sys.stderr. When
4026 there is a problem, they write to the real (C level) stdout or stderr;
4027 no exceptions are raised.
4028
4029 PyErr_CheckSignals() is not called to avoid the execution of the Python
4030 signal handlers: they may raise a new exception whereas sys_write()
4031 ignores all exceptions.
4032
4033 Both take a printf-style format string as their first argument followed
4034 by a variable length argument list determined by the format string.
4035
4036 *** WARNING ***
4037
4038 The format should limit the total size of the formatted output string to
4039 1000 bytes. In particular, this means that no unrestricted "%s" formats
4040 should occur; these should be limited using "%.<N>s where <N> is a
4041 decimal number calculated so that <N> plus the maximum size of other
4042 formatted text does not exceed 1000 bytes. Also watch out for "%f",
4043 which can print hundreds of digits for very large numbers.
4044
4045 */
4046
4047 static void
sys_write(PyObject * key,FILE * fp,const char * format,va_list va)4048 sys_write(PyObject *key, FILE *fp, const char *format, va_list va)
4049 {
4050 PyObject *file;
4051 char buffer[1001];
4052 int written;
4053 PyThreadState *tstate = _PyThreadState_GET();
4054
4055 PyObject *exc = _PyErr_GetRaisedException(tstate);
4056 file = _PySys_GetAttr(tstate, key);
4057 written = PyOS_vsnprintf(buffer, sizeof(buffer), format, va);
4058 if (sys_pyfile_write(buffer, file) != 0) {
4059 _PyErr_Clear(tstate);
4060 fputs(buffer, fp);
4061 }
4062 if (written < 0 || (size_t)written >= sizeof(buffer)) {
4063 const char *truncated = "... truncated";
4064 if (sys_pyfile_write(truncated, file) != 0)
4065 fputs(truncated, fp);
4066 }
4067 _PyErr_SetRaisedException(tstate, exc);
4068 }
4069
4070 void
PySys_WriteStdout(const char * format,...)4071 PySys_WriteStdout(const char *format, ...)
4072 {
4073 va_list va;
4074
4075 va_start(va, format);
4076 sys_write(&_Py_ID(stdout), stdout, format, va);
4077 va_end(va);
4078 }
4079
4080 void
PySys_WriteStderr(const char * format,...)4081 PySys_WriteStderr(const char *format, ...)
4082 {
4083 va_list va;
4084
4085 va_start(va, format);
4086 sys_write(&_Py_ID(stderr), stderr, format, va);
4087 va_end(va);
4088 }
4089
4090 static void
sys_format(PyObject * key,FILE * fp,const char * format,va_list va)4091 sys_format(PyObject *key, FILE *fp, const char *format, va_list va)
4092 {
4093 PyObject *file, *message;
4094 const char *utf8;
4095 PyThreadState *tstate = _PyThreadState_GET();
4096
4097 PyObject *exc = _PyErr_GetRaisedException(tstate);
4098 file = _PySys_GetAttr(tstate, key);
4099 message = PyUnicode_FromFormatV(format, va);
4100 if (message != NULL) {
4101 if (sys_pyfile_write_unicode(message, file) != 0) {
4102 _PyErr_Clear(tstate);
4103 utf8 = PyUnicode_AsUTF8(message);
4104 if (utf8 != NULL)
4105 fputs(utf8, fp);
4106 }
4107 Py_DECREF(message);
4108 }
4109 _PyErr_SetRaisedException(tstate, exc);
4110 }
4111
4112 void
PySys_FormatStdout(const char * format,...)4113 PySys_FormatStdout(const char *format, ...)
4114 {
4115 va_list va;
4116
4117 va_start(va, format);
4118 sys_format(&_Py_ID(stdout), stdout, format, va);
4119 va_end(va);
4120 }
4121
4122 void
PySys_FormatStderr(const char * format,...)4123 PySys_FormatStderr(const char *format, ...)
4124 {
4125 va_list va;
4126
4127 va_start(va, format);
4128 sys_format(&_Py_ID(stderr), stderr, format, va);
4129 va_end(va);
4130 }
4131