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