summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Doc/c-api/concrete.rst2
-rw-r--r--Doc/glossary.rst16
-rw-r--r--Doc/library/functions.rst15
-rw-r--r--Doc/library/sys.rst42
-rwxr-xr-xLib/pydoc.py8
-rw-r--r--Lib/test/test_structseq.py6
-rw-r--r--Lib/test/test_sys.py13
-rw-r--r--Modules/_ctypes/_ctypes.c2
-rw-r--r--Modules/_ctypes/stgdict.c2
-rw-r--r--Modules/socketmodule.c11
-rw-r--r--Objects/floatobject.c106
-rw-r--r--Objects/structseq.c82
-rw-r--r--Python/sysmodule.c91
13 files changed, 336 insertions, 60 deletions
diff --git a/Doc/c-api/concrete.rst b/Doc/c-api/concrete.rst
index a2aaeea..cc5c9d5 100644
--- a/Doc/c-api/concrete.rst
+++ b/Doc/c-api/concrete.rst
@@ -433,7 +433,7 @@ Floating Point Objects
.. cfunction:: PyObject* PyFloat_GetInfo(void)
- Return a :ctype:`PyDictObject` object which contains information about the
+ Return a structseq instance which contains information about the
precision, minimum and maximum values of a float. It's a thin wrapper
around the header file :file:`float.h`.
diff --git a/Doc/glossary.rst b/Doc/glossary.rst
index 194fbd9..5c11ae0 100644
--- a/Doc/glossary.rst
+++ b/Doc/glossary.rst
@@ -329,11 +329,17 @@ Glossary
also :term:`immutable`.
named tuple
- A tuple subclass whose elements also are accessible as attributes via
- fixed names (the class name and field names are indicated in the
- individual documentation of a named tuple type, like ``TestResults(failed,
- attempted)``). Named tuple classes are created by
- :func:`collections.namedtuple`.
+ Any tuple-like class whose indexable fields are also accessible with
+ named attributes (for example, :func:`time.localtime` returns a
+ tuple-like object where the *year* is accessible either with an
+ index such as ``t[0]`` or with a named attribute like ``t.tm_year``).
+
+ A named tuple can be a built-in type such as :class:`time.struct_time`,
+ or it can be created with a regular class definition. A full featured
+ named tuple can also be created with the factory function
+ :func:`collections.namedtuple`. The latter approach automatically
+ provides extra features such as a self-documenting representation like
+ ``Employee(name='jones', title='programmer')``.
namespace
The place where a variable is stored. Namespaces are implemented as
diff --git a/Doc/library/functions.rst b/Doc/library/functions.rst
index e7add3a..731afb4 100644
--- a/Doc/library/functions.rst
+++ b/Doc/library/functions.rst
@@ -743,10 +743,17 @@ available. They are listed here in alphabetical order.
* 'U' universal newline mode (for backwards compatibility;
unnecessary in new code)
- Combine ``'b'`` with ``'r'``, ``'w'``, or ``'a'``, for binary
- mode, e.g., ``'rb'`` to open a file for reading in binary mode.
- Modes ``'r+'``, ``'w+'`` and ``'a+'`` open the file for updating (note
- that ``'w+'`` truncates the file).
+ The most commonly-used values of *mode* are ``'r'`` for reading, ``'w'`` for
+ writing (truncating the file if it already exists), and ``'a'`` for appending
+ (which on *some* Unix systems means that *all* writes append to the end of the
+ file regardless of the current seek position). If *mode* is omitted, it
+ defaults to ``'r'``. The default is to use text mode, which may convert
+ ``'\n'`` characters to a platform-specific representation on writing and back
+ on reading. Thus, when opening a binary file, you should append ``'b'`` to
+ the *mode* value to open the file in binary mode, which will improve
+ portability. (Appending ``'b'`` is useful even on systems that don't treat
+ binary and text files differently, where it serves as documentation.) See below
+ for more possible values of *mode*.
Python distinguishes between files opened in binary and text modes, even
when the underlying operating system doesn't. Files opened in binary
diff --git a/Doc/library/sys.rst b/Doc/library/sys.rst
index 85c592e..4ab3529 100644
--- a/Doc/library/sys.rst
+++ b/Doc/library/sys.rst
@@ -184,14 +184,52 @@ always available.
error occurs.
+.. data:: flags
+
+ The struct sequence *flags* exposes the status of command line flags. The
+ attributes are read only.
+
+ +------------------------------+------------------------------------------+
+ | attribute | flag |
+ +==============================+==========================================+
+ | :const:`debug` | -d |
+ +------------------------------+------------------------------------------+
+ | :const:`py3k_warning` | -3 |
+ +------------------------------+------------------------------------------+
+ | :const:`division_warning` | -Q |
+ +------------------------------+------------------------------------------+
+ | :const:`division_new` | -Qnew |
+ +------------------------------+------------------------------------------+
+ | :const:`inspect` | -i |
+ +------------------------------+------------------------------------------+
+ | :const:`interactive` | -i |
+ +------------------------------+------------------------------------------+
+ | :const:`optimize` | -O or -OO |
+ +------------------------------+------------------------------------------+
+ | :const:`dont_write_bytecode` | -B |
+ +------------------------------+------------------------------------------+
+ | :const:`no_site` | -S |
+ +------------------------------+------------------------------------------+
+ | :const:`ingnore_environment` | -E |
+ +------------------------------+------------------------------------------+
+ | :const:`tabcheck` | -t or -tt |
+ +------------------------------+------------------------------------------+
+ | :const:`verbose` | -v |
+ +------------------------------+------------------------------------------+
+ | :const:`unicode` | -U |
+ +------------------------------+------------------------------------------+
+
+ .. versionadded:: 2.6
+
+
.. data:: float_info
- A dict holding information about the float type. It contains low level
+ A structseq holding information about the float type. It contains low level
information about the precision and internal representation. Please study
your system's :file:`float.h` for more information.
+---------------------+--------------------------------------------------+
- | key | explanation |
+ | attribute | explanation |
+=====================+==================================================+
| :const:`epsilon` | Difference between 1 and the next representable |
| | floating point number |
diff --git a/Lib/pydoc.py b/Lib/pydoc.py
index 1bab8e3..5d764eb 100755
--- a/Lib/pydoc.py
+++ b/Lib/pydoc.py
@@ -1834,7 +1834,9 @@ Please wait a moment while I gather a list of all available modules...
modname = modname[:-9] + ' (package)'
if modname.find('.') < 0:
modules[modname] = 1
- ModuleScanner().run(callback)
+ def onerror(modname):
+ callback(None, modname, None)
+ ModuleScanner().run(callback, onerror=onerror)
self.list(modules.keys())
self.output.write('''
Enter any module name to get more help. Or, type "modules spam" to search
@@ -1870,7 +1872,7 @@ class Scanner:
class ModuleScanner:
"""An interruptible scanner that searches module synopses."""
- def run(self, callback, key=None, completer=None):
+ def run(self, callback, key=None, completer=None, onerror=None):
if key: key = key.lower()
self.quit = False
seen = {}
@@ -1887,7 +1889,7 @@ class ModuleScanner:
if name.lower().find(key) >= 0:
callback(None, modname, desc)
- for importer, modname, ispkg in pkgutil.walk_packages():
+ for importer, modname, ispkg in pkgutil.walk_packages(onerror=onerror):
if self.quit:
break
if key is None:
diff --git a/Lib/test/test_structseq.py b/Lib/test/test_structseq.py
index 7a18fb2..7ba142b 100644
--- a/Lib/test/test_structseq.py
+++ b/Lib/test/test_structseq.py
@@ -28,7 +28,11 @@ class StructSeqTest(unittest.TestCase):
def test_repr(self):
t = time.gmtime()
- repr(t)
+ self.assert_(repr(t))
+ t = time.gmtime(0)
+ self.assertEqual(repr(t),
+ "time.struct_time(tm_year=1970, tm_mon=1, tm_mday=1, tm_hour=0, "
+ "tm_min=0, tm_sec=0, tm_wday=3, tm_yday=1, tm_isdst=0)")
def test_concat(self):
t1 = time.gmtime()
diff --git a/Lib/test/test_sys.py b/Lib/test/test_sys.py
index 0a62c01..264544d 100644
--- a/Lib/test/test_sys.py
+++ b/Lib/test/test_sys.py
@@ -279,8 +279,8 @@ class SysModuleTest(unittest.TestCase):
self.assert_(isinstance(sys.copyright, str))
self.assert_(isinstance(sys.exec_prefix, str))
self.assert_(isinstance(sys.executable, str))
- self.assert_(isinstance(sys.float_info, dict))
self.assertEqual(len(sys.float_info), 11)
+ self.assertEqual(sys.float_info.radix, 2)
self.assert_(isinstance(sys.hexversion, int))
self.assert_(isinstance(sys.maxsize, int))
self.assert_(isinstance(sys.maxunicode, int))
@@ -320,6 +320,17 @@ class SysModuleTest(unittest.TestCase):
self.assertRaises(TypeError, sys.intern, S("abc"))
+ def test_sys_flags(self):
+ self.failUnless(sys.flags)
+ attrs = ("debug", "division_warning",
+ "inspect", "interactive", "optimize", "dont_write_bytecode",
+ "no_site", "ingnore_environment", "tabcheck", "verbose")
+ for attr in attrs:
+ self.assert_(hasattr(sys.flags, attr), attr)
+ self.assertEqual(type(getattr(sys.flags, attr)), int, attr)
+ self.assert_(repr(sys.flags))
+
+
def test_main():
test.test_support.run_unittest(SysModuleTest)
diff --git a/Modules/_ctypes/_ctypes.c b/Modules/_ctypes/_ctypes.c
index c5e3be4..f60d494 100644
--- a/Modules/_ctypes/_ctypes.c
+++ b/Modules/_ctypes/_ctypes.c
@@ -401,7 +401,7 @@ static int
StructType_setattro(PyObject *self, PyObject *key, PyObject *value)
{
/* XXX Should we disallow deleting _fields_? */
- if (-1 == PyObject_GenericSetAttr(self, key, value))
+ if (-1 == PyType_Type.tp_setattro(self, key, value))
return -1;
if (value && PyUnicode_Check(key) &&
diff --git a/Modules/_ctypes/stgdict.c b/Modules/_ctypes/stgdict.c
index 11a1a63..9914cab 100644
--- a/Modules/_ctypes/stgdict.c
+++ b/Modules/_ctypes/stgdict.c
@@ -458,7 +458,7 @@ StructUnionType_update_stgdict(PyObject *type, PyObject *fields, int isStruct)
Py_DECREF(pair);
return -1;
}
- if (-1 == PyDict_SetItem(realdict, name, prop)) {
+ if (-1 == PyObject_SetAttr(type, name, prop)) {
Py_DECREF(prop);
Py_DECREF(pair);
return -1;
diff --git a/Modules/socketmodule.c b/Modules/socketmodule.c
index 7ad96d3..37e7caa 100644
--- a/Modules/socketmodule.c
+++ b/Modules/socketmodule.c
@@ -4979,10 +4979,13 @@ init_socket(void)
#endif
#ifdef SIO_RCVALL
- tmp = PyLong_FromUnsignedLong(SIO_RCVALL);
- if (tmp == NULL)
- return;
- PyModule_AddObject(m, "SIO_RCVALL", tmp);
+ {
+ PyObject *tmp;
+ tmp = PyLong_FromUnsignedLong(SIO_RCVALL);
+ if (tmp == NULL)
+ return;
+ PyModule_AddObject(m, "SIO_RCVALL", tmp);
+ }
PyModule_AddIntConstant(m, "RCVALL_OFF", RCVALL_OFF);
PyModule_AddIntConstant(m, "RCVALL_ON", RCVALL_ON);
PyModule_AddIntConstant(m, "RCVALL_SOCKETLEVELONLY", RCVALL_SOCKETLEVELONLY);
diff --git a/Objects/floatobject.c b/Objects/floatobject.c
index 0989415..a832c5d 100644
--- a/Objects/floatobject.c
+++ b/Objects/floatobject.c
@@ -5,6 +5,7 @@
for any kind of float exception without losing portability. */
#include "Python.h"
+#include "structseq.h"
#include "formatter_unicode.h"
@@ -61,39 +62,86 @@ PyFloat_GetMin(void)
return DBL_MIN;
}
+static PyTypeObject FloatInfoType;
+
+PyDoc_STRVAR(floatinfo__doc__,
+"sys.floatinfo\n\
+\n\
+A structseq holding information about the float type. It contains low level\n\
+information about the precision and internal representation. Please study\n\
+your system's :file:`float.h` for more information.");
+
+static PyStructSequence_Field floatinfo_fields[] = {
+ {"max", "DBL_MAX -- maximum representable finite float"},
+ {"max_exp", "DBL_MAX_EXP -- maximum int e such that radix**(e-1) "
+ "is representable"},
+ {"max_10_exp", "DBL_MAX_10_EXP -- maximum int e such that 10**e "
+ "is representable"},
+ {"min", "DBL_MIN -- Minimum positive normalizer float"},
+ {"min_exp", "DBL_MIN_EXP -- minimum int e such that radix**(e-1) "
+ "is a normalized float"},
+ {"min_10_exp", "DBL_MIN_10_EXP -- minimum int e such that 10**e is "
+ "a normalized"},
+ {"dig", "DBL_DIG -- digits"},
+ {"mant_dig", "DBL_MANT_DIG -- mantissa digits"},
+ {"epsilon", "DBL_EPSILON -- Difference between 1 and the next "
+ "representable float"},
+ {"radix", "FLT_RADIX -- radix of exponent"},
+ {"rounds", "FLT_ROUNDS -- addition rounds"},
+ {0}
+};
+
+static PyStructSequence_Desc floatinfo_desc = {
+ "sys.floatinfo", /* name */
+ floatinfo__doc__, /* doc */
+ floatinfo_fields, /* fields */
+ 11
+};
+
PyObject *
PyFloat_GetInfo(void)
{
- PyObject *d, *tmp;
-
-#define SET_FLOAT_CONST(d, key, const) \
- tmp = PyFloat_FromDouble(const); \
- if (tmp == NULL) return NULL; \
- if (PyDict_SetItemString(d, key, tmp)) return NULL; \
- Py_DECREF(tmp)
-#define SET_INT_CONST(d, key, const) \
- tmp = PyLong_FromLong(const); \
- if (tmp == NULL) return NULL; \
- if (PyDict_SetItemString(d, key, tmp)) return NULL; \
- Py_DECREF(tmp)
-
- d = PyDict_New();
-
- SET_FLOAT_CONST(d, "max", DBL_MAX);
- SET_INT_CONST(d, "max_exp", DBL_MAX_EXP);
- SET_INT_CONST(d, "max_10_exp", DBL_MAX_10_EXP);
- SET_FLOAT_CONST(d, "min", DBL_MIN);
- SET_INT_CONST(d, "min_exp", DBL_MIN_EXP);
- SET_INT_CONST(d, "min_10_exp", DBL_MIN_10_EXP);
- SET_INT_CONST(d, "dig", DBL_DIG);
- SET_INT_CONST(d, "mant_dig", DBL_MANT_DIG);
- SET_FLOAT_CONST(d, "epsilon", DBL_EPSILON);
- SET_INT_CONST(d, "radix", FLT_RADIX);
- SET_INT_CONST(d, "rounds", FLT_ROUNDS);
-
- return d;
-}
+ static PyObject* floatinfo;
+ int pos = 0;
+ if (floatinfo != NULL) {
+ Py_INCREF(floatinfo);
+ return floatinfo;
+ }
+ PyStructSequence_InitType(&FloatInfoType, &floatinfo_desc);
+
+ floatinfo = PyStructSequence_New(&FloatInfoType);
+ if (floatinfo == NULL) {
+ return NULL;
+ }
+
+#define SetIntFlag(flag) \
+ PyStructSequence_SET_ITEM(floatinfo, pos++, PyLong_FromLong(flag))
+#define SetDblFlag(flag) \
+ PyStructSequence_SET_ITEM(floatinfo, pos++, PyFloat_FromDouble(flag))
+
+ SetDblFlag(DBL_MAX);
+ SetIntFlag(DBL_MAX_EXP);
+ SetIntFlag(DBL_MAX_10_EXP);
+ SetDblFlag(DBL_MIN);
+ SetIntFlag(DBL_MIN_EXP);
+ SetIntFlag(DBL_MIN_10_EXP);
+ SetIntFlag(DBL_DIG);
+ SetIntFlag(DBL_MANT_DIG);
+ SetDblFlag(DBL_EPSILON);
+ SetIntFlag(FLT_RADIX);
+ SetIntFlag(FLT_ROUNDS);
+#undef SetIntFlag
+#undef SetDblFlag
+
+ if (PyErr_Occurred()) {
+ Py_CLEAR(floatinfo);
+ return NULL;
+ }
+
+ Py_INCREF(floatinfo);
+ return floatinfo;
+}
PyObject *
PyFloat_FromDouble(double fval)
diff --git a/Objects/structseq.c b/Objects/structseq.c
index 96026fc..56e885c 100644
--- a/Objects/structseq.c
+++ b/Objects/structseq.c
@@ -30,7 +30,7 @@ PyObject *
PyStructSequence_New(PyTypeObject *type)
{
PyStructSequence *obj;
-
+
obj = PyObject_New(PyStructSequence, type);
Py_SIZE(obj) = VISIBLE_SIZE_TP(type);
@@ -230,11 +230,83 @@ make_tuple(PyStructSequence *obj)
static PyObject *
structseq_repr(PyStructSequence *obj)
{
- PyObject *tup, *str;
- tup = make_tuple(obj);
- str = PyObject_Repr(tup);
+ /* buffer and type size were chosen well considered. */
+#define REPR_BUFFER_SIZE 512
+#define TYPE_MAXSIZE 100
+
+ PyObject *tup;
+ PyTypeObject *typ = Py_TYPE(obj);
+ int i, removelast = 0;
+ Py_ssize_t len;
+ char buf[REPR_BUFFER_SIZE];
+ char *endofbuf, *pbuf = buf;
+
+ /* pointer to end of writeable buffer; safes space for "...)\0" */
+ endofbuf= &buf[REPR_BUFFER_SIZE-5];
+
+ if ((tup = make_tuple(obj)) == NULL) {
+ return NULL;
+ }
+
+ /* "typename(", limited to TYPE_MAXSIZE */
+ len = strlen(typ->tp_name) > TYPE_MAXSIZE ? TYPE_MAXSIZE :
+ strlen(typ->tp_name);
+ strncpy(pbuf, typ->tp_name, len);
+ pbuf += len;
+ *pbuf++ = '(';
+
+ for (i=0; i < VISIBLE_SIZE(obj); i++) {
+ PyObject *val, *repr;
+ char *cname, *crepr;
+
+ cname = typ->tp_members[i].name;
+
+ val = PyTuple_GetItem(tup, i);
+ if (cname == NULL || val == NULL) {
+ return NULL;
+ }
+ repr = PyObject_Repr(val);
+ if (repr == NULL) {
+ Py_DECREF(tup);
+ return NULL;
+ }
+ crepr = PyUnicode_AsString(repr);
+ if (crepr == NULL) {
+ Py_DECREF(tup);
+ Py_DECREF(repr);
+ return NULL;
+ }
+
+ /* + 3: keep space for "=" and ", " */
+ len = strlen(cname) + strlen(crepr) + 3;
+ if ((pbuf+len) <= endofbuf) {
+ strcpy(pbuf, cname);
+ pbuf += strlen(cname);
+ *pbuf++ = '=';
+ strcpy(pbuf, crepr);
+ pbuf += strlen(crepr);
+ *pbuf++ = ',';
+ *pbuf++ = ' ';
+ removelast = 1;
+ Py_DECREF(repr);
+ }
+ else {
+ strcpy(pbuf, "...");
+ pbuf += 3;
+ removelast = 0;
+ Py_DECREF(repr);
+ break;
+ }
+ }
Py_DECREF(tup);
- return str;
+ if (removelast) {
+ /* overwrite last ", " */
+ pbuf-=2;
+ }
+ *pbuf++ = ')';
+ *pbuf = '\0';
+
+ return PyUnicode_FromString(buf);
}
static PyObject *
diff --git a/Python/sysmodule.c b/Python/sysmodule.c
index 35834ae..d6c0427 100644
--- a/Python/sysmodule.c
+++ b/Python/sysmodule.c
@@ -15,6 +15,7 @@ Data members:
*/
#include "Python.h"
+#include "structseq.h"
#include "code.h"
#include "frameobject.h"
#include "eval.h"
@@ -1002,6 +1003,84 @@ Py_SubversionShortBranch()
return shortbranch;
}
+
+PyDoc_STRVAR(flags__doc__,
+"sys.flags\n\
+\n\
+Flags provided through command line arguments or environment vars.");
+
+static PyTypeObject FlagsType;
+
+static PyStructSequence_Field flags_fields[] = {
+ {"debug", "-d"},
+ {"division_warning", "-Q"},
+ {"inspect", "-i"},
+ {"interactive", "-i"},
+ {"optimize", "-O or -OO"},
+ {"dont_write_bytecode", "-B"},
+ /* {"no_user_site", "-s"}, */
+ {"no_site", "-S"},
+ {"ingnore_environment", "-E"},
+ {"tabcheck", "-t or -tt"},
+ {"verbose", "-v"},
+#ifdef RISCOS
+ {"ricos_wimp", "???"},
+#endif
+ /* {"unbuffered", "-u"}, */
+ /* {"skip_first", "-x"}, */
+ {0}
+};
+
+static PyStructSequence_Desc flags_desc = {
+ "sys.flags", /* name */
+ flags__doc__, /* doc */
+ flags_fields, /* fields */
+#ifdef RISCOS
+ 11
+#else
+ 10
+#endif
+};
+
+static PyObject*
+make_flags(void)
+{
+ int pos = 0;
+ PyObject *seq;
+
+ seq = PyStructSequence_New(&FlagsType);
+ if (seq == NULL)
+ return NULL;
+
+#define SetFlag(flag) \
+ PyStructSequence_SET_ITEM(seq, pos++, PyLong_FromLong(flag))
+
+ SetFlag(Py_DebugFlag);
+ SetFlag(Py_DivisionWarningFlag);
+ SetFlag(Py_InspectFlag);
+ SetFlag(Py_InteractiveFlag);
+ SetFlag(Py_OptimizeFlag);
+ SetFlag(Py_DontWriteBytecodeFlag);
+ /* SetFlag(Py_NoUserSiteDirectory); */
+ SetFlag(Py_NoSiteFlag);
+ SetFlag(Py_IgnoreEnvironmentFlag);
+ SetFlag(Py_TabcheckFlag);
+ SetFlag(Py_VerboseFlag);
+#ifdef RISCOS
+ SetFlag(Py_RISCOSWimpFlag);
+#endif
+ /* SetFlag(saw_unbuffered_flag); */
+ /* SetFlag(skipfirstline); */
+#undef SetFlag
+
+ if (PyErr_Occurred()) {
+ return NULL;
+ }
+
+ Py_INCREF(seq);
+ return seq;
+}
+
PyObject *
_PySys_Init(void)
{
@@ -1041,9 +1120,9 @@ _PySys_Init(void)
v = Py_BuildValue("(UUU)", "CPython", branch, svn_revision);
PyDict_SetItemString(sysdict, "subversion", v);
Py_XDECREF(v);
- PyDict_SetItemString(sysdict, "dont_write_bytecode",
- v = PyBool_FromLong(Py_DontWriteBytecodeFlag));
- Py_XDECREF(v);
+ PyDict_SetItemString(sysdict, "dont_write_bytecode",
+ v = PyBool_FromLong(Py_DontWriteBytecodeFlag));
+ Py_XDECREF(v);
/*
* These release level checks are mutually exclusive and cover
* the field, so don't get too fancy with the pre-processor!
@@ -1121,6 +1200,12 @@ _PySys_Init(void)
PyDict_SetItemString(sysdict, "warnoptions", warnoptions);
}
+ PyStructSequence_InitType(&FlagsType, &flags_desc);
+ PyDict_SetItemString(sysdict, "flags", make_flags());
+ /* prevent user from creating new instances */
+ FlagsType.tp_init = NULL;
+ FlagsType.tp_new = NULL;
+
if (PyErr_Occurred())
return NULL;
return m;