summaryrefslogtreecommitdiff
path: root/Python/sysmodule.c
diff options
context:
space:
mode:
Diffstat (limited to 'Python/sysmodule.c')
-rw-r--r--Python/sysmodule.c314
1 files changed, 191 insertions, 123 deletions
diff --git a/Python/sysmodule.c b/Python/sysmodule.c
index e73e5c283e..814eccb157 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;