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
[email protected]
http://mail.python.org/mailman/listinfo/python-3000
Unsubscribe:
http://mail.python.org/mailman/options/python-3000/archive%40mail-archive.com