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