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