[Python-checkins] r64072 - in python/branches/tlee-ast-optimize: Doc/library/stdtypes.rst Lib/test/test_set.py Misc/NEWS Modules/mathmodule.c Objects/setobject.c

thomas.lee python-checkins at python.org
Tue Jun 10 16:31:48 CEST 2008


Author: thomas.lee
Date: Tue Jun 10 16:31:47 2008
New Revision: 64072

Log:
Merged revisions 64053-64056 via svnmerge from 
svn+ssh://pythondev@svn.python.org/python/trunk

........
  r64054 | raymond.hettinger | 2008-06-09 21:24:47 +1000 (Mon, 09 Jun 2008) | 1 line
  
  Unhappy buildbots.  Revert 64052.  Long doubles have unexpected effects on some builds.
........
  r64055 | raymond.hettinger | 2008-06-09 23:07:27 +1000 (Mon, 09 Jun 2008) | 1 line
  
  Let set.intersection() and set.intersection_update() take multiple input arguments.
........


Modified:
   python/branches/tlee-ast-optimize/   (props changed)
   python/branches/tlee-ast-optimize/Doc/library/stdtypes.rst
   python/branches/tlee-ast-optimize/Lib/test/test_set.py
   python/branches/tlee-ast-optimize/Misc/NEWS
   python/branches/tlee-ast-optimize/Modules/mathmodule.c
   python/branches/tlee-ast-optimize/Objects/setobject.c

Modified: python/branches/tlee-ast-optimize/Doc/library/stdtypes.rst
==============================================================================
--- python/branches/tlee-ast-optimize/Doc/library/stdtypes.rst	(original)
+++ python/branches/tlee-ast-optimize/Doc/library/stdtypes.rst	Tue Jun 10 16:31:47 2008
@@ -1575,11 +1575,14 @@
       .. versionchanged:: 2.6
          Accepts multiple input iterables.
 
-   .. method:: intersection(other)
-               set & other
+   .. method:: intersection(other, ...)
+               set & other & ...
 
       Return a new set with elements common to both sets.
 
+      .. versionchanged:: 2.6
+         Accepts multiple input iterables.
+
    .. method:: difference(other)
                set - other
 
@@ -1639,11 +1642,14 @@
       .. versionchanged:: 2.6
          Accepts multiple input iterables.
 
-   .. method:: intersection_update(other)
-               set &= other
+   .. method:: intersection_update(other, ...)
+               set &= other & ...
 
       Update the set, keeping only elements found in it and *other*.
 
+      .. versionchanged:: 2.6
+         Accepts multiple input iterables.
+
    .. method:: difference_update(other)
                set -= other
 

Modified: python/branches/tlee-ast-optimize/Lib/test/test_set.py
==============================================================================
--- python/branches/tlee-ast-optimize/Lib/test/test_set.py	(original)
+++ python/branches/tlee-ast-optimize/Lib/test/test_set.py	Tue Jun 10 16:31:47 2008
@@ -103,6 +103,7 @@
             self.assertEqual(self.thetype('abcba').intersection(C('efgfe')), set(''))
             self.assertEqual(self.thetype('abcba').intersection(C('ccb')), set('bc'))
             self.assertEqual(self.thetype('abcba').intersection(C('ef')), set(''))
+            self.assertEqual(self.thetype('abcba').intersection(C('cbcf'), C('bag')), set('b'))
 
     def test_isdisjoint(self):
         def f(s1, s2):
@@ -429,6 +430,11 @@
                 s = self.thetype('abcba')
                 self.assertEqual(s.intersection_update(C(p)), None)
                 self.assertEqual(s, set(q))
+                ss = 'abcba'
+                s = self.thetype(ss)
+                t = 'cbc'
+                self.assertEqual(s.intersection_update(C(p), C(t)), None)
+                self.assertEqual(s, set('abcba')&set(p)&set(t))
 
     def test_iand(self):
         self.s &= set(self.otherword)

