diff options
-rw-r--r-- | Doc/c-api/concrete.rst | 2 | ||||
-rw-r--r-- | Doc/glossary.rst | 16 | ||||
-rw-r--r-- | Doc/library/functions.rst | 15 | ||||
-rw-r--r-- | Doc/library/sys.rst | 42 | ||||
-rwxr-xr-x | Lib/pydoc.py | 8 | ||||
-rw-r--r-- | Lib/test/test_structseq.py | 6 | ||||
-rw-r--r-- | Lib/test/test_sys.py | 13 | ||||
-rw-r--r-- | Modules/_ctypes/_ctypes.c | 2 | ||||
-rw-r--r-- | Modules/_ctypes/stgdict.c | 2 | ||||
-rw-r--r-- | Modules/socketmodule.c | 11 | ||||
-rw-r--r-- | Objects/floatobject.c | 106 | ||||
-rw-r--r-- | Objects/structseq.c | 82 | ||||
-rw-r--r-- | Python/sysmodule.c | 91 |
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; |