Commit a8b3a0db authored by Jeffrey Yasskin's avatar Jeffrey Yasskin

Move __builtins__.trunc() to math.trunc() per

http://mail.python.org/pipermail/python-dev/2008-January/076626.html and issue
1965.
parent 8399f1b9
......@@ -1145,14 +1145,6 @@ available. They are listed here in alphabetical order.
.. versionadded:: 2.2
.. function:: trunc(x)
Return the :class:`Real` value *x* truncated to an :class:`Integral` (usually
a long integer). Delegates to ``x.__trunc__()``.
.. versionadded:: 2.6
.. function:: tuple([iterable])
Return a tuple whose items are the same and in the same order as *iterable*'s
......
......@@ -103,6 +103,14 @@ Number-theoretic and representation functions:
Return the fractional and integer parts of *x*. Both results carry the sign of
*x*, and both are floats.
.. function:: trunc(x)
Return the :class:`Real` value *x* truncated to an :class:`Integral` (usually
a long integer). Delegates to ``x.__trunc__()``.
.. versionadded:: 2.6
Note that :func:`frexp` and :func:`modf` have a different call/return pattern
than their C equivalents: they take a single argument and return a pair of
values, rather than returning their second return value through an 'output
......
"""Unit tests for numbers.py."""
import math
import operator
import unittest
from test import test_support
from numbers import Number
from numbers import Exact, Inexact
from numbers import Complex, Real, Rational, Integral
import operator
from numbers import Exact, Inexact
from numbers import Number
from test import test_support
class TestNumbers(unittest.TestCase):
def test_int(self):
......@@ -49,8 +50,8 @@ class TestNumbers(unittest.TestCase):
self.failUnless(issubclass(complex, Inexact))
c1, c2 = complex(3, 2), complex(4,1)
# XXX: This is not ideal, but see the comment in builtin_trunc().
self.assertRaises(AttributeError, trunc, c1)
# XXX: This is not ideal, but see the comment in math_trunc().
self.assertRaises(AttributeError, math.trunc, c1)
self.assertRaises(TypeError, float, c1)
self.assertRaises(TypeError, int, c1)
......
......@@ -1766,38 +1766,6 @@ class BuiltinTest(unittest.TestCase):
raise ValueError
self.assertRaises(ValueError, sum, BadSeq())
def test_trunc(self):
self.assertEqual(trunc(1), 1)
self.assertEqual(trunc(-1), -1)
self.assertEqual(type(trunc(1)), int)
self.assertEqual(type(trunc(1.5)), int)
self.assertEqual(trunc(1.5), 1)
self.assertEqual(trunc(-1.5), -1)
self.assertEqual(trunc(1.999999), 1)
self.assertEqual(trunc(-1.999999), -1)
self.assertEqual(trunc(-0.999999), -0)
self.assertEqual(trunc(-100.999), -100)
class TestTrunc(object):
def __trunc__(self):
return 23
class TestNoTrunc(object):
pass
self.assertEqual(trunc(TestTrunc()), 23)
self.assertRaises(TypeError, trunc)
self.assertRaises(TypeError, trunc, 1, 2)
# XXX: This is not ideal, but see the comment in builtin_trunc().
self.assertRaises(AttributeError, trunc, TestNoTrunc())
t = TestNoTrunc()
t.__trunc__ = lambda *args: args
self.assertEquals((), trunc(t))
self.assertRaises(TypeError, trunc, t, 0)
def test_tuple(self):
self.assertEqual(tuple(()), ())
t0_3 = (0, 1, 2, 3)
......
......@@ -25,10 +25,11 @@ with the corresponding argument.
"""
from __future__ import with_statement
import unittest
import glob
import math
import os, sys
import pickle, copy
import unittest
from decimal import *
from test.test_support import (TestSkipped, run_unittest, run_doctest,
is_resource_enabled)
......@@ -1225,7 +1226,7 @@ class DecimalPythonAPItests(unittest.TestCase):
# should work the same as to_integral in the ROUND_DOWN mode
d = Decimal(s)
r = d.to_integral(ROUND_DOWN)
self.assertEqual(Decimal(trunc(d)), r)
self.assertEqual(Decimal(math.trunc(d)), r)
class ContextAPItests(unittest.TestCase):
......
......@@ -237,6 +237,37 @@ class MathTests(unittest.TestCase):
self.ftest('tanh(0)', math.tanh(0), 0)
self.ftest('tanh(1)+tanh(-1)', math.tanh(1)+math.tanh(-1), 0)
def test_trunc(self):
self.assertEqual(math.trunc(1), 1)
self.assertEqual(math.trunc(-1), -1)
self.assertEqual(type(math.trunc(1)), int)
self.assertEqual(type(math.trunc(1.5)), int)
self.assertEqual(math.trunc(1.5), 1)
self.assertEqual(math.trunc(-1.5), -1)
self.assertEqual(math.trunc(1.999999), 1)
self.assertEqual(math.trunc(-1.999999), -1)
self.assertEqual(math.trunc(-0.999999), -0)
self.assertEqual(math.trunc(-100.999), -100)
class TestTrunc(object):
def __trunc__(self):
return 23
class TestNoTrunc(object):
pass
self.assertEqual(math.trunc(TestTrunc()), 23)
self.assertRaises(TypeError, math.trunc)
self.assertRaises(TypeError, math.trunc, 1, 2)
# XXX: This is not ideal, but see the comment in math_trunc().
self.assertRaises(AttributeError, math.trunc, TestNoTrunc())
t = TestNoTrunc()
t.__trunc__ = lambda *args: args
self.assertEquals((), math.trunc(t))
self.assertRaises(TypeError, math.trunc, t, 0)
def testCopysign(self):
self.assertEqual(math.copysign(1, 42), 1.0)
self.assertEqual(math.copysign(0., 42), 0.0)
......
......@@ -195,7 +195,7 @@ class RationalTest(unittest.TestCase):
self.assertEqual(R.from_float(0.0).approximate(10000), R(0))
def testConversions(self):
self.assertTypedEquals(-1, trunc(R(-11, 10)))
self.assertTypedEquals(-1, math.trunc(R(-11, 10)))
self.assertTypedEquals(-1, int(R(-11, 10)))
self.assertEquals(False, bool(R(0, 1)))
......@@ -322,11 +322,11 @@ class RationalTest(unittest.TestCase):
# Because 10**23 can't be represented exactly as a float:
self.assertFalse(R(10**23) == float(10**23))
# The first test demonstrates why these are important.
self.assertFalse(1e23 < float(R(trunc(1e23) + 1)))
self.assertTrue(1e23 < R(trunc(1e23) + 1))
self.assertFalse(1e23 <= R(trunc(1e23) - 1))
self.assertTrue(1e23 > R(trunc(1e23) - 1))
self.assertFalse(1e23 >= R(trunc(1e23) + 1))
self.assertFalse(1e23 < float(R(math.trunc(1e23) + 1)))
self.assertTrue(1e23 < R(math.trunc(1e23) + 1))
self.assertFalse(1e23 <= R(math.trunc(1e23) - 1))
self.assertTrue(1e23 > R(math.trunc(1e23) - 1))
self.assertFalse(1e23 >= R(math.trunc(1e23) + 1))
def testBigComplexComparisons(self):
self.assertFalse(R(10**23) == complex(10**23))
......
......@@ -154,6 +154,21 @@ FUNC1(tan, tan,
FUNC1(tanh, tanh,
"tanh(x)\n\nReturn the hyperbolic tangent of x.")
static PyObject *
math_trunc(PyObject *self, PyObject *number)
{
/* XXX: The py3k branch gets better errors for this by using
_PyType_Lookup(), but since float's mro isn't set in py2.6,
we just use PyObject_CallMethod here. */
return PyObject_CallMethod(number, "__trunc__", NULL);
}
PyDoc_STRVAR(math_trunc_doc,
"trunc(x:Real) -> Integral\n"
"\n"
"Truncates x to the nearest Integral toward 0. Uses the __trunc__ magic"
"method.");
static PyObject *
math_frexp(PyObject *self, PyObject *arg)
{
......@@ -377,6 +392,7 @@ static PyMethodDef math_methods[] = {
{"sqrt", math_sqrt, METH_O, math_sqrt_doc},
{"tan", math_tan, METH_O, math_tan_doc},
{"tanh", math_tanh, METH_O, math_tanh_doc},
{"trunc", math_trunc, METH_O, math_trunc_doc},
{NULL, NULL} /* sentinel */
};
......
......@@ -2044,20 +2044,6 @@ PyDoc_STRVAR(vars_doc,
Without arguments, equivalent to locals().\n\
With an argument, equivalent to object.__dict__.");
static PyObject *
builtin_trunc(PyObject *self, PyObject *number)
{
/* XXX: The py3k branch gets better errors for this by using
_PyType_Lookup(), but since float's mro isn't set in py2.6,
we just use PyObject_CallMethod here. */
return PyObject_CallMethod(number, "__trunc__", NULL);
}
PyDoc_STRVAR(trunc_doc,
"trunc(Real) -> Integral\n\
\n\
returns the integral closest to x between 0 and x.");
static PyObject*
builtin_sum(PyObject *self, PyObject *args)
......@@ -2406,7 +2392,6 @@ static PyMethodDef builtin_methods[] = {
{"unichr", builtin_unichr, METH_VARARGS, unichr_doc},
#endif
{"vars", builtin_vars, METH_VARARGS, vars_doc},
{"trunc", builtin_trunc, METH_O, trunc_doc},
{"zip", builtin_zip, METH_VARARGS, zip_doc},
{NULL, NULL},
};
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment