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

http://mail.python.org/pipermail/python-dev/2008-January/076626.html and issue
1965.
This commit is contained in:
Jeffrey Yasskin 2008-02-01 06:22:46 +00:00
parent 951cc0f474
commit ca2b69f765
9 changed files with 72 additions and 70 deletions

View File

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

View File

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

View File

@ -1,11 +1,12 @@
"""Unit tests for numbers.py."""
import unittest
from test import test_support
from numbers import Number
from numbers import Exact, Inexact
from numbers import Complex, Real, Rational, Integral
import math
import operator
import unittest
from numbers import Complex, Real, Rational, Integral
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)

View File

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

View File

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

View File

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

View File

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

View File

@ -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 */
};

View File

@ -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},
};