Modified: python/branches/tlee-ast-optimize/Misc/NEWS
==============================================================================
--- python/branches/tlee-ast-optimize/Misc/NEWS	(original)
+++ python/branches/tlee-ast-optimize/Misc/NEWS	Tue Jun 10 16:31:47 2008
@@ -12,7 +12,8 @@
 Core and Builtins
 -----------------
 
-- The set methods, update() and union() now accept multiple arguments.
+- Several set methods now accept multiple arguments:  update(), union(),
+  intersection() and intersection_update().
 
 - Issue #2898: Added sys.getsizeof() to retrieve size of objects in bytes.
 

Modified: python/branches/tlee-ast-optimize/Modules/mathmodule.c
==============================================================================
--- python/branches/tlee-ast-optimize/Modules/mathmodule.c	(original)
+++ python/branches/tlee-ast-optimize/Modules/mathmodule.c	Tue Jun 10 16:31:47 2008
@@ -324,12 +324,17 @@
 
    Note 3: The itermediate values lo, yr, and hi are declared volatile so
    aggressive compilers won't algebraicly reduce lo to always be exactly 0.0.
+   Also, the volatile declaration forces the values to be stored in memory as
+   regular doubles instead of extended long precision (80-bit) values.  This
+   prevents double rounding because any addition or substraction of two doubles
+   can be resolved exactly into double-sized hi and lo values.  As long as the 
+   hi value gets forced into a double before yr and lo are computed, the extra
+   bits in downstream extended precision operations (x87 for example) will be
+   exactly zero and therefore can be losslessly stored back into a double,
+   thereby preventing double rounding.
 
-   Note 4: Intermediate values and partial sums are declared as long doubles
-   as a way to eliminate double rounding environments where the operations
-   are carried-out in extended precision but stored in double precision
-   variables.  In some cases, this doesn't help because the compiler
-   treats long doubles as doubles (i.e. the MS compiler for Win32 builds).
+   Note 4: A similar implementation is in Modules/cmathmodule.c.
+   Be sure to update both when making changes.
 
    Note 5: The signature of math.sum() differs from __builtin__.sum()
    because the start argument doesn't make sense in the context of
@@ -342,28 +347,28 @@
 
 /* Extend the partials array p[] by doubling its size. */
 static int                          /* non-zero on error */
-_sum_realloc(long double **p_ptr, Py_ssize_t  n,
-             long double  *ps,    Py_ssize_t *m_ptr)
+_sum_realloc(double **p_ptr, Py_ssize_t  n,
+             double  *ps,    Py_ssize_t *m_ptr)
 {
 	void *v = NULL;
 	Py_ssize_t m = *m_ptr;
 
-	m += m;  /* long double */
-	if (n < m && m < (PY_SSIZE_T_MAX / sizeof(long double))) {
-		long double *p = *p_ptr;
+	m += m;  /* double */
+	if (n < m && m < (PY_SSIZE_T_MAX / sizeof(double))) {
+		double *p = *p_ptr;
 		if (p == ps) {
-			v = PyMem_Malloc(sizeof(long double) * m);
+			v = PyMem_Malloc(sizeof(double) * m);
 			if (v != NULL)
-				memcpy(v, ps, sizeof(long double) * n);
+				memcpy(v, ps, sizeof(double) * n);
 		}
 		else
-			v = PyMem_Realloc(p, sizeof(long double) * m);
+			v = PyMem_Realloc(p, sizeof(double) * m);
 	}
 	if (v == NULL) {        /* size overflow or no memory */
 		PyErr_SetString(PyExc_MemoryError, "math sum partials");
 		return 1;
 	}
-	*p_ptr = (long double*) v;
+	*p_ptr = (double*) v;
 	*m_ptr = m;
 	return 0;
 }
@@ -403,8 +408,8 @@
 {
 	PyObject *item, *iter, *sum = NULL;
 	Py_ssize_t i, j, n = 0, m = NUM_PARTIALS;
-	long double x, y, t, ps[NUM_PARTIALS], *p = ps;
-	volatile long double hi, yr, lo;
+	double x, y, t, ps[NUM_PARTIALS], *p = ps;
+	volatile double hi, yr, lo;
 
 	iter = PyObject_GetIter(seq);
 	if (iter == NULL)
@@ -423,7 +428,7 @@
 				goto _sum_error;
 			break;
 		}
-		x = (long double)PyFloat_AsDouble(item);
+		x = PyFloat_AsDouble(item);
 		Py_DECREF(item);
 		if (PyErr_Occurred())
 			goto _sum_error;
@@ -490,7 +495,7 @@
 				goto _sum_error;
 		}
 	}
