The attached patch fixes math.ceil to delegate to x.__ceil__() if it is defined, according to PEP 3141, and adds tests to cover the new cases. Patch is against r57303.
No new test failures are introduced. Keir
Index: Lib/test/test_math.py =================================================================== --- Lib/test/test_math.py (revision 57303) +++ Lib/test/test_math.py (working copy) @@ -58,6 +58,14 @@ self.ftest('ceil(-1.0)', math.ceil(-1.0), -1) self.ftest('ceil(-1.5)', math.ceil(-1.5), -1) + class TestCeil: + def __ceil__(self): + return 42 + class TestNoCeil: + pass + self.ftest('ceil(TestCeil())', math.ceil(TestCeil()), 42) + self.assertRaises(TypeError, math.ceil, TestNoCeil()) + def testCos(self): self.assertRaises(TypeError, math.cos) self.ftest('cos(-pi/2)', math.cos(-math.pi/2), 0) Index: Modules/mathmodule.c =================================================================== --- Modules/mathmodule.c (revision 57303) +++ Modules/mathmodule.c (working copy) @@ -107,9 +107,24 @@ FUNC2(atan2, atan2, "atan2(y, x)\n\nReturn the arc tangent (measured in radians) of y/x.\n" "Unlike atan(y/x), the signs of both x and y are considered.") -FUNC1(ceil, ceil, - "ceil(x)\n\nReturn the ceiling of x as a float.\n" - "This is the smallest integral value >= x.") +static PyObject * math_ceil(PyObject *self, PyObject *args) { + PyObject* d = PyObject_GetAttrString(args, "__ceil__"); + if (d == NULL) { + if (!PyFloat_Check(args)) { + PyErr_SetString(PyExc_TypeError, + "ceil() argument must have __ceil__ attribute or be a float"); + return NULL; + } + PyErr_Clear(); + return math_1(args, ceil); + } + PyObject *res = PyObject_CallFunction(d, ""); + Py_DECREF(d); + return res; +} +PyDoc_STRVAR(math_ceil_doc, +"ceil(x)\n\nReturn the ceiling of x as a float.\n" +"This is the smallest integral value >= x."); FUNC1(cos, cos, "cos(x)\n\nReturn the cosine of x (measured in radians).") FUNC1(cosh, cosh,
_______________________________________________ Python-3000 mailing list Python-3000@python.org http://mail.python.org/mailman/listinfo/python-3000 Unsubscribe: http://mail.python.org/mailman/options/python-3000/archive%40mail-archive.com