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 "code.h"
19 #include "frameobject.h"
20 #include "pycore_initconfig.h"
21 #include "pycore_pylifecycle.h"
22 #include "pycore_pymem.h"
23 #include "pycore_pathconfig.h"
24 #include "pycore_pystate.h"
25 #include "pycore_tupleobject.h"
26 #include "pycore_long.h" // _PY_LONG_MAX_STR_DIGITS_THRESHOLD
27 #include "pythread.h"
28 #include "pydtrace.h"
29
30 #include "osdefs.h"
31 #include <locale.h>
32
33 #ifdef MS_WINDOWS
34 #define WIN32_LEAN_AND_MEAN
35 #include <windows.h>
36 #endif /* MS_WINDOWS */
37
38 #ifdef MS_COREDLL
39 extern void *PyWin_DLLhModule;
40 /* A string loaded from the DLL at startup: */
41 extern const char *PyWin_DLLVersionString;
42 #endif
43
44 /*[clinic input]
45 module sys
46 [clinic start generated code]*/
47 /*[clinic end generated code: output=da39a3ee5e6b4b0d input=3726b388feee8cea]*/
48
49 #include "clinic/sysmodule.c.h"
50
51 _Py_IDENTIFIER(_);
52 _Py_IDENTIFIER(__sizeof__);
53 _Py_IDENTIFIER(_xoptions);
54 _Py_IDENTIFIER(buffer);
55 _Py_IDENTIFIER(builtins);
56 _Py_IDENTIFIER(encoding);
57 _Py_IDENTIFIER(path);
58 _Py_IDENTIFIER(stdout);
59 _Py_IDENTIFIER(stderr);
60 _Py_IDENTIFIER(warnoptions);
61 _Py_IDENTIFIER(write);
62
63 PyObject *
_PySys_GetObjectId(_Py_Identifier * key)64 _PySys_GetObjectId(_Py_Identifier *key)
65 {
66 PyObject *sd = _PyInterpreterState_GET_UNSAFE()->sysdict;
67 if (sd == NULL) {
68 return NULL;
69 }
70 return _PyDict_GetItemId(sd, key);
71 }
72
73 PyObject *
PySys_GetObject(const char * name)74 PySys_GetObject(const char *name)
75 {
76 PyObject *sd = _PyInterpreterState_GET_UNSAFE()->sysdict;
77 if (sd == NULL) {
78 return NULL;
79 }
80 return PyDict_GetItemString(sd, name);
81 }
82
83 int
_PySys_SetObjectId(_Py_Identifier * key,PyObject * v)84 _PySys_SetObjectId(_Py_Identifier *key, PyObject *v)
85 {
86 PyObject *sd = _PyInterpreterState_GET_UNSAFE()->sysdict;
87 if (v == NULL) {
88 if (_PyDict_GetItemId(sd, key) == NULL) {
89 return 0;
90 }
91 else {
92 return _PyDict_DelItemId(sd, key);
93 }
94 }
95 else {
96 return _PyDict_SetItemId(sd, key, v);
97 }
98 }
99
100 int
PySys_SetObject(const char * name,PyObject * v)101 PySys_SetObject(const char *name, PyObject *v)
102 {
103 PyObject *sd = _PyInterpreterState_GET_UNSAFE()->sysdict;
104 if (v == NULL) {
105 if (PyDict_GetItemString(sd, name) == NULL) {
106 return 0;
107 }
108 else {
109 return PyDict_DelItemString(sd, name);
110 }
111 }
112 else {
113 return PyDict_SetItemString(sd, name, v);
114 }
115 }
116
117 static int
should_audit(void)118 should_audit(void)
119 {
120 PyThreadState *ts = _PyThreadState_GET();
121 if (!ts) {
122 return 0;
123 }
124 PyInterpreterState *is = ts ? ts->interp : NULL;
125 return _PyRuntime.audit_hook_head
126 || (is && is->audit_hooks)
127 || PyDTrace_AUDIT_ENABLED();
128 }
129
130 int
PySys_Audit(const char * event,const char * argFormat,...)131 PySys_Audit(const char *event, const char *argFormat, ...)
132 {
133 PyObject *eventName = NULL;
134 PyObject *eventArgs = NULL;
135 PyObject *hooks = NULL;
136 PyObject *hook = NULL;
137 int res = -1;
138
139 /* N format is inappropriate, because you do not know
140 whether the reference is consumed by the call.
141 Assert rather than exception for perf reasons */
142 assert(!argFormat || !strchr(argFormat, 'N'));
143
144 /* Early exit when no hooks are registered */
145 if (!should_audit()) {
146 return 0;
147 }
148
149 _Py_AuditHookEntry *e = _PyRuntime.audit_hook_head;
150 PyThreadState *ts = _PyThreadState_GET();
151 PyInterpreterState *is = ts ? ts->interp : NULL;
152 int dtrace = PyDTrace_AUDIT_ENABLED();
153
154 PyObject *exc_type, *exc_value, *exc_tb;
155 if (ts) {
156 PyErr_Fetch(&exc_type, &exc_value, &exc_tb);
157 }
158
159 /* Initialize event args now */
160 if (argFormat && argFormat[0]) {
161 va_list args;
162 va_start(args, argFormat);
163 eventArgs = _Py_VaBuildValue_SizeT(argFormat, args);
164 va_end(args);
165 if (eventArgs && !PyTuple_Check(eventArgs)) {
166 PyObject *argTuple = PyTuple_Pack(1, eventArgs);
167 Py_DECREF(eventArgs);
168 eventArgs = argTuple;
169 }
170 } else {
171 eventArgs = PyTuple_New(0);
172 }
173 if (!eventArgs) {
174 goto exit;
175 }
176
177 /* Call global hooks */
178 for (; e; e = e->next) {
179 if (e->hookCFunction(event, eventArgs, e->userData) < 0) {
180 goto exit;
181 }
182 }
183
184 /* Dtrace USDT point */
185 if (dtrace) {
186 PyDTrace_AUDIT(event, (void *)eventArgs);
187 }
188
189 /* Call interpreter hooks */
190 if (is && is->audit_hooks) {
191 eventName = PyUnicode_FromString(event);
192 if (!eventName) {
193 goto exit;
194 }
195
196 hooks = PyObject_GetIter(is->audit_hooks);
197 if (!hooks) {
198 goto exit;
199 }
200
201 /* Disallow tracing in hooks unless explicitly enabled */
202 ts->tracing++;
203 ts->use_tracing = 0;
204 while ((hook = PyIter_Next(hooks)) != NULL) {
205 _Py_IDENTIFIER(__cantrace__);
206 PyObject *o;
207 int canTrace = _PyObject_LookupAttrId(hook, &PyId___cantrace__, &o);
208 if (o) {
209 canTrace = PyObject_IsTrue(o);
210 Py_DECREF(o);
211 }
212 if (canTrace < 0) {
213 break;
214 }
215 if (canTrace) {
216 ts->use_tracing = (ts->c_tracefunc || ts->c_profilefunc);
217 ts->tracing--;
218 }
219 o = PyObject_CallFunctionObjArgs(hook, eventName,
220 eventArgs, NULL);
221 if (canTrace) {
222 ts->tracing++;
223 ts->use_tracing = 0;
224 }
225 if (!o) {
226 break;
227 }
228 Py_DECREF(o);
229 Py_CLEAR(hook);
230 }
231 ts->use_tracing = (ts->c_tracefunc || ts->c_profilefunc);
232 ts->tracing--;
233 if (PyErr_Occurred()) {
234 goto exit;
235 }
236 }
237
238 res = 0;
239
240 exit:
241 Py_XDECREF(hook);
242 Py_XDECREF(hooks);
243 Py_XDECREF(eventName);
244 Py_XDECREF(eventArgs);
245
246 if (ts) {
247 if (!res) {
248 PyErr_Restore(exc_type, exc_value, exc_tb);
249 } else {
250 assert(PyErr_Occurred());
251 Py_XDECREF(exc_type);
252 Py_XDECREF(exc_value);
253 Py_XDECREF(exc_tb);
254 }
255 }
256
257 return res;
258 }
259
260 /* We expose this function primarily for our own cleanup during
261 * finalization. In general, it should not need to be called,
262 * and as such it is not defined in any header files.
263 */
_PySys_ClearAuditHooks(void)264 void _PySys_ClearAuditHooks(void) {
265 /* Must be finalizing to clear hooks */
266 _PyRuntimeState *runtime = &_PyRuntime;
267 PyThreadState *ts = _PyRuntimeState_GetThreadState(runtime);
268 assert(!ts || _Py_CURRENTLY_FINALIZING(runtime, ts));
269 if (!ts || !_Py_CURRENTLY_FINALIZING(runtime, ts))
270 return;
271
272 if (Py_VerboseFlag) {
273 PySys_WriteStderr("# clear sys.audit hooks\n");
274 }
275
276 /* Hooks can abort later hooks for this event, but cannot
277 abort the clear operation itself. */
278 PySys_Audit("cpython._PySys_ClearAuditHooks", NULL);
279 PyErr_Clear();
280
281 _Py_AuditHookEntry *e = _PyRuntime.audit_hook_head, *n;
282 _PyRuntime.audit_hook_head = NULL;
283 while (e) {
284 n = e->next;
285 PyMem_RawFree(e);
286 e = n;
287 }
288 }
289
290 int
PySys_AddAuditHook(Py_AuditHookFunction hook,void * userData)291 PySys_AddAuditHook(Py_AuditHookFunction hook, void *userData)
292 {
293 /* Invoke existing audit hooks to allow them an opportunity to abort. */
294 /* Cannot invoke hooks until we are initialized */
295 if (Py_IsInitialized()) {
296 if (PySys_Audit("sys.addaudithook", NULL) < 0) {
297 if (PyErr_ExceptionMatches(PyExc_RuntimeError)) {
298 /* We do not report errors derived from RuntimeError */
299 PyErr_Clear();
300 return 0;
301 }
302 return -1;
303 }
304 }
305
306 _Py_AuditHookEntry *e = _PyRuntime.audit_hook_head;
307 if (!e) {
308 e = (_Py_AuditHookEntry*)PyMem_RawMalloc(sizeof(_Py_AuditHookEntry));
309 _PyRuntime.audit_hook_head = e;
310 } else {
311 while (e->next)
312 e = e->next;
313 e = e->next = (_Py_AuditHookEntry*)PyMem_RawMalloc(
314 sizeof(_Py_AuditHookEntry));
315 }
316
317 if (!e) {
318 if (Py_IsInitialized())
319 PyErr_NoMemory();
320 return -1;
321 }
322
323 e->next = NULL;
324 e->hookCFunction = (Py_AuditHookFunction)hook;
325 e->userData = userData;
326
327 return 0;
328 }
329
330 /*[clinic input]
331 sys.addaudithook
332
333 hook: object
334
335 Adds a new audit hook callback.
336 [clinic start generated code]*/
337
338 static PyObject *
sys_addaudithook_impl(PyObject * module,PyObject * hook)339 sys_addaudithook_impl(PyObject *module, PyObject *hook)
340 /*[clinic end generated code: output=4f9c17aaeb02f44e input=0f3e191217a45e34]*/
341 {
342 /* Invoke existing audit hooks to allow them an opportunity to abort. */
343 if (PySys_Audit("sys.addaudithook", NULL) < 0) {
344 if (PyErr_ExceptionMatches(PyExc_Exception)) {
345 /* We do not report errors derived from Exception */
346 PyErr_Clear();
347 Py_RETURN_NONE;
348 }
349 return NULL;
350 }
351
352 PyInterpreterState *is = _PyInterpreterState_Get();
353
354 if (is->audit_hooks == NULL) {
355 is->audit_hooks = PyList_New(0);
356 if (is->audit_hooks == NULL) {
357 return NULL;
358 }
359 }
360
361 if (PyList_Append(is->audit_hooks, hook) < 0) {
362 return NULL;
363 }
364
365 Py_RETURN_NONE;
366 }
367
368 PyDoc_STRVAR(audit_doc,
369 "audit(event, *args)\n\
370 \n\
371 Passes the event to any audit hooks that are attached.");
372
373 static PyObject *
sys_audit(PyObject * self,PyObject * const * args,Py_ssize_t argc)374 sys_audit(PyObject *self, PyObject *const *args, Py_ssize_t argc)
375 {
376 if (argc == 0) {
377 PyErr_SetString(PyExc_TypeError, "audit() missing 1 required positional argument: 'event'");
378 return NULL;
379 }
380
381 if (!should_audit()) {
382 Py_RETURN_NONE;
383 }
384
385 PyObject *auditEvent = args[0];
386 if (!auditEvent) {
387 PyErr_SetString(PyExc_TypeError, "expected str for argument 'event'");
388 return NULL;
389 }
390 if (!PyUnicode_Check(auditEvent)) {
391 PyErr_Format(PyExc_TypeError, "expected str for argument 'event', not %.200s",
392 Py_TYPE(auditEvent)->tp_name);
393 return NULL;
394 }
395 const char *event = PyUnicode_AsUTF8(auditEvent);
396 if (!event) {
397 return NULL;
398 }
399
400 PyObject *auditArgs = _PyTuple_FromArray(args + 1, argc - 1);
401 if (!auditArgs) {
402 return NULL;
403 }
404
405 int res = PySys_Audit(event, "O", auditArgs);
406 Py_DECREF(auditArgs);
407
408 if (res < 0) {
409 return NULL;
410 }
411
412 Py_RETURN_NONE;
413 }
414
415
416 static PyObject *
sys_breakpointhook(PyObject * self,PyObject * const * args,Py_ssize_t nargs,PyObject * keywords)417 sys_breakpointhook(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *keywords)
418 {
419 assert(!PyErr_Occurred());
420 char *envar = Py_GETENV("PYTHONBREAKPOINT");
421
422 if (envar == NULL || strlen(envar) == 0) {
423 envar = "pdb.set_trace";
424 }
425 else if (!strcmp(envar, "0")) {
426 /* The breakpoint is explicitly no-op'd. */
427 Py_RETURN_NONE;
428 }
429 /* According to POSIX the string returned by getenv() might be invalidated
430 * or the string content might be overwritten by a subsequent call to
431 * getenv(). Since importing a module can performs the getenv() calls,
432 * we need to save a copy of envar. */
433 envar = _PyMem_RawStrdup(envar);
434 if (envar == NULL) {
435 PyErr_NoMemory();
436 return NULL;
437 }
438 const char *last_dot = strrchr(envar, '.');
439 const char *attrname = NULL;
440 PyObject *modulepath = NULL;
441
442 if (last_dot == NULL) {
443 /* The breakpoint is a built-in, e.g. PYTHONBREAKPOINT=int */
444 modulepath = PyUnicode_FromString("builtins");
445 attrname = envar;
446 }
447 else if (last_dot != envar) {
448 /* Split on the last dot; */
449 modulepath = PyUnicode_FromStringAndSize(envar, last_dot - envar);
450 attrname = last_dot + 1;
451 }
452 else {
453 goto warn;
454 }
455 if (modulepath == NULL) {
456 PyMem_RawFree(envar);
457 return NULL;
458 }
459
460 PyObject *module = PyImport_Import(modulepath);
461 Py_DECREF(modulepath);
462
463 if (module == NULL) {
464 if (PyErr_ExceptionMatches(PyExc_ImportError)) {
465 goto warn;
466 }
467 PyMem_RawFree(envar);
468 return NULL;
469 }
470
471 PyObject *hook = PyObject_GetAttrString(module, attrname);
472 Py_DECREF(module);
473
474 if (hook == NULL) {
475 if (PyErr_ExceptionMatches(PyExc_AttributeError)) {
476 goto warn;
477 }
478 PyMem_RawFree(envar);
479 return NULL;
480 }
481 PyMem_RawFree(envar);
482 PyObject *retval = _PyObject_Vectorcall(hook, args, nargs, keywords);
483 Py_DECREF(hook);
484 return retval;
485
486 warn:
487 /* If any of the imports went wrong, then warn and ignore. */
488 PyErr_Clear();
489 int status = PyErr_WarnFormat(
490 PyExc_RuntimeWarning, 0,
491 "Ignoring unimportable $PYTHONBREAKPOINT: \"%s\"", envar);
492 PyMem_RawFree(envar);
493 if (status < 0) {
494 /* Printing the warning raised an exception. */
495 return NULL;
496 }
497 /* The warning was (probably) issued. */
498 Py_RETURN_NONE;
499 }
500
501 PyDoc_STRVAR(breakpointhook_doc,
502 "breakpointhook(*args, **kws)\n"
503 "\n"
504 "This hook function is called by built-in breakpoint().\n"
505 );
506
507 /* Write repr(o) to sys.stdout using sys.stdout.encoding and 'backslashreplace'
508 error handler. If sys.stdout has a buffer attribute, use
509 sys.stdout.buffer.write(encoded), otherwise redecode the string and use
510 sys.stdout.write(redecoded).
511
512 Helper function for sys_displayhook(). */
513 static int
sys_displayhook_unencodable(PyObject * outf,PyObject * o)514 sys_displayhook_unencodable(PyObject *outf, PyObject *o)
515 {
516 PyObject *stdout_encoding = NULL;
517 PyObject *encoded, *escaped_str, *repr_str, *buffer, *result;
518 const char *stdout_encoding_str;
519 int ret;
520
521 stdout_encoding = _PyObject_GetAttrId(outf, &PyId_encoding);
522 if (stdout_encoding == NULL)
523 goto error;
524 stdout_encoding_str = PyUnicode_AsUTF8(stdout_encoding);
525 if (stdout_encoding_str == NULL)
526 goto error;
527
528 repr_str = PyObject_Repr(o);
529 if (repr_str == NULL)
530 goto error;
531 encoded = PyUnicode_AsEncodedString(repr_str,
532 stdout_encoding_str,
533 "backslashreplace");
534 Py_DECREF(repr_str);
535 if (encoded == NULL)
536 goto error;
537
538 if (_PyObject_LookupAttrId(outf, &PyId_buffer, &buffer) < 0) {
539 Py_DECREF(encoded);
540 goto error;
541 }
542 if (buffer) {
543 result = _PyObject_CallMethodIdObjArgs(buffer, &PyId_write, encoded, NULL);
544 Py_DECREF(buffer);
545 Py_DECREF(encoded);
546 if (result == NULL)
547 goto error;
548 Py_DECREF(result);
549 }
550 else {
551 escaped_str = PyUnicode_FromEncodedObject(encoded,
552 stdout_encoding_str,
553 "strict");
554 Py_DECREF(encoded);
555 if (PyFile_WriteObject(escaped_str, outf, Py_PRINT_RAW) != 0) {
556 Py_DECREF(escaped_str);
557 goto error;
558 }
559 Py_DECREF(escaped_str);
560 }
561 ret = 0;
562 goto finally;
563
564 error:
565 ret = -1;
566 finally:
567 Py_XDECREF(stdout_encoding);
568 return ret;
569 }
570
571 /*[clinic input]
572 sys.displayhook
573
574 object as o: object
575 /
576
577 Print an object to sys.stdout and also save it in builtins._
578 [clinic start generated code]*/
579
580 static PyObject *
sys_displayhook(PyObject * module,PyObject * o)581 sys_displayhook(PyObject *module, PyObject *o)
582 /*[clinic end generated code: output=347477d006df92ed input=08ba730166d7ef72]*/
583 {
584 PyObject *outf;
585 PyObject *builtins;
586 static PyObject *newline = NULL;
587 int err;
588
589 builtins = _PyImport_GetModuleId(&PyId_builtins);
590 if (builtins == NULL) {
591 if (!PyErr_Occurred()) {
592 PyErr_SetString(PyExc_RuntimeError, "lost builtins module");
593 }
594 return NULL;
595 }
596 Py_DECREF(builtins);
597
598 /* Print value except if None */
599 /* After printing, also assign to '_' */
600 /* Before, set '_' to None to avoid recursion */
601 if (o == Py_None) {
602 Py_RETURN_NONE;
603 }
604 if (_PyObject_SetAttrId(builtins, &PyId__, Py_None) != 0)
605 return NULL;
606 outf = _PySys_GetObjectId(&PyId_stdout);
607 if (outf == NULL || outf == Py_None) {
608 PyErr_SetString(PyExc_RuntimeError, "lost sys.stdout");
609 return NULL;
610 }
611 if (PyFile_WriteObject(o, outf, 0) != 0) {
612 if (PyErr_ExceptionMatches(PyExc_UnicodeEncodeError)) {
613 /* repr(o) is not encodable to sys.stdout.encoding with
614 * sys.stdout.errors error handler (which is probably 'strict') */
615 PyErr_Clear();
616 err = sys_displayhook_unencodable(outf, o);
617 if (err)
618 return NULL;
619 }
620 else {
621 return NULL;
622 }
623 }
624 if (newline == NULL) {
625 newline = PyUnicode_FromString("\n");
626 if (newline == NULL)
627 return NULL;
628 }
629 if (PyFile_WriteObject(newline, outf, Py_PRINT_RAW) != 0)
630 return NULL;
631 if (_PyObject_SetAttrId(builtins, &PyId__, o) != 0)
632 return NULL;
633 Py_RETURN_NONE;
634 }
635
636
637 /*[clinic input]
638 sys.excepthook
639
640 exctype: object
641 value: object
642 traceback: object
643 /
644
645 Handle an exception by displaying it with a traceback on sys.stderr.
646 [clinic start generated code]*/
647
648 static PyObject *
sys_excepthook_impl(PyObject * module,PyObject * exctype,PyObject * value,PyObject * traceback)649 sys_excepthook_impl(PyObject *module, PyObject *exctype, PyObject *value,
650 PyObject *traceback)
651 /*[clinic end generated code: output=18d99fdda21b6b5e input=ecf606fa826f19d9]*/
652 {
653 PyErr_Display(exctype, value, traceback);
654 Py_RETURN_NONE;
655 }
656
657
658 /*[clinic input]
659 sys.exc_info
660
661 Return current exception information: (type, value, traceback).
662
663 Return information about the most recent exception caught by an except
664 clause in the current stack frame or in an older stack frame.
665 [clinic start generated code]*/
666
667 static PyObject *
sys_exc_info_impl(PyObject * module)668 sys_exc_info_impl(PyObject *module)
669 /*[clinic end generated code: output=3afd0940cf3a4d30 input=b5c5bf077788a3e5]*/
670 {
671 _PyErr_StackItem *err_info = _PyErr_GetTopmostException(_PyThreadState_GET());
672 return Py_BuildValue(
673 "(OOO)",
674 err_info->exc_type != NULL ? err_info->exc_type : Py_None,
675 err_info->exc_value != NULL ? err_info->exc_value : Py_None,
676 err_info->exc_traceback != NULL ?
677 err_info->exc_traceback : Py_None);
678 }
679
680
681 /*[clinic input]
682 sys.unraisablehook
683
684 unraisable: object
685 /
686
687 Handle an unraisable exception.
688
689 The unraisable argument has the following attributes:
690
691 * exc_type: Exception type.
692 * exc_value: Exception value, can be None.
693 * exc_traceback: Exception traceback, can be None.
694 * err_msg: Error message, can be None.
695 * object: Object causing the exception, can be None.
696 [clinic start generated code]*/
697
698 static PyObject *
sys_unraisablehook(PyObject * module,PyObject * unraisable)699 sys_unraisablehook(PyObject *module, PyObject *unraisable)
700 /*[clinic end generated code: output=bb92838b32abaa14 input=ec3af148294af8d3]*/
701 {
702 return _PyErr_WriteUnraisableDefaultHook(unraisable);
703 }
704
705
706 /*[clinic input]
707 sys.exit
708
709 status: object = None
710 /
711
712 Exit the interpreter by raising SystemExit(status).
713
714 If the status is omitted or None, it defaults to zero (i.e., success).
715 If the status is an integer, it will be used as the system exit status.
716 If it is another kind of object, it will be printed and the system
717 exit status will be one (i.e., failure).
718 [clinic start generated code]*/
719
720 static PyObject *
sys_exit_impl(PyObject * module,PyObject * status)721 sys_exit_impl(PyObject *module, PyObject *status)
722 /*[clinic end generated code: output=13870986c1ab2ec0 input=b86ca9497baa94f2]*/
723 {
724 /* Raise SystemExit so callers may catch it or clean up. */
725 PyErr_SetObject(PyExc_SystemExit, status);
726 return NULL;
727 }
728
729
730
731 /*[clinic input]
732 sys.getdefaultencoding
733
734 Return the current default encoding used by the Unicode implementation.
735 [clinic start generated code]*/
736
737 static PyObject *
sys_getdefaultencoding_impl(PyObject * module)738 sys_getdefaultencoding_impl(PyObject *module)
739 /*[clinic end generated code: output=256d19dfcc0711e6 input=d416856ddbef6909]*/
740 {
741 return PyUnicode_FromString(PyUnicode_GetDefaultEncoding());
742 }
743
744 /*[clinic input]
745 sys.getfilesystemencoding
746
747 Return the encoding used to convert Unicode filenames to OS filenames.
748 [clinic start generated code]*/
749
750 static PyObject *
sys_getfilesystemencoding_impl(PyObject * module)751 sys_getfilesystemencoding_impl(PyObject *module)
752 /*[clinic end generated code: output=1dc4bdbe9be44aa7 input=8475f8649b8c7d8c]*/
753 {
754 PyInterpreterState *interp = _PyInterpreterState_GET_UNSAFE();
755 const PyConfig *config = &interp->config;
756 return PyUnicode_FromWideChar(config->filesystem_encoding, -1);
757 }
758
759 /*[clinic input]
760 sys.getfilesystemencodeerrors
761
762 Return the error mode used Unicode to OS filename conversion.
763 [clinic start generated code]*/
764
765 static PyObject *
sys_getfilesystemencodeerrors_impl(PyObject * module)766 sys_getfilesystemencodeerrors_impl(PyObject *module)
767 /*[clinic end generated code: output=ba77b36bbf7c96f5 input=22a1e8365566f1e5]*/
768 {
769 PyInterpreterState *interp = _PyInterpreterState_GET_UNSAFE();
770 const PyConfig *config = &interp->config;
771 return PyUnicode_FromWideChar(config->filesystem_errors, -1);
772 }
773
774 /*[clinic input]
775 sys.intern
776
777 string as s: unicode
778 /
779
780 ``Intern'' the given string.
781
782 This enters the string in the (global) table of interned strings whose
783 purpose is to speed up dictionary lookups. Return the string itself or
784 the previously interned string object with the same value.
785 [clinic start generated code]*/
786
787 static PyObject *
sys_intern_impl(PyObject * module,PyObject * s)788 sys_intern_impl(PyObject *module, PyObject *s)
789 /*[clinic end generated code: output=be680c24f5c9e5d6 input=849483c006924e2f]*/
790 {
791 if (PyUnicode_CheckExact(s)) {
792 Py_INCREF(s);
793 PyUnicode_InternInPlace(&s);
794 return s;
795 }
796 else {
797 PyErr_Format(PyExc_TypeError,
798 "can't intern %.400s", s->ob_type->tp_name);
799 return NULL;
800 }
801 }
802
803
804 /*
805 * Cached interned string objects used for calling the profile and
806 * trace functions. Initialized by trace_init().
807 */
808 static PyObject *whatstrings[8] = {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL};
809
810 static int
trace_init(void)811 trace_init(void)
812 {
813 static const char * const whatnames[8] = {
814 "call", "exception", "line", "return",
815 "c_call", "c_exception", "c_return",
816 "opcode"
817 };
818 PyObject *name;
819 int i;
820 for (i = 0; i < 8; ++i) {
821 if (whatstrings[i] == NULL) {
822 name = PyUnicode_InternFromString(whatnames[i]);
823 if (name == NULL)
824 return -1;
825 whatstrings[i] = name;
826 }
827 }
828 return 0;
829 }
830
831
832 static PyObject *
call_trampoline(PyObject * callback,PyFrameObject * frame,int what,PyObject * arg)833 call_trampoline(PyObject* callback,
834 PyFrameObject *frame, int what, PyObject *arg)
835 {
836 PyObject *result;
837 PyObject *stack[3];
838
839 if (PyFrame_FastToLocalsWithError(frame) < 0) {
840 return NULL;
841 }
842
843 stack[0] = (PyObject *)frame;
844 stack[1] = whatstrings[what];
845 stack[2] = (arg != NULL) ? arg : Py_None;
846
847 /* call the Python-level function */
848 result = _PyObject_FastCall(callback, stack, 3);
849
850 PyFrame_LocalsToFast(frame, 1);
851 if (result == NULL) {
852 PyTraceBack_Here(frame);
853 }
854
855 return result;
856 }
857
858 static int
profile_trampoline(PyObject * self,PyFrameObject * frame,int what,PyObject * arg)859 profile_trampoline(PyObject *self, PyFrameObject *frame,
860 int what, PyObject *arg)
861 {
862 PyObject *result;
863
864 if (arg == NULL)
865 arg = Py_None;
866 result = call_trampoline(self, frame, what, arg);
867 if (result == NULL) {
868 PyEval_SetProfile(NULL, NULL);
869 return -1;
870 }
871 Py_DECREF(result);
872 return 0;
873 }
874
875 static int
trace_trampoline(PyObject * self,PyFrameObject * frame,int what,PyObject * arg)876 trace_trampoline(PyObject *self, PyFrameObject *frame,
877 int what, PyObject *arg)
878 {
879 PyObject *callback;
880 PyObject *result;
881
882 if (what == PyTrace_CALL)
883 callback = self;
884 else
885 callback = frame->f_trace;
886 if (callback == NULL)
887 return 0;
888 result = call_trampoline(callback, frame, what, arg);
889 if (result == NULL) {
890 PyEval_SetTrace(NULL, NULL);
891 Py_CLEAR(frame->f_trace);
892 return -1;
893 }
894 if (result != Py_None) {
895 Py_XSETREF(frame->f_trace, result);
896 }
897 else {
898 Py_DECREF(result);
899 }
900 return 0;
901 }
902
903 static PyObject *
sys_settrace(PyObject * self,PyObject * args)904 sys_settrace(PyObject *self, PyObject *args)
905 {
906 if (trace_init() == -1)
907 return NULL;
908 if (args == Py_None)
909 PyEval_SetTrace(NULL, NULL);
910 else
911 PyEval_SetTrace(trace_trampoline, args);
912 Py_RETURN_NONE;
913 }
914
915 PyDoc_STRVAR(settrace_doc,
916 "settrace(function)\n\
917 \n\
918 Set the global debug tracing function. It will be called on each\n\
919 function call. See the debugger chapter in the library manual."
920 );
921
922 /*[clinic input]
923 sys.gettrace
924
925 Return the global debug tracing function set with sys.settrace.
926
927 See the debugger chapter in the library manual.
928 [clinic start generated code]*/
929
930 static PyObject *
sys_gettrace_impl(PyObject * module)931 sys_gettrace_impl(PyObject *module)
932 /*[clinic end generated code: output=e97e3a4d8c971b6e input=373b51bb2147f4d8]*/
933 {
934 PyThreadState *tstate = _PyThreadState_GET();
935 PyObject *temp = tstate->c_traceobj;
936
937 if (temp == NULL)
938 temp = Py_None;
939 Py_INCREF(temp);
940 return temp;
941 }
942
943 static PyObject *
sys_setprofile(PyObject * self,PyObject * args)944 sys_setprofile(PyObject *self, PyObject *args)
945 {
946 if (trace_init() == -1)
947 return NULL;
948 if (args == Py_None)
949 PyEval_SetProfile(NULL, NULL);
950 else
951 PyEval_SetProfile(profile_trampoline, args);
952 Py_RETURN_NONE;
953 }
954
955 PyDoc_STRVAR(setprofile_doc,
956 "setprofile(function)\n\
957 \n\
958 Set the profiling function. It will be called on each function call\n\
959 and return. See the profiler chapter in the library manual."
960 );
961
962 /*[clinic input]
963 sys.getprofile
964
965 Return the profiling function set with sys.setprofile.
966
967 See the profiler chapter in the library manual.
968 [clinic start generated code]*/
969
970 static PyObject *
sys_getprofile_impl(PyObject * module)971 sys_getprofile_impl(PyObject *module)
972 /*[clinic end generated code: output=579b96b373448188 input=1b3209d89a32965d]*/
973 {
974 PyThreadState *tstate = _PyThreadState_GET();
975 PyObject *temp = tstate->c_profileobj;
976
977 if (temp == NULL)
978 temp = Py_None;
979 Py_INCREF(temp);
980 return temp;
981 }
982
983 /*[clinic input]
984 sys.setcheckinterval
985
986 n: int
987 /
988
989 Set the async event check interval to n instructions.
990
991 This tells the Python interpreter to check for asynchronous events
992 every n instructions.
993
994 This also affects how often thread switches occur.
995 [clinic start generated code]*/
996
997 static PyObject *
sys_setcheckinterval_impl(PyObject * module,int n)998 sys_setcheckinterval_impl(PyObject *module, int n)
999 /*[clinic end generated code: output=3f686cef07e6e178 input=7a35b17bf22a6227]*/
1000 {
1001 if (PyErr_WarnEx(PyExc_DeprecationWarning,
1002 "sys.getcheckinterval() and sys.setcheckinterval() "
1003 "are deprecated. Use sys.setswitchinterval() "
1004 "instead.", 1) < 0)
1005 return NULL;
1006
1007 PyInterpreterState *interp = _PyInterpreterState_Get();
1008 interp->check_interval = n;
1009 Py_RETURN_NONE;
1010 }
1011
1012 /*[clinic input]
1013 sys.getcheckinterval
1014
1015 Return the current check interval; see sys.setcheckinterval().
1016 [clinic start generated code]*/
1017
1018 static PyObject *
sys_getcheckinterval_impl(PyObject * module)1019 sys_getcheckinterval_impl(PyObject *module)
1020 /*[clinic end generated code: output=1b5060bf2b23a47c input=4b6589cbcca1db4e]*/
1021 {
1022 if (PyErr_WarnEx(PyExc_DeprecationWarning,
1023 "sys.getcheckinterval() and sys.setcheckinterval() "
1024 "are deprecated. Use sys.getswitchinterval() "
1025 "instead.", 1) < 0)
1026 return NULL;
1027 PyInterpreterState *interp = _PyInterpreterState_Get();
1028 return PyLong_FromLong(interp->check_interval);
1029 }
1030
1031 /*[clinic input]
1032 sys.setswitchinterval
1033
1034 interval: double
1035 /
1036
1037 Set the ideal thread switching delay inside the Python interpreter.
1038
1039 The actual frequency of switching threads can be lower if the
1040 interpreter executes long sequences of uninterruptible code
1041 (this is implementation-specific and workload-dependent).
1042
1043 The parameter must represent the desired switching delay in seconds
1044 A typical value is 0.005 (5 milliseconds).
1045 [clinic start generated code]*/
1046
1047 static PyObject *
sys_setswitchinterval_impl(PyObject * module,double interval)1048 sys_setswitchinterval_impl(PyObject *module, double interval)
1049 /*[clinic end generated code: output=65a19629e5153983 input=561b477134df91d9]*/
1050 {
1051 if (interval <= 0.0) {
1052 PyErr_SetString(PyExc_ValueError,
1053 "switch interval must be strictly positive");
1054 return NULL;
1055 }
1056 _PyEval_SetSwitchInterval((unsigned long) (1e6 * interval));
1057 Py_RETURN_NONE;
1058 }
1059
1060
1061 /*[clinic input]
1062 sys.getswitchinterval -> double
1063
1064 Return the current thread switch interval; see sys.setswitchinterval().
1065 [clinic start generated code]*/
1066
1067 static double
sys_getswitchinterval_impl(PyObject * module)1068 sys_getswitchinterval_impl(PyObject *module)
1069 /*[clinic end generated code: output=a38c277c85b5096d input=bdf9d39c0ebbbb6f]*/
1070 {
1071 return 1e-6 * _PyEval_GetSwitchInterval();
1072 }
1073
1074 /*[clinic input]
1075 sys.setrecursionlimit
1076
1077 limit as new_limit: int
1078 /
1079
1080 Set the maximum depth of the Python interpreter stack to n.
1081
1082 This limit prevents infinite recursion from causing an overflow of the C
1083 stack and crashing Python. The highest possible limit is platform-
1084 dependent.
1085 [clinic start generated code]*/
1086
1087 static PyObject *
sys_setrecursionlimit_impl(PyObject * module,int new_limit)1088 sys_setrecursionlimit_impl(PyObject *module, int new_limit)
1089 /*[clinic end generated code: output=35e1c64754800ace input=b0f7a23393924af3]*/
1090 {
1091 int mark;
1092 PyThreadState *tstate;
1093
1094 if (new_limit < 1) {
1095 PyErr_SetString(PyExc_ValueError,
1096 "recursion limit must be greater or equal than 1");
1097 return NULL;
1098 }
1099
1100 /* Issue #25274: When the recursion depth hits the recursion limit in
1101 _Py_CheckRecursiveCall(), the overflowed flag of the thread state is
1102 set to 1 and a RecursionError is raised. The overflowed flag is reset
1103 to 0 when the recursion depth goes below the low-water mark: see
1104 Py_LeaveRecursiveCall().
1105
1106 Reject too low new limit if the current recursion depth is higher than
1107 the new low-water mark. Otherwise it may not be possible anymore to
1108 reset the overflowed flag to 0. */
1109 mark = _Py_RecursionLimitLowerWaterMark(new_limit);
1110 tstate = _PyThreadState_GET();
1111 if (tstate->recursion_depth >= mark) {
1112 PyErr_Format(PyExc_RecursionError,
1113 "cannot set the recursion limit to %i at "
1114 "the recursion depth %i: the limit is too low",
1115 new_limit, tstate->recursion_depth);
1116 return NULL;
1117 }
1118
1119 Py_SetRecursionLimit(new_limit);
1120 Py_RETURN_NONE;
1121 }
1122
1123 /*[clinic input]
1124 sys.set_coroutine_origin_tracking_depth
1125
1126 depth: int
1127
1128 Enable or disable origin tracking for coroutine objects in this thread.
1129
1130 Coroutine objects will track 'depth' frames of traceback information
1131 about where they came from, available in their cr_origin attribute.
1132
1133 Set a depth of 0 to disable.
1134 [clinic start generated code]*/
1135
1136 static PyObject *
sys_set_coroutine_origin_tracking_depth_impl(PyObject * module,int depth)1137 sys_set_coroutine_origin_tracking_depth_impl(PyObject *module, int depth)
1138 /*[clinic end generated code: output=0a2123c1cc6759c5 input=a1d0a05f89d2c426]*/
1139 {
1140 if (depth < 0) {
1141 PyErr_SetString(PyExc_ValueError, "depth must be >= 0");
1142 return NULL;
1143 }
1144 _PyEval_SetCoroutineOriginTrackingDepth(depth);
1145 Py_RETURN_NONE;
1146 }
1147
1148 /*[clinic input]
1149 sys.get_coroutine_origin_tracking_depth -> int
1150
1151 Check status of origin tracking for coroutine objects in this thread.
1152 [clinic start generated code]*/
1153
1154 static int
sys_get_coroutine_origin_tracking_depth_impl(PyObject * module)1155 sys_get_coroutine_origin_tracking_depth_impl(PyObject *module)
1156 /*[clinic end generated code: output=3699f7be95a3afb8 input=335266a71205b61a]*/
1157 {
1158 return _PyEval_GetCoroutineOriginTrackingDepth();
1159 }
1160
1161 static PyTypeObject AsyncGenHooksType;
1162
1163 PyDoc_STRVAR(asyncgen_hooks_doc,
1164 "asyncgen_hooks\n\
1165 \n\
1166 A named tuple providing information about asynchronous\n\
1167 generators hooks. The attributes are read only.");
1168
1169 static PyStructSequence_Field asyncgen_hooks_fields[] = {
1170 {"firstiter", "Hook to intercept first iteration"},
1171 {"finalizer", "Hook to intercept finalization"},
1172 {0}
1173 };
1174
1175 static PyStructSequence_Desc asyncgen_hooks_desc = {
1176 "asyncgen_hooks", /* name */
1177 asyncgen_hooks_doc, /* doc */
1178 asyncgen_hooks_fields , /* fields */
1179 2
1180 };
1181
1182 static int
set_async_gen_firstiter(PyObject * firstiter)1183 set_async_gen_firstiter(PyObject *firstiter)
1184 {
1185 PyThreadState *tstate = _PyThreadState_GET();
1186
1187 if (PySys_Audit("sys.set_asyncgen_hook_firstiter", NULL) < 0) {
1188 return -1;
1189 }
1190
1191 Py_XINCREF(firstiter);
1192 Py_XSETREF(tstate->async_gen_firstiter, firstiter);
1193 return 0;
1194 }
1195
1196 void
_PyEval_SetAsyncGenFirstiter(PyObject * firstiter)1197 _PyEval_SetAsyncGenFirstiter(PyObject *firstiter)
1198 {
1199 if (set_async_gen_firstiter(firstiter) < 0) {
1200 PyErr_WriteUnraisable(NULL);
1201 }
1202 }
1203
1204 static int
set_async_gen_finalizer(PyObject * finalizer)1205 set_async_gen_finalizer(PyObject *finalizer)
1206 {
1207 PyThreadState *tstate = _PyThreadState_GET();
1208
1209 if (PySys_Audit("sys.set_asyncgen_hook_finalizer", NULL) < 0) {
1210 return -1;
1211 }
1212
1213 Py_XINCREF(finalizer);
1214 Py_XSETREF(tstate->async_gen_finalizer, finalizer);
1215 return 0;
1216 }
1217
1218 void
_PyEval_SetAsyncGenFinalizer(PyObject * finalizer)1219 _PyEval_SetAsyncGenFinalizer(PyObject *finalizer)
1220 {
1221 if (set_async_gen_finalizer(finalizer) < 0) {
1222 PyErr_WriteUnraisable(NULL);
1223 }
1224 }
1225
1226
1227 static PyObject *
sys_set_asyncgen_hooks(PyObject * self,PyObject * args,PyObject * kw)1228 sys_set_asyncgen_hooks(PyObject *self, PyObject *args, PyObject *kw)
1229 {
1230 static char *keywords[] = {"firstiter", "finalizer", NULL};
1231 PyObject *firstiter = NULL;
1232 PyObject *finalizer = NULL;
1233
1234 if (!PyArg_ParseTupleAndKeywords(
1235 args, kw, "|OO", keywords,
1236 &firstiter, &finalizer)) {
1237 return NULL;
1238 }
1239
1240 if (finalizer && finalizer != Py_None) {
1241 if (!PyCallable_Check(finalizer)) {
1242 PyErr_Format(PyExc_TypeError,
1243 "callable finalizer expected, got %.50s",
1244 Py_TYPE(finalizer)->tp_name);
1245 return NULL;
1246 }
1247 if (set_async_gen_finalizer(finalizer) < 0) {
1248 return NULL;
1249 }
1250 }
1251 else if (finalizer == Py_None && set_async_gen_finalizer(NULL) < 0) {
1252 return NULL;
1253 }
1254
1255 if (firstiter && firstiter != Py_None) {
1256 if (!PyCallable_Check(firstiter)) {
1257 PyErr_Format(PyExc_TypeError,
1258 "callable firstiter expected, got %.50s",
1259 Py_TYPE(firstiter)->tp_name);
1260 return NULL;
1261 }
1262 if (set_async_gen_firstiter(firstiter) < 0) {
1263 return NULL;
1264 }
1265 }
1266 else if (firstiter == Py_None && set_async_gen_firstiter(NULL) < 0) {
1267 return NULL;
1268 }
1269
1270 Py_RETURN_NONE;
1271 }
1272
1273 PyDoc_STRVAR(set_asyncgen_hooks_doc,
1274 "set_asyncgen_hooks(* [, firstiter] [, finalizer])\n\
1275 \n\
1276 Set a finalizer for async generators objects."
1277 );
1278
1279 /*[clinic input]
1280 sys.get_asyncgen_hooks
1281
1282 Return the installed asynchronous generators hooks.
1283
1284 This returns a namedtuple of the form (firstiter, finalizer).
1285 [clinic start generated code]*/
1286
1287 static PyObject *
sys_get_asyncgen_hooks_impl(PyObject * module)1288 sys_get_asyncgen_hooks_impl(PyObject *module)
1289 /*[clinic end generated code: output=53a253707146f6cf input=3676b9ea62b14625]*/
1290 {
1291 PyObject *res;
1292 PyObject *firstiter = _PyEval_GetAsyncGenFirstiter();
1293 PyObject *finalizer = _PyEval_GetAsyncGenFinalizer();
1294
1295 res = PyStructSequence_New(&AsyncGenHooksType);
1296 if (res == NULL) {
1297 return NULL;
1298 }
1299
1300 if (firstiter == NULL) {
1301 firstiter = Py_None;
1302 }
1303
1304 if (finalizer == NULL) {
1305 finalizer = Py_None;
1306 }
1307
1308 Py_INCREF(firstiter);
1309 PyStructSequence_SET_ITEM(res, 0, firstiter);
1310
1311 Py_INCREF(finalizer);
1312 PyStructSequence_SET_ITEM(res, 1, finalizer);
1313
1314 return res;
1315 }
1316
1317
1318 static PyTypeObject Hash_InfoType;
1319
1320 PyDoc_STRVAR(hash_info_doc,
1321 "hash_info\n\
1322 \n\
1323 A named tuple providing parameters used for computing\n\
1324 hashes. The attributes are read only.");
1325
1326 static PyStructSequence_Field hash_info_fields[] = {
1327 {"width", "width of the type used for hashing, in bits"},
1328 {"modulus", "prime number giving the modulus on which the hash "
1329 "function is based"},
1330 {"inf", "value to be used for hash of a positive infinity"},
1331 {"nan", "value to be used for hash of a nan"},
1332 {"imag", "multiplier used for the imaginary part of a complex number"},
1333 {"algorithm", "name of the algorithm for hashing of str, bytes and "
1334 "memoryviews"},
1335 {"hash_bits", "internal output size of hash algorithm"},
1336 {"seed_bits", "seed size of hash algorithm"},
1337 {"cutoff", "small string optimization cutoff"},
1338 {NULL, NULL}
1339 };
1340
1341 static PyStructSequence_Desc hash_info_desc = {
1342 "sys.hash_info",
1343 hash_info_doc,
1344 hash_info_fields,
1345 9,
1346 };
1347
1348 static PyObject *
get_hash_info(void)1349 get_hash_info(void)
1350 {
1351 PyObject *hash_info;
1352 int field = 0;
1353 PyHash_FuncDef *hashfunc;
1354 hash_info = PyStructSequence_New(&Hash_InfoType);
1355 if (hash_info == NULL)
1356 return NULL;
1357 hashfunc = PyHash_GetFuncDef();
1358 PyStructSequence_SET_ITEM(hash_info, field++,
1359 PyLong_FromLong(8*sizeof(Py_hash_t)));
1360 PyStructSequence_SET_ITEM(hash_info, field++,
1361 PyLong_FromSsize_t(_PyHASH_MODULUS));
1362 PyStructSequence_SET_ITEM(hash_info, field++,
1363 PyLong_FromLong(_PyHASH_INF));
1364 PyStructSequence_SET_ITEM(hash_info, field++,
1365 PyLong_FromLong(_PyHASH_NAN));
1366 PyStructSequence_SET_ITEM(hash_info, field++,
1367 PyLong_FromLong(_PyHASH_IMAG));
1368 PyStructSequence_SET_ITEM(hash_info, field++,
1369 PyUnicode_FromString(hashfunc->name));
1370 PyStructSequence_SET_ITEM(hash_info, field++,
1371 PyLong_FromLong(hashfunc->hash_bits));
1372 PyStructSequence_SET_ITEM(hash_info, field++,
1373 PyLong_FromLong(hashfunc->seed_bits));
1374 PyStructSequence_SET_ITEM(hash_info, field++,
1375 PyLong_FromLong(Py_HASH_CUTOFF));
1376 if (PyErr_Occurred()) {
1377 Py_CLEAR(hash_info);
1378 return NULL;
1379 }
1380 return hash_info;
1381 }
1382 /*[clinic input]
1383 sys.getrecursionlimit
1384
1385 Return the current value of the recursion limit.
1386
1387 The recursion limit is the maximum depth of the Python interpreter
1388 stack. This limit prevents infinite recursion from causing an overflow
1389 of the C stack and crashing Python.
1390 [clinic start generated code]*/
1391
1392 static PyObject *
sys_getrecursionlimit_impl(PyObject * module)1393 sys_getrecursionlimit_impl(PyObject *module)
1394 /*[clinic end generated code: output=d571fb6b4549ef2e input=1c6129fd2efaeea8]*/
1395 {
1396 return PyLong_FromLong(Py_GetRecursionLimit());
1397 }
1398
1399 #ifdef MS_WINDOWS
1400
1401 static PyTypeObject WindowsVersionType = {0, 0, 0, 0, 0, 0};
1402
1403 static PyStructSequence_Field windows_version_fields[] = {
1404 {"major", "Major version number"},
1405 {"minor", "Minor version number"},
1406 {"build", "Build number"},
1407 {"platform", "Operating system platform"},
1408 {"service_pack", "Latest Service Pack installed on the system"},
1409 {"service_pack_major", "Service Pack major version number"},
1410 {"service_pack_minor", "Service Pack minor version number"},
1411 {"suite_mask", "Bit mask identifying available product suites"},
1412 {"product_type", "System product type"},
1413 {"platform_version", "Diagnostic version number"},
1414 {0}
1415 };
1416
1417 static PyStructSequence_Desc windows_version_desc = {
1418 "sys.getwindowsversion", /* name */
1419 sys_getwindowsversion__doc__, /* doc */
1420 windows_version_fields, /* fields */
1421 5 /* For backward compatibility,
1422 only the first 5 items are accessible
1423 via indexing, the rest are name only */
1424 };
1425
1426 /* Disable deprecation warnings about GetVersionEx as the result is
1427 being passed straight through to the caller, who is responsible for
1428 using it correctly. */
1429 #pragma warning(push)
1430 #pragma warning(disable:4996)
1431
1432 /*[clinic input]
1433 sys.getwindowsversion
1434
1435 Return info about the running version of Windows as a named tuple.
1436
1437 The members are named: major, minor, build, platform, service_pack,
1438 service_pack_major, service_pack_minor, suite_mask, product_type and
1439 platform_version. For backward compatibility, only the first 5 items
1440 are available by indexing. All elements are numbers, except
1441 service_pack and platform_type which are strings, and platform_version
1442 which is a 3-tuple. Platform is always 2. Product_type may be 1 for a
1443 workstation, 2 for a domain controller, 3 for a server.
1444 Platform_version is a 3-tuple containing a version number that is
1445 intended for identifying the OS rather than feature detection.
1446 [clinic start generated code]*/
1447
1448 static PyObject *
sys_getwindowsversion_impl(PyObject * module)1449 sys_getwindowsversion_impl(PyObject *module)
1450 /*[clinic end generated code: output=1ec063280b932857 input=73a228a328fee63a]*/
1451 {
1452 PyObject *version;
1453 int pos = 0;
1454 OSVERSIONINFOEXW ver;
1455 DWORD realMajor, realMinor, realBuild;
1456 HANDLE hKernel32;
1457 wchar_t kernel32_path[MAX_PATH];
1458 LPVOID verblock;
1459 DWORD verblock_size;
1460
1461 ver.dwOSVersionInfoSize = sizeof(ver);
1462 if (!GetVersionExW((OSVERSIONINFOW*) &ver))
1463 return PyErr_SetFromWindowsErr(0);
1464
1465 version = PyStructSequence_New(&WindowsVersionType);
1466 if (version == NULL)
1467 return NULL;
1468
1469 PyStructSequence_SET_ITEM(version, pos++, PyLong_FromLong(ver.dwMajorVersion));
1470 PyStructSequence_SET_ITEM(version, pos++, PyLong_FromLong(ver.dwMinorVersion));
1471 PyStructSequence_SET_ITEM(version, pos++, PyLong_FromLong(ver.dwBuildNumber));
1472 PyStructSequence_SET_ITEM(version, pos++, PyLong_FromLong(ver.dwPlatformId));
1473 PyStructSequence_SET_ITEM(version, pos++, PyUnicode_FromWideChar(ver.szCSDVersion, -1));
1474 PyStructSequence_SET_ITEM(version, pos++, PyLong_FromLong(ver.wServicePackMajor));
1475 PyStructSequence_SET_ITEM(version, pos++, PyLong_FromLong(ver.wServicePackMinor));
1476 PyStructSequence_SET_ITEM(version, pos++, PyLong_FromLong(ver.wSuiteMask));
1477 PyStructSequence_SET_ITEM(version, pos++, PyLong_FromLong(ver.wProductType));
1478
1479 realMajor = ver.dwMajorVersion;
1480 realMinor = ver.dwMinorVersion;
1481 realBuild = ver.dwBuildNumber;
1482
1483 // GetVersion will lie if we are running in a compatibility mode.
1484 // We need to read the version info from a system file resource
1485 // to accurately identify the OS version. If we fail for any reason,
1486 // just return whatever GetVersion said.
1487 Py_BEGIN_ALLOW_THREADS
1488 hKernel32 = GetModuleHandleW(L"kernel32.dll");
1489 Py_END_ALLOW_THREADS
1490 if (hKernel32 && GetModuleFileNameW(hKernel32, kernel32_path, MAX_PATH) &&
1491 (verblock_size = GetFileVersionInfoSizeW(kernel32_path, NULL)) &&
1492 (verblock = PyMem_RawMalloc(verblock_size))) {
1493 VS_FIXEDFILEINFO *ffi;
1494 UINT ffi_len;
1495
1496 if (GetFileVersionInfoW(kernel32_path, 0, verblock_size, verblock) &&
1497 VerQueryValueW(verblock, L"", (LPVOID)&ffi, &ffi_len)) {
1498 realMajor = HIWORD(ffi->dwProductVersionMS);
1499 realMinor = LOWORD(ffi->dwProductVersionMS);
1500 realBuild = HIWORD(ffi->dwProductVersionLS);
1501 }
1502 PyMem_RawFree(verblock);
1503 }
1504 PyStructSequence_SET_ITEM(version, pos++, Py_BuildValue("(kkk)",
1505 realMajor,
1506 realMinor,
1507 realBuild
1508 ));
1509
1510 if (PyErr_Occurred()) {
1511 Py_DECREF(version);
1512 return NULL;
1513 }
1514
1515 return version;
1516 }
1517
1518 #pragma warning(pop)
1519
1520 /*[clinic input]
1521 sys._enablelegacywindowsfsencoding
1522
1523 Changes the default filesystem encoding to mbcs:replace.
1524
1525 This is done for consistency with earlier versions of Python. See PEP
1526 529 for more information.
1527
1528 This is equivalent to defining the PYTHONLEGACYWINDOWSFSENCODING
1529 environment variable before launching Python.
1530 [clinic start generated code]*/
1531
1532 static PyObject *
sys__enablelegacywindowsfsencoding_impl(PyObject * module)1533 sys__enablelegacywindowsfsencoding_impl(PyObject *module)
1534 /*[clinic end generated code: output=f5c3855b45e24fe9 input=2bfa931a20704492]*/
1535 {
1536 if (_PyUnicode_EnableLegacyWindowsFSEncoding() < 0) {
1537 return NULL;
1538 }
1539 Py_RETURN_NONE;
1540 }
1541
1542 #endif /* MS_WINDOWS */
1543
1544 #ifdef HAVE_DLOPEN
1545
1546 /*[clinic input]
1547 sys.setdlopenflags
1548
1549 flags as new_val: int
1550 /
1551
1552 Set the flags used by the interpreter for dlopen calls.
1553
1554 This is used, for example, when the interpreter loads extension
1555 modules. Among other things, this will enable a lazy resolving of
1556 symbols when importing a module, if called as sys.setdlopenflags(0).
1557 To share symbols across extension modules, call as
1558 sys.setdlopenflags(os.RTLD_GLOBAL). Symbolic names for the flag
1559 modules can be found in the os module (RTLD_xxx constants, e.g.
1560 os.RTLD_LAZY).
1561 [clinic start generated code]*/
1562
1563 static PyObject *
sys_setdlopenflags_impl(PyObject * module,int new_val)1564 sys_setdlopenflags_impl(PyObject *module, int new_val)
1565 /*[clinic end generated code: output=ec918b7fe0a37281 input=4c838211e857a77f]*/
1566 {
1567 PyInterpreterState *interp = _PyInterpreterState_Get();
1568 interp->dlopenflags = new_val;
1569 Py_RETURN_NONE;
1570 }
1571
1572
1573 /*[clinic input]
1574 sys.getdlopenflags
1575
1576 Return the current value of the flags that are used for dlopen calls.
1577
1578 The flag constants are defined in the os module.
1579 [clinic start generated code]*/
1580
1581 static PyObject *
sys_getdlopenflags_impl(PyObject * module)1582 sys_getdlopenflags_impl(PyObject *module)
1583 /*[clinic end generated code: output=e92cd1bc5005da6e input=dc4ea0899c53b4b6]*/
1584 {
1585 PyInterpreterState *interp = _PyInterpreterState_Get();
1586 return PyLong_FromLong(interp->dlopenflags);
1587 }
1588
1589 #endif /* HAVE_DLOPEN */
1590
1591 #ifdef USE_MALLOPT
1592 /* Link with -lmalloc (or -lmpc) on an SGI */
1593 #include <malloc.h>
1594
1595 /*[clinic input]
1596 sys.mdebug
1597
1598 flag: int
1599 /
1600 [clinic start generated code]*/
1601
1602 static PyObject *
sys_mdebug_impl(PyObject * module,int flag)1603 sys_mdebug_impl(PyObject *module, int flag)
1604 /*[clinic end generated code: output=5431d545847c3637 input=151d150ae1636f8a]*/
1605 {
1606 int flag;
1607 mallopt(M_DEBUG, flag);
1608 Py_RETURN_NONE;
1609 }
1610 #endif /* USE_MALLOPT */
1611
1612
1613 /*[clinic input]
1614 sys.get_int_max_str_digits
1615
1616 Set the maximum string digits limit for non-binary int<->str conversions.
1617 [clinic start generated code]*/
1618
1619 static PyObject *
sys_get_int_max_str_digits_impl(PyObject * module)1620 sys_get_int_max_str_digits_impl(PyObject *module)
1621 /*[clinic end generated code: output=0042f5e8ae0e8631 input=8dab13e2023e60d5]*/
1622 {
1623 PyInterpreterState *interp = _PyInterpreterState_Get();
1624 return PyLong_FromSsize_t(interp->int_max_str_digits);
1625 }
1626
1627 /*[clinic input]
1628 sys.set_int_max_str_digits
1629
1630 maxdigits: int
1631
1632 Set the maximum string digits limit for non-binary int<->str conversions.
1633 [clinic start generated code]*/
1634
1635 static PyObject *
sys_set_int_max_str_digits_impl(PyObject * module,int maxdigits)1636 sys_set_int_max_str_digits_impl(PyObject *module, int maxdigits)
1637 /*[clinic end generated code: output=734d4c2511f2a56d input=d7e3f325db6910c5]*/
1638 {
1639 PyInterpreterState *interp = _PyInterpreterState_Get();
1640 if ((!maxdigits) || (maxdigits >= _PY_LONG_MAX_STR_DIGITS_THRESHOLD)) {
1641 interp->int_max_str_digits = maxdigits;
1642 Py_RETURN_NONE;
1643 } else {
1644 PyErr_Format(
1645 PyExc_ValueError, "maxdigits must be 0 or larger than %d",
1646 _PY_LONG_MAX_STR_DIGITS_THRESHOLD);
1647 return NULL;
1648 }
1649 }
1650
1651 size_t
_PySys_GetSizeOf(PyObject * o)1652 _PySys_GetSizeOf(PyObject *o)
1653 {
1654 PyObject *res = NULL;
1655 PyObject *method;
1656 Py_ssize_t size;
1657
1658 /* Make sure the type is initialized. float gets initialized late */
1659 if (PyType_Ready(Py_TYPE(o)) < 0)
1660 return (size_t)-1;
1661
1662 method = _PyObject_LookupSpecial(o, &PyId___sizeof__);
1663 if (method == NULL) {
1664 if (!PyErr_Occurred())
1665 PyErr_Format(PyExc_TypeError,
1666 "Type %.100s doesn't define __sizeof__",
1667 Py_TYPE(o)->tp_name);
1668 }
1669 else {
1670 res = _PyObject_CallNoArg(method);
1671 Py_DECREF(method);
1672 }
1673
1674 if (res == NULL)
1675 return (size_t)-1;
1676
1677 size = PyLong_AsSsize_t(res);
1678 Py_DECREF(res);
1679 if (size == -1 && PyErr_Occurred())
1680 return (size_t)-1;
1681
1682 if (size < 0) {
1683 PyErr_SetString(PyExc_ValueError, "__sizeof__() should return >= 0");
1684 return (size_t)-1;
1685 }
1686
1687 /* add gc_head size */
1688 if (PyObject_IS_GC(o))
1689 return ((size_t)size) + sizeof(PyGC_Head);
1690 return (size_t)size;
1691 }
1692
1693 static PyObject *
sys_getsizeof(PyObject * self,PyObject * args,PyObject * kwds)1694 sys_getsizeof(PyObject *self, PyObject *args, PyObject *kwds)
1695 {
1696 static char *kwlist[] = {"object", "default", 0};
1697 size_t size;
1698 PyObject *o, *dflt = NULL;
1699
1700 if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|O:getsizeof",
1701 kwlist, &o, &dflt))
1702 return NULL;
1703
1704 size = _PySys_GetSizeOf(o);
1705
1706 if (size == (size_t)-1 && PyErr_Occurred()) {
1707 /* Has a default value been given */
1708 if (dflt != NULL && PyErr_ExceptionMatches(PyExc_TypeError)) {
1709 PyErr_Clear();
1710 Py_INCREF(dflt);
1711 return dflt;
1712 }
1713 else
1714 return NULL;
1715 }
1716
1717 return PyLong_FromSize_t(size);
1718 }
1719
1720 PyDoc_STRVAR(getsizeof_doc,
1721 "getsizeof(object [, default]) -> int\n\
1722 \n\
1723 Return the size of object in bytes.");
1724
1725 /*[clinic input]
1726 sys.getrefcount -> Py_ssize_t
1727
1728 object: object
1729 /
1730
1731 Return the reference count of object.
1732
1733 The count returned is generally one higher than you might expect,
1734 because it includes the (temporary) reference as an argument to
1735 getrefcount().
1736 [clinic start generated code]*/
1737
1738 static Py_ssize_t
sys_getrefcount_impl(PyObject * module,PyObject * object)1739 sys_getrefcount_impl(PyObject *module, PyObject *object)
1740 /*[clinic end generated code: output=5fd477f2264b85b2 input=bf474efd50a21535]*/
1741 {
1742 return object->ob_refcnt;
1743 }
1744
1745 #ifdef Py_REF_DEBUG
1746 /*[clinic input]
1747 sys.gettotalrefcount -> Py_ssize_t
1748 [clinic start generated code]*/
1749
1750 static Py_ssize_t
sys_gettotalrefcount_impl(PyObject * module)1751 sys_gettotalrefcount_impl(PyObject *module)
1752 /*[clinic end generated code: output=4103886cf17c25bc input=53b744faa5d2e4f6]*/
1753 {
1754 return _Py_GetRefTotal();
1755 }
1756 #endif /* Py_REF_DEBUG */
1757
1758 /*[clinic input]
1759 sys.getallocatedblocks -> Py_ssize_t
1760
1761 Return the number of memory blocks currently allocated.
1762 [clinic start generated code]*/
1763
1764 static Py_ssize_t
sys_getallocatedblocks_impl(PyObject * module)1765 sys_getallocatedblocks_impl(PyObject *module)
1766 /*[clinic end generated code: output=f0c4e873f0b6dcf7 input=dab13ee346a0673e]*/
1767 {
1768 return _Py_GetAllocatedBlocks();
1769 }
1770
1771 #ifdef COUNT_ALLOCS
1772 /*[clinic input]
1773 sys.getcounts
1774 [clinic start generated code]*/
1775
1776 static PyObject *
sys_getcounts_impl(PyObject * module)1777 sys_getcounts_impl(PyObject *module)
1778 /*[clinic end generated code: output=20df00bc164f43cb input=ad2ec7bda5424953]*/
1779 {
1780 extern PyObject *_Py_get_counts(void);
1781
1782 return _Py_get_counts();
1783 }
1784 #endif
1785
1786 /*[clinic input]
1787 sys._getframe
1788
1789 depth: int = 0
1790 /
1791
1792 Return a frame object from the call stack.
1793
1794 If optional integer depth is given, return the frame object that many
1795 calls below the top of the stack. If that is deeper than the call
1796 stack, ValueError is raised. The default for depth is zero, returning
1797 the frame at the top of the call stack.
1798
1799 This function should be used for internal and specialized purposes
1800 only.
1801 [clinic start generated code]*/
1802
1803 static PyObject *
sys__getframe_impl(PyObject * module,int depth)1804 sys__getframe_impl(PyObject *module, int depth)
1805 /*[clinic end generated code: output=d438776c04d59804 input=c1be8a6464b11ee5]*/
1806 {
1807 PyFrameObject *f = _PyThreadState_GET()->frame;
1808
1809 if (PySys_Audit("sys._getframe", "O", f) < 0) {
1810 return NULL;
1811 }
1812
1813 while (depth > 0 && f != NULL) {
1814 f = f->f_back;
1815 --depth;
1816 }
1817 if (f == NULL) {
1818 PyErr_SetString(PyExc_ValueError,
1819 "call stack is not deep enough");
1820 return NULL;
1821 }
1822 Py_INCREF(f);
1823 return (PyObject*)f;
1824 }
1825
1826 /*[clinic input]
1827 sys._current_frames
1828
1829 Return a dict mapping each thread's thread id to its current stack frame.
1830
1831 This function should be used for specialized purposes only.
1832 [clinic start generated code]*/
1833
1834 static PyObject *
sys__current_frames_impl(PyObject * module)1835 sys__current_frames_impl(PyObject *module)
1836 /*[clinic end generated code: output=d2a41ac0a0a3809a input=2a9049c5f5033691]*/
1837 {
1838 return _PyThread_CurrentFrames();
1839 }
1840
1841 /*[clinic input]
1842 sys.call_tracing
1843
1844 func: object
1845 args as funcargs: object(subclass_of='&PyTuple_Type')
1846 /
1847
1848 Call func(*args), while tracing is enabled.
1849
1850 The tracing state is saved, and restored afterwards. This is intended
1851 to be called from a debugger from a checkpoint, to recursively debug
1852 some other code.
1853 [clinic start generated code]*/
1854
1855 static PyObject *
sys_call_tracing_impl(PyObject * module,PyObject * func,PyObject * funcargs)1856 sys_call_tracing_impl(PyObject *module, PyObject *func, PyObject *funcargs)
1857 /*[clinic end generated code: output=7e4999853cd4e5a6 input=5102e8b11049f92f]*/
1858 {
1859 return _PyEval_CallTracing(func, funcargs);
1860 }
1861
1862 /*[clinic input]
1863 sys.callstats
1864
1865 Return a tuple of function call statistics.
1866
1867 A tuple is returned only if CALL_PROFILE was defined when Python was
1868 built. Otherwise, this returns None.
1869
1870 When enabled, this function returns detailed, implementation-specific
1871 details about the number of function calls executed. The return value
1872 is a 11-tuple where the entries in the tuple are counts of:
1873 0. all function calls
1874 1. calls to PyFunction_Type objects
1875 2. PyFunction calls that do not create an argument tuple
1876 3. PyFunction calls that do not create an argument tuple
1877 and bypass PyEval_EvalCodeEx()
1878 4. PyMethod calls
1879 5. PyMethod calls on bound methods
1880 6. PyType calls
1881 7. PyCFunction calls
1882 8. generator calls
1883 9. All other calls
1884 10. Number of stack pops performed by call_function()
1885 [clinic start generated code]*/
1886
1887 static PyObject *
sys_callstats_impl(PyObject * module)1888 sys_callstats_impl(PyObject *module)
1889 /*[clinic end generated code: output=edc4a74957fa8def input=d447d8d224d5d175]*/
1890 {
1891 if (PyErr_WarnEx(PyExc_DeprecationWarning,
1892 "sys.callstats() has been deprecated in Python 3.7 "
1893 "and will be removed in the future", 1) < 0) {
1894 return NULL;
1895 }
1896
1897 Py_RETURN_NONE;
1898 }
1899
1900
1901 #ifdef __cplusplus
1902 extern "C" {
1903 #endif
1904
1905 /*[clinic input]
1906 sys._debugmallocstats
1907
1908 Print summary info to stderr about the state of pymalloc's structures.
1909
1910 In Py_DEBUG mode, also perform some expensive internal consistency
1911 checks.
1912 [clinic start generated code]*/
1913
1914 static PyObject *
sys__debugmallocstats_impl(PyObject * module)1915 sys__debugmallocstats_impl(PyObject *module)
1916 /*[clinic end generated code: output=ec3565f8c7cee46a input=33c0c9c416f98424]*/
1917 {
1918 #ifdef WITH_PYMALLOC
1919 if (_PyObject_DebugMallocStats(stderr)) {
1920 fputc('\n', stderr);
1921 }
1922 #endif
1923 _PyObject_DebugTypeStats(stderr);
1924
1925 Py_RETURN_NONE;
1926 }
1927
1928 #ifdef Py_TRACE_REFS
1929 /* Defined in objects.c because it uses static globals if that file */
1930 extern PyObject *_Py_GetObjects(PyObject *, PyObject *);
1931 #endif
1932
1933 #ifdef DYNAMIC_EXECUTION_PROFILE
1934 /* Defined in ceval.c because it uses static globals if that file */
1935 extern PyObject *_Py_GetDXProfile(PyObject *, PyObject *);
1936 #endif
1937
1938 #ifdef __cplusplus
1939 }
1940 #endif
1941
1942
1943 /*[clinic input]
1944 sys._clear_type_cache
1945
1946 Clear the internal type lookup cache.
1947 [clinic start generated code]*/
1948
1949 static PyObject *
sys__clear_type_cache_impl(PyObject * module)1950 sys__clear_type_cache_impl(PyObject *module)
1951 /*[clinic end generated code: output=20e48ca54a6f6971 input=127f3e04a8d9b555]*/
1952 {
1953 PyType_ClearCache();
1954 Py_RETURN_NONE;
1955 }
1956
1957 /*[clinic input]
1958 sys.is_finalizing
1959
1960 Return True if Python is exiting.
1961 [clinic start generated code]*/
1962
1963 static PyObject *
sys_is_finalizing_impl(PyObject * module)1964 sys_is_finalizing_impl(PyObject *module)
1965 /*[clinic end generated code: output=735b5ff7962ab281 input=f0df747a039948a5]*/
1966 {
1967 return PyBool_FromLong(_Py_IsFinalizing());
1968 }
1969
1970 #ifdef ANDROID_API_LEVEL
1971 /*[clinic input]
1972 sys.getandroidapilevel
1973
1974 Return the build time API version of Android as an integer.
1975 [clinic start generated code]*/
1976
1977 static PyObject *
sys_getandroidapilevel_impl(PyObject * module)1978 sys_getandroidapilevel_impl(PyObject *module)
1979 /*[clinic end generated code: output=214abf183a1c70c1 input=3e6d6c9fcdd24ac6]*/
1980 {
1981 return PyLong_FromLong(ANDROID_API_LEVEL);
1982 }
1983 #endif /* ANDROID_API_LEVEL */
1984
1985
1986
1987 static PyMethodDef sys_methods[] = {
1988 /* Might as well keep this in alphabetic order */
1989 SYS_ADDAUDITHOOK_METHODDEF
1990 {"audit", (PyCFunction)(void(*)(void))sys_audit, METH_FASTCALL, audit_doc },
1991 {"breakpointhook", (PyCFunction)(void(*)(void))sys_breakpointhook,
1992 METH_FASTCALL | METH_KEYWORDS, breakpointhook_doc},
1993 SYS_CALLSTATS_METHODDEF
1994 SYS__CLEAR_TYPE_CACHE_METHODDEF
1995 SYS__CURRENT_FRAMES_METHODDEF
1996 SYS_DISPLAYHOOK_METHODDEF
1997 SYS_EXC_INFO_METHODDEF
1998 SYS_EXCEPTHOOK_METHODDEF
1999 SYS_EXIT_METHODDEF
2000 SYS_GETDEFAULTENCODING_METHODDEF
2001 SYS_GETDLOPENFLAGS_METHODDEF
2002 SYS_GETALLOCATEDBLOCKS_METHODDEF
2003 SYS_GETCOUNTS_METHODDEF
2004 #ifdef DYNAMIC_EXECUTION_PROFILE
2005 {"getdxp", _Py_GetDXProfile, METH_VARARGS},
2006 #endif
2007 SYS_GETFILESYSTEMENCODING_METHODDEF
2008 SYS_GETFILESYSTEMENCODEERRORS_METHODDEF
2009 #ifdef Py_TRACE_REFS
2010 {"getobjects", _Py_GetObjects, METH_VARARGS},
2011 #endif
2012 SYS_GETTOTALREFCOUNT_METHODDEF
2013 SYS_GETREFCOUNT_METHODDEF
2014 SYS_GETRECURSIONLIMIT_METHODDEF
2015 {"getsizeof", (PyCFunction)(void(*)(void))sys_getsizeof,
2016 METH_VARARGS | METH_KEYWORDS, getsizeof_doc},
2017 SYS__GETFRAME_METHODDEF
2018 SYS_GETWINDOWSVERSION_METHODDEF
2019 SYS__ENABLELEGACYWINDOWSFSENCODING_METHODDEF
2020 SYS_INTERN_METHODDEF
2021 SYS_IS_FINALIZING_METHODDEF
2022 SYS_MDEBUG_METHODDEF
2023 SYS_SETCHECKINTERVAL_METHODDEF
2024 SYS_GETCHECKINTERVAL_METHODDEF
2025 SYS_SETSWITCHINTERVAL_METHODDEF
2026 SYS_GETSWITCHINTERVAL_METHODDEF
2027 SYS_SETDLOPENFLAGS_METHODDEF
2028 {"setprofile", sys_setprofile, METH_O, setprofile_doc},
2029 SYS_GETPROFILE_METHODDEF
2030 SYS_SETRECURSIONLIMIT_METHODDEF
2031 {"settrace", sys_settrace, METH_O, settrace_doc},
2032 SYS_GETTRACE_METHODDEF
2033 SYS_CALL_TRACING_METHODDEF
2034 SYS__DEBUGMALLOCSTATS_METHODDEF
2035 SYS_SET_COROUTINE_ORIGIN_TRACKING_DEPTH_METHODDEF
2036 SYS_GET_COROUTINE_ORIGIN_TRACKING_DEPTH_METHODDEF
2037 {"set_asyncgen_hooks", (PyCFunction)(void(*)(void))sys_set_asyncgen_hooks,
2038 METH_VARARGS | METH_KEYWORDS, set_asyncgen_hooks_doc},
2039 SYS_GET_ASYNCGEN_HOOKS_METHODDEF
2040 SYS_GETANDROIDAPILEVEL_METHODDEF
2041 SYS_UNRAISABLEHOOK_METHODDEF
2042 SYS_GET_INT_MAX_STR_DIGITS_METHODDEF
2043 SYS_SET_INT_MAX_STR_DIGITS_METHODDEF
2044 {NULL, NULL} /* sentinel */
2045 };
2046
2047 static PyObject *
list_builtin_module_names(void)2048 list_builtin_module_names(void)
2049 {
2050 PyObject *list = PyList_New(0);
2051 int i;
2052 if (list == NULL)
2053 return NULL;
2054 for (i = 0; PyImport_Inittab[i].name != NULL; i++) {
2055 PyObject *name = PyUnicode_FromString(
2056 PyImport_Inittab[i].name);
2057 if (name == NULL)
2058 break;
2059 PyList_Append(list, name);
2060 Py_DECREF(name);
2061 }
2062 if (PyList_Sort(list) != 0) {
2063 Py_DECREF(list);
2064 list = NULL;
2065 }
2066 if (list) {
2067 PyObject *v = PyList_AsTuple(list);
2068 Py_DECREF(list);
2069 list = v;
2070 }
2071 return list;
2072 }
2073
2074 /* Pre-initialization support for sys.warnoptions and sys._xoptions
2075 *
2076 * Modern internal code paths:
2077 * These APIs get called after _Py_InitializeCore and get to use the
2078 * regular CPython list, dict, and unicode APIs.
2079 *
2080 * Legacy embedding code paths:
2081 * The multi-phase initialization API isn't public yet, so embedding
2082 * apps still need to be able configure sys.warnoptions and sys._xoptions
2083 * before they call Py_Initialize. To support this, we stash copies of
2084 * the supplied wchar * sequences in linked lists, and then migrate the
2085 * contents of those lists to the sys module in _PyInitializeCore.
2086 *
2087 */
2088
2089 struct _preinit_entry {
2090 wchar_t *value;
2091 struct _preinit_entry *next;
2092 };
2093
2094 typedef struct _preinit_entry *_Py_PreInitEntry;
2095
2096 static _Py_PreInitEntry _preinit_warnoptions = NULL;
2097 static _Py_PreInitEntry _preinit_xoptions = NULL;
2098
2099 static _Py_PreInitEntry
_alloc_preinit_entry(const wchar_t * value)2100 _alloc_preinit_entry(const wchar_t *value)
2101 {
2102 /* To get this to work, we have to initialize the runtime implicitly */
2103 _PyRuntime_Initialize();
2104
2105 /* Force default allocator, so we can ensure that it also gets used to
2106 * destroy the linked list in _clear_preinit_entries.
2107 */
2108 PyMemAllocatorEx old_alloc;
2109 _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
2110
2111 _Py_PreInitEntry node = PyMem_RawCalloc(1, sizeof(*node));
2112 if (node != NULL) {
2113 node->value = _PyMem_RawWcsdup(value);
2114 if (node->value == NULL) {
2115 PyMem_RawFree(node);
2116 node = NULL;
2117 };
2118 };
2119
2120 PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
2121 return node;
2122 }
2123
2124 static int
_append_preinit_entry(_Py_PreInitEntry * optionlist,const wchar_t * value)2125 _append_preinit_entry(_Py_PreInitEntry *optionlist, const wchar_t *value)
2126 {
2127 _Py_PreInitEntry new_entry = _alloc_preinit_entry(value);
2128 if (new_entry == NULL) {
2129 return -1;
2130 }
2131 /* We maintain the linked list in this order so it's easy to play back
2132 * the add commands in the same order later on in _Py_InitializeCore
2133 */
2134 _Py_PreInitEntry last_entry = *optionlist;
2135 if (last_entry == NULL) {
2136 *optionlist = new_entry;
2137 } else {
2138 while (last_entry->next != NULL) {
2139 last_entry = last_entry->next;
2140 }
2141 last_entry->next = new_entry;
2142 }
2143 return 0;
2144 }
2145
2146 static void
_clear_preinit_entries(_Py_PreInitEntry * optionlist)2147 _clear_preinit_entries(_Py_PreInitEntry *optionlist)
2148 {
2149 _Py_PreInitEntry current = *optionlist;
2150 *optionlist = NULL;
2151 /* Deallocate the nodes and their contents using the default allocator */
2152 PyMemAllocatorEx old_alloc;
2153 _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
2154 while (current != NULL) {
2155 _Py_PreInitEntry next = current->next;
2156 PyMem_RawFree(current->value);
2157 PyMem_RawFree(current);
2158 current = next;
2159 }
2160 PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
2161 }
2162
2163
2164 PyStatus
_PySys_ReadPreinitWarnOptions(PyWideStringList * options)2165 _PySys_ReadPreinitWarnOptions(PyWideStringList *options)
2166 {
2167 PyStatus status;
2168 _Py_PreInitEntry entry;
2169
2170 for (entry = _preinit_warnoptions; entry != NULL; entry = entry->next) {
2171 status = PyWideStringList_Append(options, entry->value);
2172 if (_PyStatus_EXCEPTION(status)) {
2173 return status;
2174 }
2175 }
2176
2177 _clear_preinit_entries(&_preinit_warnoptions);
2178 return _PyStatus_OK();
2179 }
2180
2181
2182 PyStatus
_PySys_ReadPreinitXOptions(PyConfig * config)2183 _PySys_ReadPreinitXOptions(PyConfig *config)
2184 {
2185 PyStatus status;
2186 _Py_PreInitEntry entry;
2187
2188 for (entry = _preinit_xoptions; entry != NULL; entry = entry->next) {
2189 status = PyWideStringList_Append(&config->xoptions, entry->value);
2190 if (_PyStatus_EXCEPTION(status)) {
2191 return status;
2192 }
2193 }
2194
2195 _clear_preinit_entries(&_preinit_xoptions);
2196 return _PyStatus_OK();
2197 }
2198
2199
2200 static PyObject *
get_warnoptions(void)2201 get_warnoptions(void)
2202 {
2203 PyObject *warnoptions = _PySys_GetObjectId(&PyId_warnoptions);
2204 if (warnoptions == NULL || !PyList_Check(warnoptions)) {
2205 /* PEP432 TODO: we can reach this if warnoptions is NULL in the main
2206 * interpreter config. When that happens, we need to properly set
2207 * the `warnoptions` reference in the main interpreter config as well.
2208 *
2209 * For Python 3.7, we shouldn't be able to get here due to the
2210 * combination of how _PyMainInterpreter_ReadConfig and _PySys_EndInit
2211 * work, but we expect 3.8+ to make the _PyMainInterpreter_ReadConfig
2212 * call optional for embedding applications, thus making this
2213 * reachable again.
2214 */
2215 warnoptions = PyList_New(0);
2216 if (warnoptions == NULL)
2217 return NULL;
2218 if (_PySys_SetObjectId(&PyId_warnoptions, warnoptions)) {
2219 Py_DECREF(warnoptions);
2220 return NULL;
2221 }
2222 Py_DECREF(warnoptions);
2223 }
2224 return warnoptions;
2225 }
2226
2227 void
PySys_ResetWarnOptions(void)2228 PySys_ResetWarnOptions(void)
2229 {
2230 PyThreadState *tstate = _PyThreadState_GET();
2231 if (tstate == NULL) {
2232 _clear_preinit_entries(&_preinit_warnoptions);
2233 return;
2234 }
2235
2236 PyObject *warnoptions = _PySys_GetObjectId(&PyId_warnoptions);
2237 if (warnoptions == NULL || !PyList_Check(warnoptions))
2238 return;
2239 PyList_SetSlice(warnoptions, 0, PyList_GET_SIZE(warnoptions), NULL);
2240 }
2241
2242 static int
_PySys_AddWarnOptionWithError(PyObject * option)2243 _PySys_AddWarnOptionWithError(PyObject *option)
2244 {
2245 PyObject *warnoptions = get_warnoptions();
2246 if (warnoptions == NULL) {
2247 return -1;
2248 }
2249 if (PyList_Append(warnoptions, option)) {
2250 return -1;
2251 }
2252 return 0;
2253 }
2254
2255 void
PySys_AddWarnOptionUnicode(PyObject * option)2256 PySys_AddWarnOptionUnicode(PyObject *option)
2257 {
2258 if (_PySys_AddWarnOptionWithError(option) < 0) {
2259 /* No return value, therefore clear error state if possible */
2260 if (_PyThreadState_UncheckedGet()) {
2261 PyErr_Clear();
2262 }
2263 }
2264 }
2265
2266 void
PySys_AddWarnOption(const wchar_t * s)2267 PySys_AddWarnOption(const wchar_t *s)
2268 {
2269 PyThreadState *tstate = _PyThreadState_GET();
2270 if (tstate == NULL) {
2271 _append_preinit_entry(&_preinit_warnoptions, s);
2272 return;
2273 }
2274 PyObject *unicode;
2275 unicode = PyUnicode_FromWideChar(s, -1);
2276 if (unicode == NULL)
2277 return;
2278 PySys_AddWarnOptionUnicode(unicode);
2279 Py_DECREF(unicode);
2280 }
2281
2282 int
PySys_HasWarnOptions(void)2283 PySys_HasWarnOptions(void)
2284 {
2285 PyObject *warnoptions = _PySys_GetObjectId(&PyId_warnoptions);
2286 return (warnoptions != NULL && PyList_Check(warnoptions)
2287 && PyList_GET_SIZE(warnoptions) > 0);
2288 }
2289
2290 static PyObject *
get_xoptions(void)2291 get_xoptions(void)
2292 {
2293 PyObject *xoptions = _PySys_GetObjectId(&PyId__xoptions);
2294 if (xoptions == NULL || !PyDict_Check(xoptions)) {
2295 /* PEP432 TODO: we can reach this if xoptions is NULL in the main
2296 * interpreter config. When that happens, we need to properly set
2297 * the `xoptions` reference in the main interpreter config as well.
2298 *
2299 * For Python 3.7, we shouldn't be able to get here due to the
2300 * combination of how _PyMainInterpreter_ReadConfig and _PySys_EndInit
2301 * work, but we expect 3.8+ to make the _PyMainInterpreter_ReadConfig
2302 * call optional for embedding applications, thus making this
2303 * reachable again.
2304 */
2305 xoptions = PyDict_New();
2306 if (xoptions == NULL)
2307 return NULL;
2308 if (_PySys_SetObjectId(&PyId__xoptions, xoptions)) {
2309 Py_DECREF(xoptions);
2310 return NULL;
2311 }
2312 Py_DECREF(xoptions);
2313 }
2314 return xoptions;
2315 }
2316
2317 static int
_PySys_AddXOptionWithError(const wchar_t * s)2318 _PySys_AddXOptionWithError(const wchar_t *s)
2319 {
2320 PyObject *name = NULL, *value = NULL;
2321
2322 PyObject *opts = get_xoptions();
2323 if (opts == NULL) {
2324 goto error;
2325 }
2326
2327 const wchar_t *name_end = wcschr(s, L'=');
2328 if (!name_end) {
2329 name = PyUnicode_FromWideChar(s, -1);
2330 value = Py_True;
2331 Py_INCREF(value);
2332 }
2333 else {
2334 name = PyUnicode_FromWideChar(s, name_end - s);
2335 value = PyUnicode_FromWideChar(name_end + 1, -1);
2336 }
2337 if (name == NULL || value == NULL) {
2338 goto error;
2339 }
2340 if (PyDict_SetItem(opts, name, value) < 0) {
2341 goto error;
2342 }
2343 Py_DECREF(name);
2344 Py_DECREF(value);
2345 return 0;
2346
2347 error:
2348 Py_XDECREF(name);
2349 Py_XDECREF(value);
2350 return -1;
2351 }
2352
2353 void
PySys_AddXOption(const wchar_t * s)2354 PySys_AddXOption(const wchar_t *s)
2355 {
2356 PyThreadState *tstate = _PyThreadState_GET();
2357 if (tstate == NULL) {
2358 _append_preinit_entry(&_preinit_xoptions, s);
2359 return;
2360 }
2361 if (_PySys_AddXOptionWithError(s) < 0) {
2362 /* No return value, therefore clear error state if possible */
2363 PyErr_Clear();
2364 }
2365 }
2366
2367 PyObject *
PySys_GetXOptions(void)2368 PySys_GetXOptions(void)
2369 {
2370 return get_xoptions();
2371 }
2372
2373 /* XXX This doc string is too long to be a single string literal in VC++ 5.0.
2374 Two literals concatenated works just fine. If you have a K&R compiler
2375 or other abomination that however *does* understand longer strings,
2376 get rid of the !!! comment in the middle and the quotes that surround it. */
2377 PyDoc_VAR(sys_doc) =
2378 PyDoc_STR(
2379 "This module provides access to some objects used or maintained by the\n\
2380 interpreter and to functions that interact strongly with the interpreter.\n\
2381 \n\
2382 Dynamic objects:\n\
2383 \n\
2384 argv -- command line arguments; argv[0] is the script pathname if known\n\
2385 path -- module search path; path[0] is the script directory, else ''\n\
2386 modules -- dictionary of loaded modules\n\
2387 \n\
2388 displayhook -- called to show results in an interactive session\n\
2389 excepthook -- called to handle any uncaught exception other than SystemExit\n\
2390 To customize printing in an interactive session or to install a custom\n\
2391 top-level exception handler, assign other functions to replace these.\n\
2392 \n\
2393 stdin -- standard input file object; used by input()\n\
2394 stdout -- standard output file object; used by print()\n\
2395 stderr -- standard error object; used for error messages\n\
2396 By assigning other file objects (or objects that behave like files)\n\
2397 to these, it is possible to redirect all of the interpreter's I/O.\n\
2398 \n\
2399 last_type -- type of last uncaught exception\n\
2400 last_value -- value of last uncaught exception\n\
2401 last_traceback -- traceback of last uncaught exception\n\
2402 These three are only available in an interactive session after a\n\
2403 traceback has been printed.\n\
2404 "
2405 )
2406 /* concatenating string here */
2407 PyDoc_STR(
2408 "\n\
2409 Static objects:\n\
2410 \n\
2411 builtin_module_names -- tuple of module names built into this interpreter\n\
2412 copyright -- copyright notice pertaining to this interpreter\n\
2413 exec_prefix -- prefix used to find the machine-specific Python library\n\
2414 executable -- absolute path of the executable binary of the Python interpreter\n\
2415 float_info -- a named tuple with information about the float implementation.\n\
2416 float_repr_style -- string indicating the style of repr() output for floats\n\
2417 hash_info -- a named tuple with information about the hash algorithm.\n\
2418 hexversion -- version information encoded as a single integer\n\
2419 implementation -- Python implementation information.\n\
2420 int_info -- a named tuple with information about the int implementation.\n\
2421 maxsize -- the largest supported length of containers.\n\
2422 maxunicode -- the value of the largest Unicode code point\n\
2423 platform -- platform identifier\n\
2424 prefix -- prefix used to find the Python library\n\
2425 thread_info -- a named tuple with information about the thread implementation.\n\
2426 version -- the version of this interpreter as a string\n\
2427 version_info -- version information as a named tuple\n\
2428 "
2429 )
2430 #ifdef MS_COREDLL
2431 /* concatenating string here */
2432 PyDoc_STR(
2433 "dllhandle -- [Windows only] integer handle of the Python DLL\n\
2434 winver -- [Windows only] version number of the Python DLL\n\
2435 "
2436 )
2437 #endif /* MS_COREDLL */
2438 #ifdef MS_WINDOWS
2439 /* concatenating string here */
2440 PyDoc_STR(
2441 "_enablelegacywindowsfsencoding -- [Windows only]\n\
2442 "
2443 )
2444 #endif
2445 PyDoc_STR(
2446 "__stdin__ -- the original stdin; don't touch!\n\
2447 __stdout__ -- the original stdout; don't touch!\n\
2448 __stderr__ -- the original stderr; don't touch!\n\
2449 __displayhook__ -- the original displayhook; don't touch!\n\
2450 __excepthook__ -- the original excepthook; don't touch!\n\
2451 \n\
2452 Functions:\n\
2453 \n\
2454 displayhook() -- print an object to the screen, and save it in builtins._\n\
2455 excepthook() -- print an exception and its traceback to sys.stderr\n\
2456 exc_info() -- return thread-safe information about the current exception\n\
2457 exit() -- exit the interpreter by raising SystemExit\n\
2458 getdlopenflags() -- returns flags to be used for dlopen() calls\n\
2459 getprofile() -- get the global profiling function\n\
2460 getrefcount() -- return the reference count for an object (plus one :-)\n\
2461 getrecursionlimit() -- return the max recursion depth for the interpreter\n\
2462 getsizeof() -- return the size of an object in bytes\n\
2463 gettrace() -- get the global debug tracing function\n\
2464 setcheckinterval() -- control how often the interpreter checks for events\n\
2465 setdlopenflags() -- set the flags to be used for dlopen() calls\n\
2466 setprofile() -- set the global profiling function\n\
2467 setrecursionlimit() -- set the max recursion depth for the interpreter\n\
2468 settrace() -- set the global debug tracing function\n\
2469 "
2470 )
2471 /* end of sys_doc */ ;
2472
2473
2474 PyDoc_STRVAR(flags__doc__,
2475 "sys.flags\n\
2476 \n\
2477 Flags provided through command line arguments or environment vars.");
2478
2479 static PyTypeObject FlagsType;
2480
2481 static PyStructSequence_Field flags_fields[] = {
2482 {"debug", "-d"},
2483 {"inspect", "-i"},
2484 {"interactive", "-i"},
2485 {"optimize", "-O or -OO"},
2486 {"dont_write_bytecode", "-B"},
2487 {"no_user_site", "-s"},
2488 {"no_site", "-S"},
2489 {"ignore_environment", "-E"},
2490 {"verbose", "-v"},
2491 /* {"unbuffered", "-u"}, */
2492 /* {"skip_first", "-x"}, */
2493 {"bytes_warning", "-b"},
2494 {"quiet", "-q"},
2495 {"hash_randomization", "-R"},
2496 {"isolated", "-I"},
2497 {"dev_mode", "-X dev"},
2498 {"utf8_mode", "-X utf8"},
2499 {"int_max_str_digits", "-X int_max_str_digits"},
2500 {0}
2501 };
2502
2503 static PyStructSequence_Desc flags_desc = {
2504 "sys.flags", /* name */
2505 flags__doc__, /* doc */
2506 flags_fields, /* fields */
2507 16
2508 };
2509
2510 static PyObject*
make_flags(_PyRuntimeState * runtime,PyInterpreterState * interp)2511 make_flags(_PyRuntimeState *runtime, PyInterpreterState *interp)
2512 {
2513 int pos = 0;
2514 PyObject *seq;
2515 const PyPreConfig *preconfig = &runtime->preconfig;
2516 const PyConfig *config = &interp->config;
2517
2518 seq = PyStructSequence_New(&FlagsType);
2519 if (seq == NULL)
2520 return NULL;
2521
2522 #define SetFlag(flag) \
2523 PyStructSequence_SET_ITEM(seq, pos++, PyLong_FromLong(flag))
2524
2525 SetFlag(config->parser_debug);
2526 SetFlag(config->inspect);
2527 SetFlag(config->interactive);
2528 SetFlag(config->optimization_level);
2529 SetFlag(!config->write_bytecode);
2530 SetFlag(!config->user_site_directory);
2531 SetFlag(!config->site_import);
2532 SetFlag(!config->use_environment);
2533 SetFlag(config->verbose);
2534 /* SetFlag(saw_unbuffered_flag); */
2535 /* SetFlag(skipfirstline); */
2536 SetFlag(config->bytes_warning);
2537 SetFlag(config->quiet);
2538 SetFlag(config->use_hash_seed == 0 || config->hash_seed != 0);
2539 SetFlag(config->isolated);
2540 PyStructSequence_SET_ITEM(seq, pos++, PyBool_FromLong(config->dev_mode));
2541 SetFlag(preconfig->utf8_mode);
2542 SetFlag(_Py_global_config_int_max_str_digits);
2543 #undef SetFlag
2544
2545 if (PyErr_Occurred()) {
2546 Py_DECREF(seq);
2547 return NULL;
2548 }
2549 return seq;
2550 }
2551
2552 PyDoc_STRVAR(version_info__doc__,
2553 "sys.version_info\n\
2554 \n\
2555 Version information as a named tuple.");
2556
2557 static PyTypeObject VersionInfoType;
2558
2559 static PyStructSequence_Field version_info_fields[] = {
2560 {"major", "Major release number"},
2561 {"minor", "Minor release number"},
2562 {"micro", "Patch release number"},
2563 {"releaselevel", "'alpha', 'beta', 'candidate', or 'final'"},
2564 {"serial", "Serial release number"},
2565 {0}
2566 };
2567
2568 static PyStructSequence_Desc version_info_desc = {
2569 "sys.version_info", /* name */
2570 version_info__doc__, /* doc */
2571 version_info_fields, /* fields */
2572 5
2573 };
2574
2575 static PyObject *
make_version_info(void)2576 make_version_info(void)
2577 {
2578 PyObject *version_info;
2579 char *s;
2580 int pos = 0;
2581
2582 version_info = PyStructSequence_New(&VersionInfoType);
2583 if (version_info == NULL) {
2584 return NULL;
2585 }
2586
2587 /*
2588 * These release level checks are mutually exclusive and cover
2589 * the field, so don't get too fancy with the pre-processor!
2590 */
2591 #if PY_RELEASE_LEVEL == PY_RELEASE_LEVEL_ALPHA
2592 s = "alpha";
2593 #elif PY_RELEASE_LEVEL == PY_RELEASE_LEVEL_BETA
2594 s = "beta";
2595 #elif PY_RELEASE_LEVEL == PY_RELEASE_LEVEL_GAMMA
2596 s = "candidate";
2597 #elif PY_RELEASE_LEVEL == PY_RELEASE_LEVEL_FINAL
2598 s = "final";
2599 #endif
2600
2601 #define SetIntItem(flag) \
2602 PyStructSequence_SET_ITEM(version_info, pos++, PyLong_FromLong(flag))
2603 #define SetStrItem(flag) \
2604 PyStructSequence_SET_ITEM(version_info, pos++, PyUnicode_FromString(flag))
2605
2606 SetIntItem(PY_MAJOR_VERSION);
2607 SetIntItem(PY_MINOR_VERSION);
2608 SetIntItem(PY_MICRO_VERSION);
2609 SetStrItem(s);
2610 SetIntItem(PY_RELEASE_SERIAL);
2611 #undef SetIntItem
2612 #undef SetStrItem
2613
2614 if (PyErr_Occurred()) {
2615 Py_CLEAR(version_info);
2616 return NULL;
2617 }
2618 return version_info;
2619 }
2620
2621 /* sys.implementation values */
2622 #define NAME "cpython"
2623 const char *_PySys_ImplName = NAME;
2624 #define MAJOR Py_STRINGIFY(PY_MAJOR_VERSION)
2625 #define MINOR Py_STRINGIFY(PY_MINOR_VERSION)
2626 #define TAG NAME "-" MAJOR MINOR
2627 const char *_PySys_ImplCacheTag = TAG;
2628 #undef NAME
2629 #undef MAJOR
2630 #undef MINOR
2631 #undef TAG
2632
2633 static PyObject *
make_impl_info(PyObject * version_info)2634 make_impl_info(PyObject *version_info)
2635 {
2636 int res;
2637 PyObject *impl_info, *value, *ns;
2638
2639 impl_info = PyDict_New();
2640 if (impl_info == NULL)
2641 return NULL;
2642
2643 /* populate the dict */
2644
2645 value = PyUnicode_FromString(_PySys_ImplName);
2646 if (value == NULL)
2647 goto error;
2648 res = PyDict_SetItemString(impl_info, "name", value);
2649 Py_DECREF(value);
2650 if (res < 0)
2651 goto error;
2652
2653 value = PyUnicode_FromString(_PySys_ImplCacheTag);
2654 if (value == NULL)
2655 goto error;
2656 res = PyDict_SetItemString(impl_info, "cache_tag", value);
2657 Py_DECREF(value);
2658 if (res < 0)
2659 goto error;
2660
2661 res = PyDict_SetItemString(impl_info, "version", version_info);
2662 if (res < 0)
2663 goto error;
2664
2665 value = PyLong_FromLong(PY_VERSION_HEX);
2666 if (value == NULL)
2667 goto error;
2668 res = PyDict_SetItemString(impl_info, "hexversion", value);
2669 Py_DECREF(value);
2670 if (res < 0)
2671 goto error;
2672
2673 #ifdef MULTIARCH
2674 value = PyUnicode_FromString(MULTIARCH);
2675 if (value == NULL)
2676 goto error;
2677 res = PyDict_SetItemString(impl_info, "_multiarch", value);
2678 Py_DECREF(value);
2679 if (res < 0)
2680 goto error;
2681 #endif
2682
2683 /* dict ready */
2684
2685 ns = _PyNamespace_New(impl_info);
2686 Py_DECREF(impl_info);
2687 return ns;
2688
2689 error:
2690 Py_CLEAR(impl_info);
2691 return NULL;
2692 }
2693
2694 static struct PyModuleDef sysmodule = {
2695 PyModuleDef_HEAD_INIT,
2696 "sys",
2697 sys_doc,
2698 -1, /* multiple "initialization" just copies the module dict. */
2699 sys_methods,
2700 NULL,
2701 NULL,
2702 NULL,
2703 NULL
2704 };
2705
2706 /* Updating the sys namespace, returning NULL pointer on error */
2707 #define SET_SYS_FROM_STRING_BORROW(key, value) \
2708 do { \
2709 PyObject *v = (value); \
2710 if (v == NULL) { \
2711 goto err_occurred; \
2712 } \
2713 res = PyDict_SetItemString(sysdict, key, v); \
2714 if (res < 0) { \
2715 goto err_occurred; \
2716 } \
2717 } while (0)
2718 #define SET_SYS_FROM_STRING(key, value) \
2719 do { \
2720 PyObject *v = (value); \
2721 if (v == NULL) { \
2722 goto err_occurred; \
2723 } \
2724 res = PyDict_SetItemString(sysdict, key, v); \
2725 Py_DECREF(v); \
2726 if (res < 0) { \
2727 goto err_occurred; \
2728 } \
2729 } while (0)
2730
2731 static PyStatus
_PySys_InitCore(_PyRuntimeState * runtime,PyInterpreterState * interp,PyObject * sysdict)2732 _PySys_InitCore(_PyRuntimeState *runtime, PyInterpreterState *interp,
2733 PyObject *sysdict)
2734 {
2735 PyObject *version_info;
2736 int res;
2737
2738 /* stdin/stdout/stderr are set in pylifecycle.c */
2739
2740 SET_SYS_FROM_STRING_BORROW("__displayhook__",
2741 PyDict_GetItemString(sysdict, "displayhook"));
2742 SET_SYS_FROM_STRING_BORROW("__excepthook__",
2743 PyDict_GetItemString(sysdict, "excepthook"));
2744 SET_SYS_FROM_STRING_BORROW(
2745 "__breakpointhook__",
2746 PyDict_GetItemString(sysdict, "breakpointhook"));
2747 SET_SYS_FROM_STRING_BORROW("__unraisablehook__",
2748 PyDict_GetItemString(sysdict, "unraisablehook"));
2749
2750 SET_SYS_FROM_STRING("version",
2751 PyUnicode_FromString(Py_GetVersion()));
2752 SET_SYS_FROM_STRING("hexversion",
2753 PyLong_FromLong(PY_VERSION_HEX));
2754 SET_SYS_FROM_STRING("_git",
2755 Py_BuildValue("(szz)", "CPython", _Py_gitidentifier(),
2756 _Py_gitversion()));
2757 SET_SYS_FROM_STRING("_framework", PyUnicode_FromString(_PYTHONFRAMEWORK));
2758 SET_SYS_FROM_STRING("api_version",
2759 PyLong_FromLong(PYTHON_API_VERSION));
2760 SET_SYS_FROM_STRING("copyright",
2761 PyUnicode_FromString(Py_GetCopyright()));
2762 SET_SYS_FROM_STRING("platform",
2763 PyUnicode_FromString(Py_GetPlatform()));
2764 SET_SYS_FROM_STRING("maxsize",
2765 PyLong_FromSsize_t(PY_SSIZE_T_MAX));
2766 SET_SYS_FROM_STRING("float_info",
2767 PyFloat_GetInfo());
2768 SET_SYS_FROM_STRING("int_info",
2769 PyLong_GetInfo());
2770 /* initialize hash_info */
2771 if (Hash_InfoType.tp_name == NULL) {
2772 if (PyStructSequence_InitType2(&Hash_InfoType, &hash_info_desc) < 0) {
2773 goto type_init_failed;
2774 }
2775 }
2776 SET_SYS_FROM_STRING("hash_info",
2777 get_hash_info());
2778 SET_SYS_FROM_STRING("maxunicode",
2779 PyLong_FromLong(0x10FFFF));
2780 SET_SYS_FROM_STRING("builtin_module_names",
2781 list_builtin_module_names());
2782 #if PY_BIG_ENDIAN
2783 SET_SYS_FROM_STRING("byteorder",
2784 PyUnicode_FromString("big"));
2785 #else
2786 SET_SYS_FROM_STRING("byteorder",
2787 PyUnicode_FromString("little"));
2788 #endif
2789
2790 #ifdef MS_COREDLL
2791 SET_SYS_FROM_STRING("dllhandle",
2792 PyLong_FromVoidPtr(PyWin_DLLhModule));
2793 SET_SYS_FROM_STRING("winver",
2794 PyUnicode_FromString(PyWin_DLLVersionString));
2795 #endif
2796 #ifdef ABIFLAGS
2797 SET_SYS_FROM_STRING("abiflags",
2798 PyUnicode_FromString(ABIFLAGS));
2799 #endif
2800
2801 /* version_info */
2802 if (VersionInfoType.tp_name == NULL) {
2803 if (PyStructSequence_InitType2(&VersionInfoType,
2804 &version_info_desc) < 0) {
2805 goto type_init_failed;
2806 }
2807 }
2808 version_info = make_version_info();
2809 SET_SYS_FROM_STRING("version_info", version_info);
2810 /* prevent user from creating new instances */
2811 VersionInfoType.tp_init = NULL;
2812 VersionInfoType.tp_new = NULL;
2813 res = PyDict_DelItemString(VersionInfoType.tp_dict, "__new__");
2814 if (res < 0 && PyErr_ExceptionMatches(PyExc_KeyError))
2815 PyErr_Clear();
2816
2817 /* implementation */
2818 SET_SYS_FROM_STRING("implementation", make_impl_info(version_info));
2819
2820 /* flags */
2821 if (FlagsType.tp_name == 0) {
2822 if (PyStructSequence_InitType2(&FlagsType, &flags_desc) < 0) {
2823 goto type_init_failed;
2824 }
2825 }
2826 /* Set flags to their default values (updated by _PySys_InitMain()) */
2827 SET_SYS_FROM_STRING("flags", make_flags(runtime, interp));
2828
2829 #if defined(MS_WINDOWS)
2830 /* getwindowsversion */
2831 if (WindowsVersionType.tp_name == 0)
2832 if (PyStructSequence_InitType2(&WindowsVersionType,
2833 &windows_version_desc) < 0) {
2834 goto type_init_failed;
2835 }
2836 /* prevent user from creating new instances */
2837 WindowsVersionType.tp_init = NULL;
2838 WindowsVersionType.tp_new = NULL;
2839 assert(!PyErr_Occurred());
2840 res = PyDict_DelItemString(WindowsVersionType.tp_dict, "__new__");
2841 if (res < 0 && PyErr_ExceptionMatches(PyExc_KeyError)) {
2842 PyErr_Clear();
2843 }
2844 #endif
2845
2846 /* float repr style: 0.03 (short) vs 0.029999999999999999 (legacy) */
2847 #ifndef PY_NO_SHORT_FLOAT_REPR
2848 SET_SYS_FROM_STRING("float_repr_style",
2849 PyUnicode_FromString("short"));
2850 #else
2851 SET_SYS_FROM_STRING("float_repr_style",
2852 PyUnicode_FromString("legacy"));
2853 #endif
2854
2855 SET_SYS_FROM_STRING("thread_info", PyThread_GetInfo());
2856
2857 /* initialize asyncgen_hooks */
2858 if (AsyncGenHooksType.tp_name == NULL) {
2859 if (PyStructSequence_InitType2(
2860 &AsyncGenHooksType, &asyncgen_hooks_desc) < 0) {
2861 goto type_init_failed;
2862 }
2863 }
2864
2865 if (PyErr_Occurred()) {
2866 goto err_occurred;
2867 }
2868 return _PyStatus_OK();
2869
2870 type_init_failed:
2871 return _PyStatus_ERR("failed to initialize a type");
2872
2873 err_occurred:
2874 return _PyStatus_ERR("can't initialize sys module");
2875 }
2876
2877 #undef SET_SYS_FROM_STRING
2878
2879 /* Updating the sys namespace, returning integer error codes */
2880 #define SET_SYS_FROM_STRING_INT_RESULT(key, value) \
2881 do { \
2882 PyObject *v = (value); \
2883 if (v == NULL) \
2884 return -1; \
2885 res = PyDict_SetItemString(sysdict, key, v); \
2886 Py_DECREF(v); \
2887 if (res < 0) { \
2888 return res; \
2889 } \
2890 } while (0)
2891
2892
2893 static int
sys_add_xoption(PyObject * opts,const wchar_t * s)2894 sys_add_xoption(PyObject *opts, const wchar_t *s)
2895 {
2896 PyObject *name, *value;
2897
2898 const wchar_t *name_end = wcschr(s, L'=');
2899 if (!name_end) {
2900 name = PyUnicode_FromWideChar(s, -1);
2901 value = Py_True;
2902 Py_INCREF(value);
2903 }
2904 else {
2905 name = PyUnicode_FromWideChar(s, name_end - s);
2906 value = PyUnicode_FromWideChar(name_end + 1, -1);
2907 }
2908 if (name == NULL || value == NULL) {
2909 goto error;
2910 }
2911 if (PyDict_SetItem(opts, name, value) < 0) {
2912 goto error;
2913 }
2914 Py_DECREF(name);
2915 Py_DECREF(value);
2916 return 0;
2917
2918 error:
2919 Py_XDECREF(name);
2920 Py_XDECREF(value);
2921 return -1;
2922 }
2923
2924
2925 static PyObject*
sys_create_xoptions_dict(const PyConfig * config)2926 sys_create_xoptions_dict(const PyConfig *config)
2927 {
2928 Py_ssize_t nxoption = config->xoptions.length;
2929 wchar_t * const * xoptions = config->xoptions.items;
2930 PyObject *dict = PyDict_New();
2931 if (dict == NULL) {
2932 return NULL;
2933 }
2934
2935 for (Py_ssize_t i=0; i < nxoption; i++) {
2936 const wchar_t *option = xoptions[i];
2937 if (sys_add_xoption(dict, option) < 0) {
2938 Py_DECREF(dict);
2939 return NULL;
2940 }
2941 }
2942
2943 return dict;
2944 }
2945
2946
2947 int
_PySys_InitMain(_PyRuntimeState * runtime,PyInterpreterState * interp)2948 _PySys_InitMain(_PyRuntimeState *runtime, PyInterpreterState *interp)
2949 {
2950 PyObject *sysdict = interp->sysdict;
2951 const PyConfig *config = &interp->config;
2952 int res;
2953
2954 #define COPY_LIST(KEY, VALUE) \
2955 do { \
2956 PyObject *list = _PyWideStringList_AsList(&(VALUE)); \
2957 if (list == NULL) { \
2958 return -1; \
2959 } \
2960 SET_SYS_FROM_STRING_BORROW(KEY, list); \
2961 Py_DECREF(list); \
2962 } while (0)
2963
2964 #define SET_SYS_FROM_WSTR(KEY, VALUE) \
2965 do { \
2966 PyObject *str = PyUnicode_FromWideChar(VALUE, -1); \
2967 if (str == NULL) { \
2968 return -1; \
2969 } \
2970 SET_SYS_FROM_STRING_BORROW(KEY, str); \
2971 Py_DECREF(str); \
2972 } while (0)
2973
2974 COPY_LIST("path", config->module_search_paths);
2975
2976 SET_SYS_FROM_WSTR("executable", config->executable);
2977 SET_SYS_FROM_WSTR("_base_executable", config->base_executable);
2978 SET_SYS_FROM_WSTR("prefix", config->prefix);
2979 SET_SYS_FROM_WSTR("base_prefix", config->base_prefix);
2980 SET_SYS_FROM_WSTR("exec_prefix", config->exec_prefix);
2981 SET_SYS_FROM_WSTR("base_exec_prefix", config->base_exec_prefix);
2982
2983 if (config->pycache_prefix != NULL) {
2984 SET_SYS_FROM_WSTR("pycache_prefix", config->pycache_prefix);
2985 } else {
2986 PyDict_SetItemString(sysdict, "pycache_prefix", Py_None);
2987 }
2988
2989 COPY_LIST("argv", config->argv);
2990 COPY_LIST("warnoptions", config->warnoptions);
2991
2992 PyObject *xoptions = sys_create_xoptions_dict(config);
2993 if (xoptions == NULL) {
2994 return -1;
2995 }
2996 SET_SYS_FROM_STRING_BORROW("_xoptions", xoptions);
2997 Py_DECREF(xoptions);
2998
2999 #undef COPY_LIST
3000 #undef SET_SYS_FROM_WSTR
3001
3002 /* Set flags to their final values */
3003 SET_SYS_FROM_STRING_INT_RESULT("flags", make_flags(runtime, interp));
3004 /* prevent user from creating new instances */
3005 FlagsType.tp_init = NULL;
3006 FlagsType.tp_new = NULL;
3007 res = PyDict_DelItemString(FlagsType.tp_dict, "__new__");
3008 if (res < 0) {
3009 if (!PyErr_ExceptionMatches(PyExc_KeyError)) {
3010 return res;
3011 }
3012 PyErr_Clear();
3013 }
3014
3015 SET_SYS_FROM_STRING_INT_RESULT("dont_write_bytecode",
3016 PyBool_FromLong(!config->write_bytecode));
3017
3018 if (get_warnoptions() == NULL)
3019 return -1;
3020
3021 if (get_xoptions() == NULL)
3022 return -1;
3023
3024 if (PyErr_Occurred())
3025 return -1;
3026
3027 return 0;
3028
3029 err_occurred:
3030 return -1;
3031 }
3032
3033 #undef SET_SYS_FROM_STRING_BORROW
3034 #undef SET_SYS_FROM_STRING_INT_RESULT
3035
3036
3037 /* Set up a preliminary stderr printer until we have enough
3038 infrastructure for the io module in place.
3039
3040 Use UTF-8/surrogateescape and ignore EAGAIN errors. */
3041 PyStatus
_PySys_SetPreliminaryStderr(PyObject * sysdict)3042 _PySys_SetPreliminaryStderr(PyObject *sysdict)
3043 {
3044 PyObject *pstderr = PyFile_NewStdPrinter(fileno(stderr));
3045 if (pstderr == NULL) {
3046 goto error;
3047 }
3048 if (_PyDict_SetItemId(sysdict, &PyId_stderr, pstderr) < 0) {
3049 goto error;
3050 }
3051 if (PyDict_SetItemString(sysdict, "__stderr__", pstderr) < 0) {
3052 goto error;
3053 }
3054 Py_DECREF(pstderr);
3055 return _PyStatus_OK();
3056
3057 error:
3058 Py_XDECREF(pstderr);
3059 return _PyStatus_ERR("can't set preliminary stderr");
3060 }
3061
3062
3063 /* Create sys module without all attributes: _PySys_InitMain() should be called
3064 later to add remaining attributes. */
3065 PyStatus
_PySys_Create(_PyRuntimeState * runtime,PyInterpreterState * interp,PyObject ** sysmod_p)3066 _PySys_Create(_PyRuntimeState *runtime, PyInterpreterState *interp,
3067 PyObject **sysmod_p)
3068 {
3069 PyObject *modules = PyDict_New();
3070 if (modules == NULL) {
3071 return _PyStatus_ERR("can't make modules dictionary");
3072 }
3073 interp->modules = modules;
3074
3075 PyObject *sysmod = _PyModule_CreateInitialized(&sysmodule, PYTHON_API_VERSION);
3076 if (sysmod == NULL) {
3077 return _PyStatus_ERR("failed to create a module object");
3078 }
3079
3080 PyObject *sysdict = PyModule_GetDict(sysmod);
3081 if (sysdict == NULL) {
3082 return _PyStatus_ERR("can't initialize sys dict");
3083 }
3084 Py_INCREF(sysdict);
3085 interp->sysdict = sysdict;
3086
3087 if (PyDict_SetItemString(sysdict, "modules", interp->modules) < 0) {
3088 return _PyStatus_ERR("can't initialize sys module");
3089 }
3090
3091 PyStatus status = _PySys_SetPreliminaryStderr(sysdict);
3092 if (_PyStatus_EXCEPTION(status)) {
3093 return status;
3094 }
3095
3096 status = _PySys_InitCore(runtime, interp, sysdict);
3097 if (_PyStatus_EXCEPTION(status)) {
3098 return status;
3099 }
3100
3101 _PyImport_FixupBuiltin(sysmod, "sys", interp->modules);
3102
3103 *sysmod_p = sysmod;
3104 return _PyStatus_OK();
3105 }
3106
3107
3108 static PyObject *
makepathobject(const wchar_t * path,wchar_t delim)3109 makepathobject(const wchar_t *path, wchar_t delim)
3110 {
3111 int i, n;
3112 const wchar_t *p;
3113 PyObject *v, *w;
3114
3115 n = 1;
3116 p = path;
3117 while ((p = wcschr(p, delim)) != NULL) {
3118 n++;
3119 p++;
3120 }
3121 v = PyList_New(n);
3122 if (v == NULL)
3123 return NULL;
3124 for (i = 0; ; i++) {
3125 p = wcschr(path, delim);
3126 if (p == NULL)
3127 p = path + wcslen(path); /* End of string */
3128 w = PyUnicode_FromWideChar(path, (Py_ssize_t)(p - path));
3129 if (w == NULL) {
3130 Py_DECREF(v);
3131 return NULL;
3132 }
3133 PyList_SET_ITEM(v, i, w);
3134 if (*p == '\0')
3135 break;
3136 path = p+1;
3137 }
3138 return v;
3139 }
3140
3141 void
PySys_SetPath(const wchar_t * path)3142 PySys_SetPath(const wchar_t *path)
3143 {
3144 PyObject *v;
3145 if ((v = makepathobject(path, DELIM)) == NULL)
3146 Py_FatalError("can't create sys.path");
3147 if (_PySys_SetObjectId(&PyId_path, v) != 0)
3148 Py_FatalError("can't assign sys.path");
3149 Py_DECREF(v);
3150 }
3151
3152 static PyObject *
make_sys_argv(int argc,wchar_t * const * argv)3153 make_sys_argv(int argc, wchar_t * const * argv)
3154 {
3155 PyObject *list = PyList_New(argc);
3156 if (list == NULL) {
3157 return NULL;
3158 }
3159
3160 for (Py_ssize_t i = 0; i < argc; i++) {
3161 PyObject *v = PyUnicode_FromWideChar(argv[i], -1);
3162 if (v == NULL) {
3163 Py_DECREF(list);
3164 return NULL;
3165 }
3166 PyList_SET_ITEM(list, i, v);
3167 }
3168 return list;
3169 }
3170
3171 void
PySys_SetArgvEx(int argc,wchar_t ** argv,int updatepath)3172 PySys_SetArgvEx(int argc, wchar_t **argv, int updatepath)
3173 {
3174 wchar_t* empty_argv[1] = {L""};
3175
3176 if (argc < 1 || argv == NULL) {
3177 /* Ensure at least one (empty) argument is seen */
3178 argv = empty_argv;
3179 argc = 1;
3180 }
3181
3182 PyObject *av = make_sys_argv(argc, argv);
3183 if (av == NULL) {
3184 Py_FatalError("no mem for sys.argv");
3185 }
3186 if (PySys_SetObject("argv", av) != 0) {
3187 Py_DECREF(av);
3188 Py_FatalError("can't assign sys.argv");
3189 }
3190 Py_DECREF(av);
3191
3192 if (updatepath) {
3193 /* If argv[0] is not '-c' nor '-m', prepend argv[0] to sys.path.
3194 If argv[0] is a symlink, use the real path. */
3195 const PyWideStringList argv_list = {.length = argc, .items = argv};
3196 PyObject *path0 = NULL;
3197 if (_PyPathConfig_ComputeSysPath0(&argv_list, &path0)) {
3198 if (path0 == NULL) {
3199 Py_FatalError("can't compute path0 from argv");
3200 }
3201
3202 PyObject *sys_path = _PySys_GetObjectId(&PyId_path);
3203 if (sys_path != NULL) {
3204 if (PyList_Insert(sys_path, 0, path0) < 0) {
3205 Py_DECREF(path0);
3206 Py_FatalError("can't prepend path0 to sys.path");
3207 }
3208 }
3209 Py_DECREF(path0);
3210 }
3211 }
3212 }
3213
3214 void
PySys_SetArgv(int argc,wchar_t ** argv)3215 PySys_SetArgv(int argc, wchar_t **argv)
3216 {
3217 PySys_SetArgvEx(argc, argv, Py_IsolatedFlag == 0);
3218 }
3219
3220 /* Reimplementation of PyFile_WriteString() no calling indirectly
3221 PyErr_CheckSignals(): avoid the call to PyObject_Str(). */
3222
3223 static int
sys_pyfile_write_unicode(PyObject * unicode,PyObject * file)3224 sys_pyfile_write_unicode(PyObject *unicode, PyObject *file)
3225 {
3226 PyObject *writer = NULL, *result = NULL;
3227 int err;
3228
3229 if (file == NULL)
3230 return -1;
3231
3232 writer = _PyObject_GetAttrId(file, &PyId_write);
3233 if (writer == NULL)
3234 goto error;
3235
3236 result = PyObject_CallFunctionObjArgs(writer, unicode, NULL);
3237 if (result == NULL) {
3238 goto error;
3239 } else {
3240 err = 0;
3241 goto finally;
3242 }
3243
3244 error:
3245 err = -1;
3246 finally:
3247 Py_XDECREF(writer);
3248 Py_XDECREF(result);
3249 return err;
3250 }
3251
3252 static int
sys_pyfile_write(const char * text,PyObject * file)3253 sys_pyfile_write(const char *text, PyObject *file)
3254 {
3255 PyObject *unicode = NULL;
3256 int err;
3257
3258 if (file == NULL)
3259 return -1;
3260
3261 unicode = PyUnicode_FromString(text);
3262 if (unicode == NULL)
3263 return -1;
3264
3265 err = sys_pyfile_write_unicode(unicode, file);
3266 Py_DECREF(unicode);
3267 return err;
3268 }
3269
3270 /* APIs to write to sys.stdout or sys.stderr using a printf-like interface.
3271 Adapted from code submitted by Just van Rossum.
3272
3273 PySys_WriteStdout(format, ...)
3274 PySys_WriteStderr(format, ...)
3275
3276 The first function writes to sys.stdout; the second to sys.stderr. When
3277 there is a problem, they write to the real (C level) stdout or stderr;
3278 no exceptions are raised.
3279
3280 PyErr_CheckSignals() is not called to avoid the execution of the Python
3281 signal handlers: they may raise a new exception whereas sys_write()
3282 ignores all exceptions.
3283
3284 Both take a printf-style format string as their first argument followed
3285 by a variable length argument list determined by the format string.
3286
3287 *** WARNING ***
3288
3289 The format should limit the total size of the formatted output string to
3290 1000 bytes. In particular, this means that no unrestricted "%s" formats
3291 should occur; these should be limited using "%.<N>s where <N> is a
3292 decimal number calculated so that <N> plus the maximum size of other
3293 formatted text does not exceed 1000 bytes. Also watch out for "%f",
3294 which can print hundreds of digits for very large numbers.
3295
3296 */
3297
3298 static void
sys_write(_Py_Identifier * key,FILE * fp,const char * format,va_list va)3299 sys_write(_Py_Identifier *key, FILE *fp, const char *format, va_list va)
3300 {
3301 PyObject *file;
3302 PyObject *error_type, *error_value, *error_traceback;
3303 char buffer[1001];
3304 int written;
3305
3306 PyErr_Fetch(&error_type, &error_value, &error_traceback);
3307 file = _PySys_GetObjectId(key);
3308 written = PyOS_vsnprintf(buffer, sizeof(buffer), format, va);
3309 if (sys_pyfile_write(buffer, file) != 0) {
3310 PyErr_Clear();
3311 fputs(buffer, fp);
3312 }
3313 if (written < 0 || (size_t)written >= sizeof(buffer)) {
3314 const char *truncated = "... truncated";
3315 if (sys_pyfile_write(truncated, file) != 0)
3316 fputs(truncated, fp);
3317 }
3318 PyErr_Restore(error_type, error_value, error_traceback);
3319 }
3320
3321 void
PySys_WriteStdout(const char * format,...)3322 PySys_WriteStdout(const char *format, ...)
3323 {
3324 va_list va;
3325
3326 va_start(va, format);
3327 sys_write(&PyId_stdout, stdout, format, va);
3328 va_end(va);
3329 }
3330
3331 void
PySys_WriteStderr(const char * format,...)3332 PySys_WriteStderr(const char *format, ...)
3333 {
3334 va_list va;
3335
3336 va_start(va, format);
3337 sys_write(&PyId_stderr, stderr, format, va);
3338 va_end(va);
3339 }
3340
3341 static void
sys_format(_Py_Identifier * key,FILE * fp,const char * format,va_list va)3342 sys_format(_Py_Identifier *key, FILE *fp, const char *format, va_list va)
3343 {
3344 PyObject *file, *message;
3345 PyObject *error_type, *error_value, *error_traceback;
3346 const char *utf8;
3347
3348 PyErr_Fetch(&error_type, &error_value, &error_traceback);
3349 file = _PySys_GetObjectId(key);
3350 message = PyUnicode_FromFormatV(format, va);
3351 if (message != NULL) {
3352 if (sys_pyfile_write_unicode(message, file) != 0) {
3353 PyErr_Clear();
3354 utf8 = PyUnicode_AsUTF8(message);
3355 if (utf8 != NULL)
3356 fputs(utf8, fp);
3357 }
3358 Py_DECREF(message);
3359 }
3360 PyErr_Restore(error_type, error_value, error_traceback);
3361 }
3362
3363 void
PySys_FormatStdout(const char * format,...)3364 PySys_FormatStdout(const char *format, ...)
3365 {
3366 va_list va;
3367
3368 va_start(va, format);
3369 sys_format(&PyId_stdout, stdout, format, va);
3370 va_end(va);
3371 }
3372
3373 void
PySys_FormatStderr(const char * format,...)3374 PySys_FormatStderr(const char *format, ...)
3375 {
3376 va_list va;
3377
3378 va_start(va, format);
3379 sys_format(&PyId_stderr, stderr, format, va);
3380 va_end(va);
3381 }
3382