-	sum = PyFloat_FromDouble((double)hi);
+	sum = PyFloat_FromDouble(hi);
 
 _sum_error:
 	PyFPE_END_PROTECT(hi)
@@ -507,7 +512,6 @@
 Return an accurate floating point sum of values in the iterable.\n\
 Assumes IEEE-754 floating point arithmetic.");
 
-
 static PyObject *
 math_factorial(PyObject *self, PyObject *arg)
 {

Modified: python/branches/tlee-ast-optimize/Objects/setobject.c
==============================================================================
--- python/branches/tlee-ast-optimize/Objects/setobject.c	(original)
+++ python/branches/tlee-ast-optimize/Objects/setobject.c	Tue Jun 10 16:31:47 2008
@@ -1306,6 +1306,26 @@
 	return (PyObject *)result;
 }
 
+static PyObject *
+set_intersection_multi(PySetObject *so, PyObject *args)
+{
+	Py_ssize_t i;
+	PyObject *result = (PyObject *)so;
+
+	Py_INCREF(so);
+	for (i=0 ; i<PyTuple_GET_SIZE(args) ; i++) {
+		PyObject *other = PyTuple_GET_ITEM(args, i);
+		PyObject *newresult = set_intersection((PySetObject *)result, other);
+		if (newresult == NULL) {
+			Py_DECREF(result);
+			return NULL;
+		}
+		Py_DECREF(result);
+		result = newresult;
+	}
+	return result;
+}
+
 PyDoc_STRVAR(intersection_doc,
 "Return the intersection of two sets as a new set.\n\
 \n\
@@ -1324,6 +1344,19 @@
 	Py_RETURN_NONE;
 }
 
+static PyObject *
+set_intersection_update_multi(PySetObject *so, PyObject *args)
+{
+	PyObject *tmp;
+
+	tmp = set_intersection_multi(so, args);
+	if (tmp == NULL)
+		return NULL;
+	set_swap_bodies(so, (PySetObject *)tmp);
+	Py_DECREF(tmp);
+	Py_RETURN_NONE;
+}
+
 PyDoc_STRVAR(intersection_update_doc,
 "Update a set with the intersection of itself and another.");
 
@@ -1946,9 +1979,9 @@
 	 difference_doc},
 	{"difference_update",	(PyCFunction)set_difference_update,	METH_O,
 	 difference_update_doc},
-	{"intersection",(PyCFunction)set_intersection,	METH_O,
+	{"intersection",(PyCFunction)set_intersection_multi,	METH_VARARGS,
 	 intersection_doc},
-	{"intersection_update",(PyCFunction)set_intersection_update,	METH_O,
+	{"intersection_update",(PyCFunction)set_intersection_update_multi,	METH_VARARGS,
 	 intersection_update_doc},
 	{"isdisjoint",	(PyCFunction)set_isdisjoint,	METH_O,
 	 isdisjoint_doc},
@@ -2073,7 +2106,7 @@
 	 copy_doc},
 	{"difference",	(PyCFunction)set_difference,	METH_O,
 	 difference_doc},
-	{"intersection",(PyCFunction)set_intersection,	METH_O,
+	{"intersection",(PyCFunction)set_intersection_multi,	METH_VARARGS,
 	 intersection_doc},
 	{"isdisjoint",	(PyCFunction)set_isdisjoint,	METH_O,
 	 isdisjoint_doc},


More information about the Python-checkins mailing list