]> granicus.if.org Git - python/commitdiff
Now that I've learnt about structseq objects I felt like converting sys.float_info...
authorChristian Heimes <christian@cheimes.de>
Mon, 14 Jan 2008 04:13:37 +0000 (04:13 +0000)
committerChristian Heimes <christian@cheimes.de>
Mon, 14 Jan 2008 04:13:37 +0000 (04:13 +0000)
readonly and help(sys.float_info) explains the attributes nicely.

Doc/c-api/concrete.rst
Doc/library/sys.rst
Lib/test/test_sys.py
Misc/NEWS
Objects/floatobject.c

index 713daabda8610c380f4618f6a59bd3e783449655..623df367ad10a780e7ef4b2401da1cfb63032728 100644 (file)
@@ -559,7 +559,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`.
 
index d830490b8e5ec34de508416394aed216038df3d9..7dbf41e97ee8eb11bb4dbbb7ecc26d61d9c6c1a7 100644 (file)
@@ -280,12 +280,12 @@ always available.
 
 .. 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                            |
index 66710a0cc3f64d2ae348ab7d97a9cb8200e4ac13..1b9b9d0b13f7136defd06de1f50de82d29bcb2c0 100644 (file)
@@ -329,8 +329,8 @@ class SysModuleTest(unittest.TestCase):
         self.assert_(isinstance(sys.copyright, basestring))
         self.assert_(isinstance(sys.exec_prefix, basestring))
         self.assert_(isinstance(sys.executable, basestring))
-        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.maxint, int))
         if test.test_support.have_unicode:
index 76104c06b1d33f6565a639e604f718561eec069d..0ef721fc8be22b8ddeb167c8893f85095557beb8 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -12,6 +12,9 @@ What's New in Python 2.6 alpha 1?
 Core and builtins
 -----------------
 
+- sys.float_info / PyFloat_GetInfo: The floating point information
+  object was converted from a dict to a specialized structseq object.
+
 - Patch #1816: Added sys.flags structseq. It exposes the status of most
   command line arguments and PYTHON* environment variables. 
 
index ff23d3316196292fa0d4d1e7c745dbdb5ecd08c0..340b0e7a2d98131ac75c85ae4728e56964208cfa 100644 (file)
@@ -5,10 +5,12 @@
    for any kind of float exception without losing portability. */
 
 #include "Python.h"
+#include "structseq.h"
 
 #include <ctype.h>
 #include <float.h>
 
+
 #if !defined(__STDC__)
 extern double fmod(double, double);
 extern double pow(double, double);
@@ -59,39 +61,86 @@ PyFloat_GetMin(void)
        return DBL_MIN;
 }
 
+static PyTypeObject FloatInfoType = {0};
+
+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 = PyInt_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++, PyInt_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)