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)
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)