[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