[Python-3000-checkins] r57361 - in python/branches/py3k: Lib/test/test_math.py Modules/mathmodule.c
guido.van.rossum
python-3000-checkins at python.org
Fri Aug 24 00:56:55 CEST 2007
Author: guido.van.rossum
Date: Fri Aug 24 00:56:55 2007
New Revision: 57361
Modified:
python/branches/py3k/Lib/test/test_math.py
python/branches/py3k/Modules/mathmodule.c
Log:
Fix math.ceil() and math.floor() to fall back to __ceil__ and __floor__
methods (respectively). With Keir Mierle.
Modified: python/branches/py3k/Lib/test/test_math.py
==============================================================================
--- python/branches/py3k/Lib/test/test_math.py (original)
+++ python/branches/py3k/Lib/test/test_math.py Fri Aug 24 00:56:55 2007
@@ -58,6 +58,19 @@
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())
+
+ t = TestNoCeil()
+ t.__ceil__ = lambda *args: args
+ self.assertRaises(TypeError, math.ceil, t)
+ self.assertRaises(TypeError, math.ceil, t, 0)
+
def testCos(self):
self.assertRaises(TypeError, math.cos)
self.ftest('cos(-pi/2)', math.cos(-math.pi/2), 0)
@@ -101,6 +114,19 @@
self.ftest('floor(1.23e167)', math.floor(1.23e167), 1.23e167)
self.ftest('floor(-1.23e167)', math.floor(-1.23e167), -1.23e167)
+ class TestFloor:
+ def __floor__(self):
+ return 42
+ class TestNoFloor:
+ pass
+ self.ftest('floor(TestFloor())', math.floor(TestFloor()), 42)
+ self.assertRaises(TypeError, math.floor, TestNoFloor())
+
+ t = TestNoFloor()
+ t.__floor__ = lambda *args: args
+ self.assertRaises(TypeError, math.floor, t)
+ self.assertRaises(TypeError, math.floor, t, 0)
+
def testFmod(self):
self.assertRaises(TypeError, math.fmod)
self.ftest('fmod(10,1)', math.fmod(10,1), 0)
Modified: python/branches/py3k/Modules/mathmodule.c
==============================================================================
--- python/branches/py3k/Modules/mathmodule.c (original)
+++ python/branches/py3k/Modules/mathmodule.c Fri Aug 24 00:56:55 2007
@@ -107,9 +107,28 @@
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 *number) {
+ static PyObject *ceil_str = NULL;
+ PyObject *method;
+
+ if (ceil_str == NULL) {
+ ceil_str = PyUnicode_FromString("__ceil__");
+ if (ceil_str == NULL)
+ return NULL;
+ }
+
+ method = _PyType_Lookup(Py_Type(number), ceil_str);
+ if (method == NULL)
+ return math_1(number, ceil);
+ else
+ return PyObject_CallFunction(method, "O", number);
+}
+
+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,
@@ -118,9 +137,28 @@
"exp(x)\n\nReturn e raised to the power of x.")
FUNC1(fabs, fabs,
"fabs(x)\n\nReturn the absolute value of the float x.")
-FUNC1(floor, floor,
- "floor(x)\n\nReturn the floor of x as a float.\n"
- "This is the largest integral value <= x.")
+
+static PyObject * math_floor(PyObject *self, PyObject *number) {
+ static PyObject *floor_str = NULL;
+ PyObject *method;
+
+ if (floor_str == NULL) {
+ floor_str = PyUnicode_FromString("__floor__");
+ if (floor_str == NULL)
+ return NULL;
+ }
+
+ method = _PyType_Lookup(Py_Type(number), floor_str);
+ if (method == NULL)
+ return math_1(number, floor);
+ else
+ return PyObject_CallFunction(method, "O", number);
+}
+
+PyDoc_STRVAR(math_floor_doc,
+ "floor(x)\n\nReturn the floor of x as a float.\n"
+ "This is the largest integral value <= x.");
+
FUNC2(fmod, fmod,
"fmod(x,y)\n\nReturn fmod(x, y), according to platform C."
" x % y may differ.")
More information about the Python-3000-checkins
mailing list