diff options
Diffstat (limited to 'Python/sysmodule.c')
| -rw-r--r-- | Python/sysmodule.c | 259 | 
1 files changed, 159 insertions, 100 deletions
| diff --git a/Python/sysmodule.c b/Python/sysmodule.c index 2f700e6..64de2bf 100644 --- a/Python/sysmodule.c +++ b/Python/sysmodule.c @@ -32,15 +32,31 @@ extern void *PyWin_DLLhModule;  extern const char *PyWin_DLLVersionString;  #endif -#ifdef __VMS -#include <unixlib.h> -#endif -  #ifdef HAVE_LANGINFO_H  #include <locale.h>  #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 +68,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 +110,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 +130,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 +165,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 +184,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 +202,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; @@ -329,15 +363,19 @@ trace_init(void)  static PyObject * -call_trampoline(PyThreadState *tstate, PyObject* callback, +call_trampoline(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 +387,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) @@ -364,12 +401,11 @@ static int  profile_trampoline(PyObject *self, PyFrameObject *frame,                     int what, PyObject *arg)  { -    PyThreadState *tstate = frame->f_tstate;      PyObject *result;      if (arg == NULL)          arg = Py_None; -    result = call_trampoline(tstate, self, frame, what, arg); +    result = call_trampoline(self, frame, what, arg);      if (result == NULL) {          PyEval_SetProfile(NULL, NULL);          return -1; @@ -382,7 +418,6 @@ static int  trace_trampoline(PyObject *self, PyFrameObject *frame,                   int what, PyObject *arg)  { -    PyThreadState *tstate = frame->f_tstate;      PyObject *callback;      PyObject *result; @@ -392,7 +427,7 @@ trace_trampoline(PyObject *self, PyFrameObject *frame,          callback = frame->f_trace;      if (callback == NULL)          return 0; -    result = call_trampoline(tstate, callback, frame, what, arg); +    result = call_trampoline(callback, frame, what, arg);      if (result == NULL) {          PyEval_SetTrace(NULL, NULL);          Py_CLEAR(frame->f_trace); @@ -616,7 +651,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"}, @@ -625,6 +660,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}  }; @@ -632,7 +672,7 @@ static PyStructSequence_Desc hash_info_desc = {      "sys.hash_info",      hash_info_doc,      hash_info_fields, -    5, +    9,  };  static PyObject * @@ -640,9 +680,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++, @@ -653,6 +695,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; @@ -777,7 +827,7 @@ Set the flags used by the interpreter for dlopen calls, such as when the\n\  interpreter loads extension modules.  Among other things, this will enable\n\  a lazy resolving of symbols when importing a module, if called as\n\  sys.setdlopenflags(0).  To share symbols across extension modules, call as\n\ -sys.setdlopenflags(ctypes.RTLD_GLOBAL).  Symbolic names for the flag modules\n\ +sys.setdlopenflags(os.RTLD_GLOBAL).  Symbolic names for the flag modules\n\  can be found in the os module (RTLD_xxx constants, e.g. os.RTLD_LAZY).");  static PyObject * @@ -793,7 +843,7 @@ PyDoc_STRVAR(getdlopenflags_doc,  "getdlopenflags() -> int\n\  \n\  Return the current value of the flags that are used for dlopen calls.\n\ -The flag constants are defined in the ctypes and DLFCN modules."); +The flag constants are defined in the os module.");  #endif  /* HAVE_DLOPEN */ @@ -821,7 +871,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)) @@ -897,6 +946,19 @@ one higher than you might expect, because it includes the (temporary)\n\  reference as an argument to getrefcount()."  ); +static PyObject * +sys_getallocatedblocks(PyObject *self) +{ +    return PyLong_FromSsize_t(_Py_GetAllocatedBlocks()); +} + +PyDoc_STRVAR(getallocatedblocks_doc, +"getallocatedblocks() -> integer\n\ +\n\ +Return the number of memory blocks currently allocated, regardless of their\n\ +size." +); +  #ifdef COUNT_ALLOCS  static PyObject *  sys_getcounts(PyObject *self) @@ -1065,6 +1127,8 @@ static PyMethodDef sys_methods[] = {      {"getdlopenflags", (PyCFunction)sys_getdlopenflags, METH_NOARGS,       getdlopenflags_doc},  #endif +    {"getallocatedblocks", (PyCFunction)sys_getallocatedblocks, METH_NOARGS, +      getallocatedblocks_doc},  #ifdef COUNT_ALLOCS      {"getcounts",       (PyCFunction)sys_getcounts, METH_NOARGS},  #endif @@ -1117,7 +1181,7 @@ static PyMethodDef sys_methods[] = {      {"settrace",        sys_settrace, METH_O, settrace_doc},      {"gettrace",        sys_gettrace, METH_NOARGS, gettrace_doc},      {"call_tracing", sys_call_tracing, METH_VARARGS, call_tracing_doc}, -    {"_debugmallocstats", sys_debugmallocstats, METH_VARARGS, +    {"_debugmallocstats", sys_debugmallocstats, METH_NOARGS,       debugmallocstats_doc},      {NULL,              NULL}           /* sentinel */  }; @@ -1286,6 +1350,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\ @@ -1352,14 +1417,12 @@ static PyStructSequence_Field flags_fields[] = {      {"no_site",                 "-S"},      {"ignore_environment",      "-E"},      {"verbose",                 "-v"}, -#ifdef RISCOS -    {"riscos_wimp",             "???"}, -#endif      /* {"unbuffered",                   "-u"}, */      /* {"skip_first",                   "-x"}, */      {"bytes_warning",           "-b"},      {"quiet",                   "-q"},      {"hash_randomization",      "-R"}, +    {"isolated",                "-I"},      {0}  }; @@ -1367,11 +1430,7 @@ static PyStructSequence_Desc flags_desc = {      "sys.flags",        /* name */      flags__doc__,       /* doc */      flags_fields,       /* fields */ -#ifdef RISCOS      13 -#else -    12 -#endif  };  static PyObject* @@ -1396,14 +1455,12 @@ make_flags(void)      SetFlag(Py_NoSiteFlag);      SetFlag(Py_IgnoreEnvironmentFlag);      SetFlag(Py_VerboseFlag); -#ifdef RISCOS -    SetFlag(Py_RISCOSWimpFlag); -#endif      /* SetFlag(saw_unbuffered_flag); */      /* SetFlag(skipfirstline); */      SetFlag(Py_BytesWarningFlag);      SetFlag(Py_QuietFlag);      SetFlag(Py_HashRandomizationFlag); +    SetFlag(Py_IsolatedFlag);  #undef SetFlag      if (PyErr_Occurred()) { @@ -1564,18 +1621,35 @@ static struct PyModuleDef sysmodule = {  PyObject *  _PySys_Init(void)  { -    PyObject *m, *v, *sysdict, *version_info; -    char *s; +    PyObject *m, *sysdict, *version_info;      m = PyModule_Create(&sysmodule);      if (m == NULL)          return NULL;      sysdict = PyModule_GetDict(m); -#define SET_SYS_FROM_STRING(key, value)                 \ -    v = value;                                          \ -    if (v != NULL)                                      \ -        PyDict_SetItemString(sysdict, key, v);          \ -    Py_XDECREF(v) +#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;                                           \ +        PyObject *v = (value);                             \ +        if (v == NULL)                                     \ +            return NULL;                                   \ +        res = PyDict_SetItemString(sysdict, key, v);       \ +        Py_DECREF(v);                                      \ +        if (res < 0) {                                     \ +            return NULL;                                   \ +        }                                                  \ +    } while (0)      /* Check that stdin is not a directory      Using shell redirection, you can redirect stdin to a directory, @@ -1597,10 +1671,10 @@ _PySys_Init(void)      /* stdin/stdout/stderr are now set by pythonrun.c */ -    PyDict_SetItemString(sysdict, "__displayhook__", -                         PyDict_GetItemString(sysdict, "displayhook")); -    PyDict_SetItemString(sysdict, "__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", @@ -1634,28 +1708,24 @@ _PySys_Init(void)      SET_SYS_FROM_STRING("int_info",                          PyLong_GetInfo());      /* initialize hash_info */ -    if (Hash_InfoType.tp_name == 0) -        PyStructSequence_InitType(&Hash_InfoType, &hash_info_desc); +    if (Hash_InfoType.tp_name == NULL) { +        if (PyStructSequence_InitType2(&Hash_InfoType, &hash_info_desc) < 0) +            return NULL; +    }      SET_SYS_FROM_STRING("hash_info",                          get_hash_info());      SET_SYS_FROM_STRING("maxunicode",                          PyLong_FromLong(0x10FFFF));      SET_SYS_FROM_STRING("builtin_module_names",                          list_builtin_module_names()); -    { -        /* Assumes that longs are at least 2 bytes long. -           Should be safe! */ -        unsigned long number = 1; -        char *value; - -        s = (char *) &number; -        if (s[0] == 0) -            value = "big"; -        else -            value = "little"; -        SET_SYS_FROM_STRING("byteorder", -                            PyUnicode_FromString(value)); -    } +#if PY_BIG_ENDIAN +    SET_SYS_FROM_STRING("byteorder", +                        PyUnicode_FromString("big")); +#else +    SET_SYS_FROM_STRING("byteorder", +                        PyUnicode_FromString("little")); +#endif +  #ifdef MS_COREDLL      SET_SYS_FROM_STRING("dllhandle",                          PyLong_FromVoidPtr(PyWin_DLLhModule)); @@ -1668,22 +1738,22 @@ _PySys_Init(void)  #endif      if (warnoptions == NULL) {          warnoptions = PyList_New(0); +        if (warnoptions == NULL) +            return NULL;      }      else {          Py_INCREF(warnoptions);      } -    if (warnoptions != NULL) { -        PyDict_SetItemString(sysdict, "warnoptions", warnoptions); -    } +    SET_SYS_FROM_STRING_BORROW("warnoptions", warnoptions); -    v = get_xoptions(); -    if (v != NULL) { -        PyDict_SetItemString(sysdict, "_xoptions", v); -    } +    SET_SYS_FROM_STRING_BORROW("_xoptions", get_xoptions());      /* version_info */ -    if (VersionInfoType.tp_name == 0) -        PyStructSequence_InitType(&VersionInfoType, &version_info_desc); +    if (VersionInfoType.tp_name == NULL) { +        if (PyStructSequence_InitType2(&VersionInfoType, +                                       &version_info_desc) < 0) +            return NULL; +    }      version_info = make_version_info();      SET_SYS_FROM_STRING("version_info", version_info);      /* prevent user from creating new instances */ @@ -1694,8 +1764,10 @@ _PySys_Init(void)      SET_SYS_FROM_STRING("implementation", make_impl_info(version_info));      /* flags */ -    if (FlagsType.tp_name == 0) -        PyStructSequence_InitType(&FlagsType, &flags_desc); +    if (FlagsType.tp_name == 0) { +        if (PyStructSequence_InitType2(&FlagsType, &flags_desc) < 0) +            return NULL; +    }      SET_SYS_FROM_STRING("flags", make_flags());      /* prevent user from creating new instances */      FlagsType.tp_init = NULL; @@ -1705,7 +1777,9 @@ _PySys_Init(void)  #if defined(MS_WINDOWS)      /* getwindowsversion */      if (WindowsVersionType.tp_name == 0) -        PyStructSequence_InitType(&WindowsVersionType, &windows_version_desc); +        if (PyStructSequence_InitType2(&WindowsVersionType, +                                       &windows_version_desc) < 0) +            return NULL;      /* prevent user from creating new instances */      WindowsVersionType.tp_init = NULL;      WindowsVersionType.tp_new = NULL; @@ -1725,6 +1799,7 @@ _PySys_Init(void)  #endif  #undef SET_SYS_FROM_STRING +#undef SET_SYS_FROM_STRING_BORROW      if (PyErr_Occurred())          return NULL;      return m; @@ -1769,7 +1844,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);  } @@ -1788,22 +1863,7 @@ makeargvobject(int argc, wchar_t **argv)      if (av != NULL) {          int i;          for (i = 0; i < argc; i++) { -#ifdef __VMS -            PyObject *v; - -            /* argv[0] is the script pathname if known */ -            if (i == 0) { -                char* fn = decc$translate_vms(argv[0]); -                if ((fn == (char *)0) || fn == (char *)-1) -                    v = PyUnicode_FromString(argv[0]); -                else -                    v = PyUnicode_FromString( -                        decc$translate_vms(argv[0])); -            } else -                v = PyUnicode_FromString(argv[i]); -#else              PyObject *v = PyUnicode_FromWideChar(argv[i], -1); -#endif              if (v == NULL) {                  Py_DECREF(av);                  av = NULL; @@ -1838,7 +1898,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; @@ -1937,7 +1997,7 @@ PySys_SetArgvEx(int argc, wchar_t **argv, int updatepath)  void  PySys_SetArgv(int argc, wchar_t **argv)  { -    PySys_SetArgvEx(argc, argv, 1); +    PySys_SetArgvEx(argc, argv, Py_IsolatedFlag == 0);  }  /* Reimplementation of PyFile_WriteString() no calling indirectly @@ -1948,7 +2008,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; @@ -2025,7 +2084,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; @@ -2033,7 +2092,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(); @@ -2053,7 +2112,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);  } @@ -2063,19 +2122,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) { @@ -2095,7 +2154,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);  } @@ -2105,6 +2164,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);  } | 
