Author: alex.martelli
Date: Thu Aug 23 01:21:33 2007
New Revision: 57302

Modified:
   python/branches/py3k/Lib/test/test_builtin.py
   python/branches/py3k/Python/bltinmodule.c
Log:
Implement the round functionality for PEP 3141, and add tests for it.



Modified: python/branches/py3k/Lib/test/test_builtin.py
==============================================================================
--- python/branches/py3k/Lib/test/test_builtin.py       (original)
+++ python/branches/py3k/Lib/test/test_builtin.py       Thu Aug 23 01:21:33 2007
@@ -1474,6 +1474,19 @@
 
         self.assertRaises(TypeError, round)
 
+        # test generic rounding delegation for reals
+        class TestRound:
+            def __round__(self):
+                return 23
+
+        class TestNoRound:
+            pass
+
+        self.assertEqual(round(TestRound()), 23)
+
+        self.assertRaises(TypeError, round, 1, 2, 3)
+        self.assertRaises(TypeError, round, TestNoRound())
+
     def test_setattr(self):
         setattr(sys, 'spam', 1)
         self.assertEqual(sys.spam, 1)

Modified: python/branches/py3k/Python/bltinmodule.c
==============================================================================
--- python/branches/py3k/Python/bltinmodule.c   (original)
+++ python/branches/py3k/Python/bltinmodule.c   Thu Aug 23 01:21:33 2007
@@ -1378,10 +1378,34 @@
        int ndigits = 0;
        int i;
        static char *kwlist[] = {"number", "ndigits", 0};
+       PyObject* real;
 
-       if (!PyArg_ParseTupleAndKeywords(args, kwds, "d|i:round",
-                kwlist, &number, &ndigits))
+       if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|i:round",
+                kwlist, &real, &ndigits))
                 return NULL;
+
+       if (ndigits == 0) {
+               PyObject *res;
+               PyObject *d = PyObject_GetAttrString(real, "__round__");
+               if (d == NULL && !PyFloat_Check(real)) {
+                       PyErr_SetString(PyExc_TypeError,
+                                       "round() argument must have __round__ 
attribute or be a float");
+                       return NULL;
+               } 
+               if (d == NULL) {
+                       PyErr_Clear();
+               } else {
+                       res = PyObject_CallFunction(d, "");
+                       Py_DECREF(d);
+                       return res;
+               } 
+       } else if (!PyFloat_Check(real)) {
+               PyErr_SetString(PyExc_TypeError,
+                               "round() argument must have __round__ attribute 
or be a float");
+               return NULL;
+       }
+
+       number = PyFloat_AsDouble(real);
        f = 1.0;
        i = abs(ndigits);
        while  (--i >= 0)
_______________________________________________
Python-3000-checkins mailing list
[email protected]
http://mail.python.org/mailman/listinfo/python-3000-checkins

Reply via email to