diff options
Diffstat (limited to 'Python/sysmodule.c')
| -rw-r--r-- | Python/sysmodule.c | 314 | 
1 files changed, 191 insertions, 123 deletions
| diff --git a/Python/sysmodule.c b/Python/sysmodule.c index e73e5c2..814eccb 100644 --- a/Python/sysmodule.c +++ b/Python/sysmodule.c @@ -126,7 +126,7 @@ sys_displayhook(PyObject *self, PyObject *o)  PyDoc_STRVAR(displayhook_doc,  "displayhook(object) -> None\n"  "\n" -"Print an object to sys.stdout and also save it in __builtin__.\n" +"Print an object to sys.stdout and also save it in __builtin__._\n"  );  static PyObject * @@ -466,6 +466,7 @@ sys_setcheckinterval(PyObject *self, PyObject *args)  {      if (!PyArg_ParseTuple(args, "i:setcheckinterval", &_Py_CheckInterval))          return NULL; +    _Py_Ticker = _Py_CheckInterval;      Py_INCREF(Py_None);      return Py_None;  } @@ -557,26 +558,65 @@ recursion from causing an overflow of the C stack and crashing Python."  PyDoc_STRVAR(getwindowsversion_doc,  "getwindowsversion()\n\  \n\ -Return information about the running version of Windows.\n\ -The result is a tuple of (major, minor, build, platform, text)\n\ -All elements are numbers, except text which is a string.\n\ -Platform may be 0 for win32s, 1 for Windows 9x/ME, 2 for Windows NT/2000/XP\n\ -" +Return information about the running version of Windows as a named tuple.\n\ +The members are named: major, minor, build, platform, service_pack,\n\ +service_pack_major, service_pack_minor, suite_mask, and product_type. For\n\ +backward compatibility, only the first 5 items are available by indexing.\n\ +All elements are numbers, except service_pack which is a string. Platform\n\ +may be 0 for win32s, 1 for Windows 9x/ME, 2 for Windows NT/2000/XP/Vista/7,\n\ +3 for Windows CE. Product_type may be 1 for a workstation, 2 for a domain\n\ +controller, 3 for a server."  ); +static PyTypeObject WindowsVersionType = {0, 0, 0, 0, 0, 0}; + +static PyStructSequence_Field windows_version_fields[] = { +    {"major", "Major version number"}, +    {"minor", "Minor version number"}, +    {"build", "Build number"}, +    {"platform", "Operating system platform"}, +    {"service_pack", "Latest Service Pack installed on the system"}, +    {"service_pack_major", "Service Pack major version number"}, +    {"service_pack_minor", "Service Pack minor version number"}, +    {"suite_mask", "Bit mask identifying available product suites"}, +    {"product_type", "System product type"}, +    {0} +}; + +static PyStructSequence_Desc windows_version_desc = { +    "sys.getwindowsversion",  /* name */ +    getwindowsversion_doc,    /* doc */ +    windows_version_fields,   /* fields */ +    5                         /* For backward compatibility, +                                 only the first 5 items are accessible +                                 via indexing, the rest are name only */ +}; +  static PyObject *  sys_getwindowsversion(PyObject *self)  { -    OSVERSIONINFO ver; +    PyObject *version; +    int pos = 0; +    OSVERSIONINFOEX ver;      ver.dwOSVersionInfoSize = sizeof(ver); -    if (!GetVersionEx(&ver)) +    if (!GetVersionEx((OSVERSIONINFO*) &ver))          return PyErr_SetFromWindowsErr(0); -    return Py_BuildValue("HHHHs", -                         ver.dwMajorVersion, -                         ver.dwMinorVersion, -                         ver.dwBuildNumber, -                         ver.dwPlatformId, -                         ver.szCSDVersion); + +    version = PyStructSequence_New(&WindowsVersionType); +    if (version == NULL) +        return NULL; + +    PyStructSequence_SET_ITEM(version, pos++, PyInt_FromLong(ver.dwMajorVersion)); +    PyStructSequence_SET_ITEM(version, pos++, PyInt_FromLong(ver.dwMinorVersion)); +    PyStructSequence_SET_ITEM(version, pos++, PyInt_FromLong(ver.dwBuildNumber)); +    PyStructSequence_SET_ITEM(version, pos++, PyInt_FromLong(ver.dwPlatformId)); +    PyStructSequence_SET_ITEM(version, pos++, PyString_FromString(ver.szCSDVersion)); +    PyStructSequence_SET_ITEM(version, pos++, PyInt_FromLong(ver.wServicePackMajor)); +    PyStructSequence_SET_ITEM(version, pos++, PyInt_FromLong(ver.wServicePackMinor)); +    PyStructSequence_SET_ITEM(version, pos++, PyInt_FromLong(ver.wSuiteMask)); +    PyStructSequence_SET_ITEM(version, pos++, PyInt_FromLong(ver.wProductType)); + +    return version;  }  #endif /* MS_WINDOWS */ @@ -599,12 +639,14 @@ sys_setdlopenflags(PyObject *self, PyObject *args)  PyDoc_STRVAR(setdlopenflags_doc,  "setdlopenflags(n) -> None\n\  \n\ -Set the flags that will be used for dlopen() calls. Among other\n\ -things, this will enable a lazy resolving of symbols when importing\n\ -a module, if called as sys.setdlopenflags(0)\n\ -To share symbols across extension modules, call as\n\ -sys.setdlopenflags(dl.RTLD_NOW|dl.RTLD_GLOBAL)" -); +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\ +can be either found in the ctypes module, or in the DLFCN module. If DLFCN\n\ +is not available, it can be generated from /usr/include/dlfcn.h using the\n\ +h2py script.");  static PyObject *  sys_getdlopenflags(PyObject *self, PyObject *args) @@ -618,10 +660,10 @@ sys_getdlopenflags(PyObject *self, PyObject *args)  PyDoc_STRVAR(getdlopenflags_doc,  "getdlopenflags() -> int\n\  \n\ -Return the current value of the flags that are used for dlopen()\n\ -calls. The flag constants are defined in the dl module." -); -#endif +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."); + +#endif  /* HAVE_DLOPEN */  #ifdef USE_MALLOPT  /* Link with -lmalloc (or -lmpc) on an SGI */ @@ -643,7 +685,7 @@ static PyObject *  sys_getsizeof(PyObject *self, PyObject *args, PyObject *kwds)  {      PyObject *res = NULL; -    static PyObject *str__sizeof__, *gc_head_size = NULL; +    static PyObject *str__sizeof__ = NULL, *gc_head_size = NULL;      static char *kwlist[] = {"object", "default", 0};      PyObject *o, *dflt = NULL; @@ -651,13 +693,6 @@ sys_getsizeof(PyObject *self, PyObject *args, PyObject *kwds)                                       kwlist, &o, &dflt))          return NULL; -    /* Initialize static variable needed by _PyType_Lookup */ -    if (str__sizeof__ == NULL) { -        str__sizeof__ = PyString_InternFromString("__sizeof__"); -        if (str__sizeof__ == NULL) -            return NULL; -    } -      /* Initialize static variable for GC head size */      if (gc_head_size == NULL) {          gc_head_size = PyInt_FromSsize_t(sizeof(PyGC_Head)); @@ -674,14 +709,18 @@ sys_getsizeof(PyObject *self, PyObject *args, PyObject *kwds)          res = PyInt_FromSsize_t(PyInstance_Type.tp_basicsize);      /* all other objects */      else { -        PyObject *method = _PyType_Lookup(Py_TYPE(o), -                                          str__sizeof__); -        if (method == NULL) -            PyErr_Format(PyExc_TypeError, -                         "Type %.100s doesn't define __sizeof__", -                         Py_TYPE(o)->tp_name); -        else -            res = PyObject_CallFunctionObjArgs(method, o, NULL); +        PyObject *method = _PyObject_LookupSpecial(o, "__sizeof__", +                                                   &str__sizeof__); +        if (method == NULL) { +            if (!PyErr_Occurred()) +                PyErr_Format(PyExc_TypeError, +                             "Type %.100s doesn't define __sizeof__", +                             Py_TYPE(o)->tp_name); +        } +        else { +            res = PyObject_CallFunctionObjArgs(method, NULL); +            Py_DECREF(method); +        }      }      /* Has a default value been given? */ @@ -1043,18 +1082,21 @@ PyDoc_STR(  "\n\  Static objects:\n\  \n\ +float_info -- a dict with information about the float inplementation.\n\ +long_info -- a struct sequence with information about the long implementation.\n\  maxint -- the largest supported integer (the smallest is -maxint-1)\n\  maxsize -- the largest supported length of containers.\n\  maxunicode -- the largest supported character\n\  builtin_module_names -- tuple of module names built into this interpreter\n\  version -- the version of this interpreter as a string\n\ -version_info -- version information as a tuple\n\ +version_info -- version information as a named tuple\n\  hexversion -- version information encoded as a single integer\n\  copyright -- copyright notice pertaining to this interpreter\n\  platform -- platform identifier\n\ -executable -- pathname of this Python interpreter\n\ +executable -- absolute path of the executable binary of the Python interpreter\n\  prefix -- prefix used to find the Python library\n\  exec_prefix -- prefix used to find the machine-specific Python library\n\ +float_repr_style -- string indicating the style of repr() output for floats\n\  "  )  #ifdef MS_WINDOWS @@ -1102,8 +1144,6 @@ _check_and_flush (FILE *stream)  }  /* Subversion branch and revision management */ -static const char _patchlevel_revision[] = PY_PATCHLEVEL_REVISION; -static const char headurl[] = "$HeadURL$";  static int svn_initialized;  static char patchlevel_revision[50]; /* Just the number */  static char branch[50]; @@ -1113,69 +1153,14 @@ static const char *svn_revision;  static void  svnversion_init(void)  { -    const char *python, *br_start, *br_end, *br_end2, *svnversion; -    Py_ssize_t len; -    int istag; -      if (svn_initialized)          return; - -    python = strstr(headurl, "/python/"); -    if (!python) { -        /* XXX quick hack to get bzr working */ -        *patchlevel_revision = '\0'; -        strcpy(branch, ""); -        strcpy(shortbranch, "unknown"); -        svn_revision = ""; -        return; -        /* Py_FatalError("subversion keywords missing"); */ -    } - -    br_start = python + 8; -    br_end = strchr(br_start, '/'); -    assert(br_end); - -    /* Works even for trunk, -       as we are in trunk/Python/sysmodule.c */ -    br_end2 = strchr(br_end+1, '/'); - -    istag = strncmp(br_start, "tags", 4) == 0; -    if (strncmp(br_start, "trunk", 5) == 0) { -        strcpy(branch, "trunk"); -        strcpy(shortbranch, "trunk"); - -    } -    else if (istag || strncmp(br_start, "branches", 8) == 0) { -        len = br_end2 - br_start; -        strncpy(branch, br_start, len); -        branch[len] = '\0'; - -        len = br_end2 - (br_end + 1); -        strncpy(shortbranch, br_end + 1, len); -        shortbranch[len] = '\0'; -    } -    else { -        Py_FatalError("bad HeadURL"); -        return; -    } - - -    svnversion = _Py_svnversion(); -    if (strcmp(svnversion, "Unversioned directory") != 0 && strcmp(svnversion, "exported") != 0) -        svn_revision = svnversion; -    else if (istag) { -        len = strlen(_patchlevel_revision); -        assert(len >= 13); -        assert(len < (sizeof(patchlevel_revision) + 13)); -        strncpy(patchlevel_revision, _patchlevel_revision + 11, -            len - 13); -        patchlevel_revision[len - 13] = '\0'; -        svn_revision = patchlevel_revision; -    } -    else -        svn_revision = ""; -      svn_initialized = 1; +    *patchlevel_revision = '\0'; +    strcpy(branch, ""); +    strcpy(shortbranch, "unknown"); +    svn_revision = ""; +    return;  }  /* Return svnversion output if available. @@ -1281,6 +1266,75 @@ make_flags(void)      return seq;  } +PyDoc_STRVAR(version_info__doc__, +"sys.version_info\n\ +\n\ +Version information as a named tuple."); + +static PyTypeObject VersionInfoType = {0, 0, 0, 0, 0, 0}; + +static PyStructSequence_Field version_info_fields[] = { +    {"major", "Major release number"}, +    {"minor", "Minor release number"}, +    {"micro", "Patch release number"}, +    {"releaselevel", "'alpha', 'beta', 'candidate', or 'release'"}, +    {"serial", "Serial release number"}, +    {0} +}; + +static PyStructSequence_Desc version_info_desc = { +    "sys.version_info",     /* name */ +    version_info__doc__,    /* doc */ +    version_info_fields,    /* fields */ +    5 +}; + +static PyObject * +make_version_info(void) +{ +    PyObject *version_info; +    char *s; +    int pos = 0; + +    version_info = PyStructSequence_New(&VersionInfoType); +    if (version_info == NULL) { +        return NULL; +    } + +    /* +     * These release level checks are mutually exclusive and cover +     * the field, so don't get too fancy with the pre-processor! +     */ +#if PY_RELEASE_LEVEL == PY_RELEASE_LEVEL_ALPHA +    s = "alpha"; +#elif PY_RELEASE_LEVEL == PY_RELEASE_LEVEL_BETA +    s = "beta"; +#elif PY_RELEASE_LEVEL == PY_RELEASE_LEVEL_GAMMA +    s = "candidate"; +#elif PY_RELEASE_LEVEL == PY_RELEASE_LEVEL_FINAL +    s = "final"; +#endif + +#define SetIntItem(flag) \ +    PyStructSequence_SET_ITEM(version_info, pos++, PyInt_FromLong(flag)) +#define SetStrItem(flag) \ +    PyStructSequence_SET_ITEM(version_info, pos++, PyString_FromString(flag)) + +    SetIntItem(PY_MAJOR_VERSION); +    SetIntItem(PY_MINOR_VERSION); +    SetIntItem(PY_MICRO_VERSION); +    SetStrItem(s); +    SetIntItem(PY_RELEASE_SERIAL); +#undef SetIntItem +#undef SetStrItem + +    if (PyErr_Occurred()) { +        Py_CLEAR(version_info); +        return NULL; +    } +    return version_info; +} +  PyObject *  _PySys_Init(void)  { @@ -1354,27 +1408,11 @@ _PySys_Init(void)      SET_SYS_FROM_STRING("subversion",                           Py_BuildValue("(ssz)", "CPython", branch,                                        svn_revision)); +    SET_SYS_FROM_STRING("_mercurial", +                        Py_BuildValue("(szz)", "CPython", _Py_hgidentifier(), +                                      _Py_hgversion()));      SET_SYS_FROM_STRING("dont_write_bytecode",                           PyBool_FromLong(Py_DontWriteBytecodeFlag)); -    /* -     * These release level checks are mutually exclusive and cover -     * the field, so don't get too fancy with the pre-processor! -     */ -#if PY_RELEASE_LEVEL == PY_RELEASE_LEVEL_ALPHA -    s = "alpha"; -#elif PY_RELEASE_LEVEL == PY_RELEASE_LEVEL_BETA -    s = "beta"; -#elif PY_RELEASE_LEVEL == PY_RELEASE_LEVEL_GAMMA -    s = "candidate"; -#elif PY_RELEASE_LEVEL == PY_RELEASE_LEVEL_FINAL -    s = "final"; -#endif - -    SET_SYS_FROM_STRING("version_info", -                        Py_BuildValue("iiisi", PY_MAJOR_VERSION, -                                           PY_MINOR_VERSION, -                                           PY_MICRO_VERSION, s, -                                           PY_RELEASE_SERIAL));      SET_SYS_FROM_STRING("api_version",                          PyInt_FromLong(PYTHON_API_VERSION));      SET_SYS_FROM_STRING("copyright", @@ -1395,6 +1433,8 @@ _PySys_Init(void)                          PyBool_FromLong(Py_Py3kWarningFlag));      SET_SYS_FROM_STRING("float_info",                          PyFloat_GetInfo()); +    SET_SYS_FROM_STRING("long_info", +                        PyLong_GetInfo());  #ifdef Py_USING_UNICODE      SET_SYS_FROM_STRING("maxunicode",                          PyInt_FromLong(PyUnicode_GetMax())); @@ -1431,6 +1471,15 @@ _PySys_Init(void)          PyDict_SetItemString(sysdict, "warnoptions", warnoptions);      } +    /* version_info */ +    if (VersionInfoType.tp_name == 0) +        PyStructSequence_InitType(&VersionInfoType, &version_info_desc); +    SET_SYS_FROM_STRING("version_info", make_version_info()); +    /* prevent user from creating new instances */ +    VersionInfoType.tp_init = NULL; +    VersionInfoType.tp_new = NULL; + +    /* flags */      if (FlagsType.tp_name == 0)          PyStructSequence_InitType(&FlagsType, &flags_desc);      SET_SYS_FROM_STRING("flags", make_flags()); @@ -1438,6 +1487,25 @@ _PySys_Init(void)      FlagsType.tp_init = NULL;      FlagsType.tp_new = NULL; + +#if defined(MS_WINDOWS) +    /* getwindowsversion */ +    if (WindowsVersionType.tp_name == 0) +        PyStructSequence_InitType(&WindowsVersionType, &windows_version_desc); +    /* prevent user from creating new instances */ +    WindowsVersionType.tp_init = NULL; +    WindowsVersionType.tp_new = NULL; +#endif + +    /* float repr style: 0.03 (short) vs 0.029999999999999999 (legacy) */ +#ifndef PY_NO_SHORT_FLOAT_REPR +    SET_SYS_FROM_STRING("float_repr_style", +                        PyString_FromString("short")); +#else +    SET_SYS_FROM_STRING("float_repr_style", +                        PyString_FromString("legacy")); +#endif +  #undef SET_SYS_FROM_STRING      if (PyErr_Occurred())          return NULL; | 
