diff options
Diffstat (limited to 'Python/sysmodule.c')
-rw-r--r-- | Python/sysmodule.c | 128 |
1 files changed, 97 insertions, 31 deletions
diff --git a/Python/sysmodule.c b/Python/sysmodule.c index 2d7e01bd7f..4028a01dab 100644 --- a/Python/sysmodule.c +++ b/Python/sysmodule.c @@ -41,6 +41,26 @@ extern const char *PyWin_DLLVersionString; #include <langinfo.h> #endif +_Py_IDENTIFIER(_); +_Py_IDENTIFIER(__sizeof__); +_Py_IDENTIFIER(buffer); +_Py_IDENTIFIER(builtins); +_Py_IDENTIFIER(encoding); +_Py_IDENTIFIER(path); +_Py_IDENTIFIER(stdout); +_Py_IDENTIFIER(stderr); +_Py_IDENTIFIER(write); + +PyObject * +_PySys_GetObjectId(_Py_Identifier *key) +{ + PyThreadState *tstate = PyThreadState_GET(); + PyObject *sd = tstate->interp->sysdict; + if (sd == NULL) + return NULL; + return _PyDict_GetItemId(sd, key); +} + PyObject * PySys_GetObject(const char *name) { @@ -52,6 +72,21 @@ PySys_GetObject(const char *name) } int +_PySys_SetObjectId(_Py_Identifier *key, PyObject *v) +{ + PyThreadState *tstate = PyThreadState_GET(); + PyObject *sd = tstate->interp->sysdict; + if (v == NULL) { + if (_PyDict_GetItemId(sd, key) == NULL) + return 0; + else + return _PyDict_DelItemId(sd, key); + } + else + return _PyDict_SetItemId(sd, key, v); +} + +int PySys_SetObject(const char *name, PyObject *v) { PyThreadState *tstate = PyThreadState_GET(); @@ -79,8 +114,6 @@ sys_displayhook_unencodable(PyObject *outf, PyObject *o) PyObject *encoded, *escaped_str, *repr_str, *buffer, *result; char *stdout_encoding_str; int ret; - _Py_IDENTIFIER(encoding); - _Py_IDENTIFIER(buffer); stdout_encoding = _PyObject_GetAttrId(outf, &PyId_encoding); if (stdout_encoding == NULL) @@ -101,7 +134,6 @@ sys_displayhook_unencodable(PyObject *outf, PyObject *o) buffer = _PyObject_GetAttrId(outf, &PyId_buffer); if (buffer) { - _Py_IDENTIFIER(write); result = _PyObject_CallMethodId(buffer, &PyId_write, "(O)", encoded); Py_DECREF(buffer); Py_DECREF(encoded); @@ -137,10 +169,11 @@ sys_displayhook(PyObject *self, PyObject *o) PyObject *outf; PyInterpreterState *interp = PyThreadState_GET()->interp; PyObject *modules = interp->modules; - PyObject *builtins = PyDict_GetItemString(modules, "builtins"); + PyObject *builtins; + static PyObject *newline = NULL; int err; - _Py_IDENTIFIER(_); + builtins = _PyDict_GetItemId(modules, &PyId_builtins); if (builtins == NULL) { PyErr_SetString(PyExc_RuntimeError, "lost builtins module"); return NULL; @@ -155,7 +188,7 @@ sys_displayhook(PyObject *self, PyObject *o) } if (_PyObject_SetAttrId(builtins, &PyId__, Py_None) != 0) return NULL; - outf = PySys_GetObject("stdout"); + outf = _PySys_GetObjectId(&PyId_stdout); if (outf == NULL || outf == Py_None) { PyErr_SetString(PyExc_RuntimeError, "lost sys.stdout"); return NULL; @@ -173,7 +206,12 @@ sys_displayhook(PyObject *self, PyObject *o) return NULL; } } - if (PyFile_WriteString("\n", outf) != 0) + if (newline == NULL) { + newline = PyUnicode_FromString("\n"); + if (newline == NULL) + return NULL; + } + if (PyFile_WriteObject(newline, outf, Py_PRINT_RAW) != 0) return NULL; if (_PyObject_SetAttrId(builtins, &PyId__, o) != 0) return NULL; @@ -332,12 +370,16 @@ static PyObject * call_trampoline(PyThreadState *tstate, PyObject* callback, PyFrameObject *frame, int what, PyObject *arg) { - PyObject *args = PyTuple_New(3); + PyObject *args; PyObject *whatstr; PyObject *result; + args = PyTuple_New(3); if (args == NULL) return NULL; + if (PyFrame_FastToLocalsWithError(frame) < 0) + return NULL; + Py_INCREF(frame); whatstr = whatstrings[what]; Py_INCREF(whatstr); @@ -349,7 +391,6 @@ call_trampoline(PyThreadState *tstate, PyObject* callback, PyTuple_SET_ITEM(args, 2, arg); /* call the Python-level function */ - PyFrame_FastToLocals(frame); result = PyEval_CallObject(callback, args); PyFrame_LocalsToFast(frame, 1); if (result == NULL) @@ -617,7 +658,7 @@ PyDoc_STRVAR(hash_info_doc, "hash_info\n\ \n\ A struct sequence providing parameters used for computing\n\ -numeric hashes. The attributes are read only."); +hashes. The attributes are read only."); static PyStructSequence_Field hash_info_fields[] = { {"width", "width of the type used for hashing, in bits"}, @@ -626,6 +667,11 @@ static PyStructSequence_Field hash_info_fields[] = { {"inf", "value to be used for hash of a positive infinity"}, {"nan", "value to be used for hash of a nan"}, {"imag", "multiplier used for the imaginary part of a complex number"}, + {"algorithm", "name of the algorithm for hashing of str, bytes and " + "memoryviews"}, + {"hash_bits", "internal output size of hash algorithm"}, + {"seed_bits", "seed size of hash algorithm"}, + {"cutoff", "small string optimization cutoff"}, {NULL, NULL} }; @@ -633,7 +679,7 @@ static PyStructSequence_Desc hash_info_desc = { "sys.hash_info", hash_info_doc, hash_info_fields, - 5, + 9, }; static PyObject * @@ -641,9 +687,11 @@ get_hash_info(void) { PyObject *hash_info; int field = 0; + PyHash_FuncDef *hashfunc; hash_info = PyStructSequence_New(&Hash_InfoType); if (hash_info == NULL) return NULL; + hashfunc = PyHash_GetFuncDef(); PyStructSequence_SET_ITEM(hash_info, field++, PyLong_FromLong(8*sizeof(Py_hash_t))); PyStructSequence_SET_ITEM(hash_info, field++, @@ -654,6 +702,14 @@ get_hash_info(void) PyLong_FromLong(_PyHASH_NAN)); PyStructSequence_SET_ITEM(hash_info, field++, PyLong_FromLong(_PyHASH_IMAG)); + PyStructSequence_SET_ITEM(hash_info, field++, + PyUnicode_FromString(hashfunc->name)); + PyStructSequence_SET_ITEM(hash_info, field++, + PyLong_FromLong(hashfunc->hash_bits)); + PyStructSequence_SET_ITEM(hash_info, field++, + PyLong_FromLong(hashfunc->seed_bits)); + PyStructSequence_SET_ITEM(hash_info, field++, + PyLong_FromLong(Py_HASH_CUTOFF)); if (PyErr_Occurred()) { Py_CLEAR(hash_info); return NULL; @@ -818,7 +874,6 @@ sys_getsizeof(PyObject *self, PyObject *args, PyObject *kwds) static char *kwlist[] = {"object", "default", 0}; PyObject *o, *dflt = NULL; PyObject *method; - _Py_IDENTIFIER(__sizeof__); if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|O:getsizeof", kwlist, &o, &dflt)) @@ -1298,6 +1353,7 @@ exec_prefix -- prefix used to find the machine-specific Python library\n\ executable -- absolute path of the executable binary of the Python interpreter\n\ float_info -- a struct sequence with information about the float implementation.\n\ float_repr_style -- string indicating the style of repr() output for floats\n\ +hash_info -- a struct sequence with information about the hash algorithm.\n\ hexversion -- version information encoded as a single integer\n\ implementation -- Python implementation information.\n\ int_info -- a struct sequence with information about the int implementation.\n\ @@ -1573,6 +1629,17 @@ _PySys_Init(void) if (m == NULL) return NULL; sysdict = PyModule_GetDict(m); +#define SET_SYS_FROM_STRING_BORROW(key, value) \ + do { \ + int res; \ + PyObject *v = (value); \ + if (v == NULL) \ + return NULL; \ + res = PyDict_SetItemString(sysdict, key, v); \ + if (res < 0) { \ + return NULL; \ + } \ + } while (0) #define SET_SYS_FROM_STRING(key, value) \ do { \ int res; \ @@ -1580,8 +1647,8 @@ _PySys_Init(void) if (v == NULL) \ return NULL; \ res = PyDict_SetItemString(sysdict, key, v); \ + Py_DECREF(v); \ if (res < 0) { \ - Py_DECREF(v); \ return NULL; \ } \ } while (0) @@ -1606,10 +1673,10 @@ _PySys_Init(void) /* stdin/stdout/stderr are now set by pythonrun.c */ - SET_SYS_FROM_STRING("__displayhook__", - PyDict_GetItemString(sysdict, "displayhook")); - SET_SYS_FROM_STRING("__excepthook__", - PyDict_GetItemString(sysdict, "excepthook")); + SET_SYS_FROM_STRING_BORROW("__displayhook__", + PyDict_GetItemString(sysdict, "displayhook")); + SET_SYS_FROM_STRING_BORROW("__excepthook__", + PyDict_GetItemString(sysdict, "excepthook")); SET_SYS_FROM_STRING("version", PyUnicode_FromString(Py_GetVersion())); SET_SYS_FROM_STRING("hexversion", @@ -1679,9 +1746,9 @@ _PySys_Init(void) else { Py_INCREF(warnoptions); } - SET_SYS_FROM_STRING("warnoptions", warnoptions); + SET_SYS_FROM_STRING_BORROW("warnoptions", warnoptions); - SET_SYS_FROM_STRING("_xoptions", get_xoptions()); + SET_SYS_FROM_STRING_BORROW("_xoptions", get_xoptions()); /* version_info */ if (VersionInfoType.tp_name == NULL) { @@ -1778,7 +1845,7 @@ PySys_SetPath(const wchar_t *path) PyObject *v; if ((v = makepathobject(path, DELIM)) == NULL) Py_FatalError("can't create sys.path"); - if (PySys_SetObject("path", v) != 0) + if (_PySys_SetObjectId(&PyId_path, v) != 0) Py_FatalError("can't assign sys.path"); Py_DECREF(v); } @@ -1847,7 +1914,7 @@ sys_update_path(int argc, wchar_t **argv) wchar_t fullpath[MAX_PATH]; #endif - path = PySys_GetObject("path"); + path = _PySys_GetObjectId(&PyId_path); if (path == NULL) return; @@ -1908,7 +1975,7 @@ sys_update_path(int argc, wchar_t **argv) #else /* All other filename syntaxes */ if (_HAVE_SCRIPT_ARGUMENT(argc, argv)) { #if defined(HAVE_REALPATH) - if (_Py_wrealpath(argv0, fullpath, PATH_MAX)) { + if (_Py_wrealpath(argv0, fullpath, Py_ARRAY_LENGTH(fullpath))) { argv0 = fullpath; } #endif @@ -1957,7 +2024,6 @@ sys_pyfile_write_unicode(PyObject *unicode, PyObject *file) { PyObject *writer = NULL, *args = NULL, *result = NULL; int err; - _Py_IDENTIFIER(write); if (file == NULL) return -1; @@ -2034,7 +2100,7 @@ sys_pyfile_write(const char *text, PyObject *file) */ static void -sys_write(char *name, FILE *fp, const char *format, va_list va) +sys_write(_Py_Identifier *key, FILE *fp, const char *format, va_list va) { PyObject *file; PyObject *error_type, *error_value, *error_traceback; @@ -2042,7 +2108,7 @@ sys_write(char *name, FILE *fp, const char *format, va_list va) int written; PyErr_Fetch(&error_type, &error_value, &error_traceback); - file = PySys_GetObject(name); + file = _PySys_GetObjectId(key); written = PyOS_vsnprintf(buffer, sizeof(buffer), format, va); if (sys_pyfile_write(buffer, file) != 0) { PyErr_Clear(); @@ -2062,7 +2128,7 @@ PySys_WriteStdout(const char *format, ...) va_list va; va_start(va, format); - sys_write("stdout", stdout, format, va); + sys_write(&PyId_stdout, stdout, format, va); va_end(va); } @@ -2072,19 +2138,19 @@ PySys_WriteStderr(const char *format, ...) va_list va; va_start(va, format); - sys_write("stderr", stderr, format, va); + sys_write(&PyId_stderr, stderr, format, va); va_end(va); } static void -sys_format(char *name, FILE *fp, const char *format, va_list va) +sys_format(_Py_Identifier *key, FILE *fp, const char *format, va_list va) { PyObject *file, *message; PyObject *error_type, *error_value, *error_traceback; char *utf8; PyErr_Fetch(&error_type, &error_value, &error_traceback); - file = PySys_GetObject(name); + file = _PySys_GetObjectId(key); message = PyUnicode_FromFormatV(format, va); if (message != NULL) { if (sys_pyfile_write_unicode(message, file) != 0) { @@ -2104,7 +2170,7 @@ PySys_FormatStdout(const char *format, ...) va_list va; va_start(va, format); - sys_format("stdout", stdout, format, va); + sys_format(&PyId_stdout, stdout, format, va); va_end(va); } @@ -2114,6 +2180,6 @@ PySys_FormatStderr(const char *format, ...) va_list va; va_start(va, format); - sys_format("stderr", stderr, format, va); + sys_format(&PyId_stderr, stderr, format, va); va_end(va); } |