summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Doc/c-api/concrete.rst2
-rw-r--r--Doc/library/sys.rst4
-rw-r--r--Lib/test/test_sys.py2
-rw-r--r--Misc/NEWS3
-rw-r--r--Objects/floatobject.c107
5 files changed, 85 insertions, 33 deletions
diff --git a/Doc/c-api/concrete.rst b/Doc/c-api/concrete.rst
index 713daab..623df36 100644
--- a/Doc/c-api/concrete.rst
+++ b/Doc/c-api/concrete.rst
@@ -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`.
diff --git a/Doc/library/sys.rst b/Doc/library/sys.rst
index d830490..7dbf41e 100644
--- a/Doc/library/sys.rst
+++ b/Doc/library/sys.rst
@@ -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 |
diff --git a/Lib/test/test_sys.py b/Lib/test/test_sys.py
index 66710a0..1b9b9d0 100644
--- a/Lib/test/test_sys.py
+++ b/Lib/test/test_sys.py
@@ -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:
diff --git a/Misc/NEWS b/Misc/NEWS
index 76104c0..0ef721f 100644
--- 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.
diff --git a/Objects/floatobject.c b/Objects/floatobject.c
index ff23d33..340b0e7 100644
--- a/Objects/floatobject.c
+++ b/Objects/floatobject.c
@@ -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)