[Python-3000-checkins] r57302 - in python/branches/py3k: Lib/test/test_builtin.py Python/bltinmodule.c
alex.martelli
python-3000-checkins at python.org
Thu Aug 23 01:21:34 CEST 2007
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)
More information about the Python-3000-checkins
mailing list