[Python-checkins] r69125 - in python/branches/py3k-issue1717: Lib/test/test_funcattrs.py Objects/cellobject.c

mark.dickinson python-checkins at python.org
Fri Jan 30 16:42:42 CET 2009


Author: mark.dickinson
Date: Fri Jan 30 16:42:41 2009
New Revision: 69125

Log:
Add tp_richcompare slot for cell objects, together with tests.


Modified:
   python/branches/py3k-issue1717/Lib/test/test_funcattrs.py
   python/branches/py3k-issue1717/Objects/cellobject.c

Modified: python/branches/py3k-issue1717/Lib/test/test_funcattrs.py
==============================================================================
--- python/branches/py3k-issue1717/Lib/test/test_funcattrs.py	(original)
+++ python/branches/py3k-issue1717/Lib/test/test_funcattrs.py	Fri Jan 30 16:42:41 2009
@@ -224,10 +224,41 @@
         del self.b.__doc__
         self.assertEqual(self.b.__doc__, None)
 
+def cell(value):
+    """Create a cell containing the given value."""
+    def f():
+        print(a)
+    a = value
+    return f.__closure__[0]
+
+def empty_cell(empty=True):
+    """Create an empty cell."""
+    def f():
+        print(a)
+    # the intent of the following line is simply "if False:";  it's
+    # spelt this way to avoid the danger that a future optimization
+    # might simply remove an "if False:" code block.
+    if not empty:
+        a = 1729
+    return f.__closure__[0]
+
+class CellTest(unittest.TestCase):
+    def test_comparison(self):
+        # These tests are here simply to exercise the comparison code;
+        # their presence should not be interpreted as providing any
+        # guarantees about the semantics (or even existence) of cell
+        # comparisons in future versions of CPython.
+        self.assert_(cell(2) < cell(3))
+        self.assert_(empty_cell() < cell('saturday'))
+        self.assert_(empty_cell() == empty_cell())
+        self.assert_(cell(-36) == cell(-36.0))
+        self.assert_(cell(True) > empty_cell())
+
+
 def test_main():
     support.run_unittest(FunctionPropertiesTest, ImplicitReferencesTest,
                               ArbitraryFunctionAttrTest, FunctionDictsTest,
-                              FunctionDocstringTest)
+                              FunctionDocstringTest, CellTest)
 
 if __name__ == "__main__":
     test_main()

Modified: python/branches/py3k-issue1717/Objects/cellobject.c
==============================================================================
--- python/branches/py3k-issue1717/Objects/cellobject.c	(original)
+++ python/branches/py3k-issue1717/Objects/cellobject.c	Fri Jan 30 16:42:41 2009
@@ -51,6 +51,58 @@
 	PyObject_GC_Del(op);
 }
 
+#define TEST_COND(cond) ((cond) ? Py_True : Py_False)
+
+static PyObject *
+cell_richcompare(PyObject *a, PyObject *b, int op)
+{
+	int result;
+	PyObject *v;
+
+	/* neither argument should be NULL, unless something's gone wrong */
+	assert(a != NULL && b != NULL);
+
+	/* both arguments should be instances of PyCellObject */
+	if (!PyCell_Check(a) || !PyCell_Check(b)) {
+		v = Py_NotImplemented;
+		Py_INCREF(v);
+		return v;
+	}
+
+	/* compare cells by contents; empty cells come before anything else */
+	a = ((PyCellObject *)a)->ob_ref;
+	b = ((PyCellObject *)b)->ob_ref;
+	if (a != NULL && b != NULL)
+		return PyObject_RichCompare(a, b, op);
+
+	result = (b == NULL) - (a == NULL);
+	switch (op) {
+	case Py_EQ:
+		v = TEST_COND(result == 0);
+		break;
+	case Py_NE:
+		v = TEST_COND(result != 0);
+		break;
+	case Py_LE:
+		v = TEST_COND(result <= 0);
+		break;
+	case Py_GE:
+		v = TEST_COND(result >= 0);
+		break;
+	case Py_LT:
+		v = TEST_COND(result < 0);
+		break;
+	case Py_GT:
+		v = TEST_COND(result > 0);
+		break;
+	default:
+		PyErr_BadArgument();
+		return NULL;
+	}
+	Py_INCREF(v);
+	return v;
+}
+
 static PyObject *
 cell_repr(PyCellObject *op)
 {
@@ -117,7 +169,7 @@
  	0,					/* tp_doc */
  	(traverseproc)cell_traverse,		/* tp_traverse */
  	(inquiry)cell_clear,			/* tp_clear */
-	0,					/* tp_richcompare */
+	cell_richcompare,			/* tp_richcompare */
 	0,					/* tp_weaklistoffset */
 	0, 					/* tp_iter */
 	0,					/* tp_iternext */


More information about the Python-checkins mailing list