mirror of
https://github.com/python/cpython.git
synced 2025-07-28 21:55:21 +00:00
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:
parent
951cc0f474
commit
ca2b69f765
9 changed files with 72 additions and 70 deletions
|
@ -1145,14 +1145,6 @@ available. They are listed here in alphabetical order.
|
||||||
.. versionadded:: 2.2
|
.. 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])
|
.. function:: tuple([iterable])
|
||||||
|
|
||||||
Return a tuple whose items are the same and in the same order as *iterable*'s
|
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
|
Return the fractional and integer parts of *x*. Both results carry the sign of
|
||||||
*x*, and both are floats.
|
*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
|
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
|
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
|
values, rather than returning their second return value through an 'output
|
||||||
|
|
|
@ -1,11 +1,12 @@
|
||||||
"""Unit tests for numbers.py."""
|
"""Unit tests for numbers.py."""
|
||||||
|
|
||||||
import unittest
|
import math
|
||||||
from test import test_support
|
|
||||||
from numbers import Number
|
|
||||||
from numbers import Exact, Inexact
|
|
||||||
from numbers import Complex, Real, Rational, Integral
|
|
||||||
import operator
|
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):
|
class TestNumbers(unittest.TestCase):
|
||||||
def test_int(self):
|
def test_int(self):
|
||||||
|
@ -49,8 +50,8 @@ class TestNumbers(unittest.TestCase):
|
||||||
self.failUnless(issubclass(complex, Inexact))
|
self.failUnless(issubclass(complex, Inexact))
|
||||||
|
|
||||||
c1, c2 = complex(3, 2), complex(4,1)
|
c1, c2 = complex(3, 2), complex(4,1)
|
||||||
# XXX: This is not ideal, but see the comment in builtin_trunc().
|
# XXX: This is not ideal, but see the comment in math_trunc().
|
||||||
self.assertRaises(AttributeError, trunc, c1)
|
self.assertRaises(AttributeError, math.trunc, c1)
|
||||||
self.assertRaises(TypeError, float, c1)
|
self.assertRaises(TypeError, float, c1)
|
||||||
self.assertRaises(TypeError, int, c1)
|
self.assertRaises(TypeError, int, c1)
|
||||||
|
|
||||||
|
|
|
@ -1766,38 +1766,6 @@ class BuiltinTest(unittest.TestCase):
|
||||||
raise ValueError
|
raise ValueError
|
||||||
self.assertRaises(ValueError, sum, BadSeq())
|
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):
|
def test_tuple(self):
|
||||||
self.assertEqual(tuple(()), ())
|
self.assertEqual(tuple(()), ())
|
||||||
t0_3 = (0, 1, 2, 3)
|
t0_3 = (0, 1, 2, 3)
|
||||||
|
|
|
@ -25,10 +25,11 @@ with the corresponding argument.
|
||||||
"""
|
"""
|
||||||
from __future__ import with_statement
|
from __future__ import with_statement
|
||||||
|
|
||||||
import unittest
|
|
||||||
import glob
|
import glob
|
||||||
|
import math
|
||||||
import os, sys
|
import os, sys
|
||||||
import pickle, copy
|
import pickle, copy
|
||||||
|
import unittest
|
||||||
from decimal import *
|
from decimal import *
|
||||||
from test.test_support import (TestSkipped, run_unittest, run_doctest,
|
from test.test_support import (TestSkipped, run_unittest, run_doctest,
|
||||||
is_resource_enabled)
|
is_resource_enabled)
|
||||||
|
@ -1225,7 +1226,7 @@ class DecimalPythonAPItests(unittest.TestCase):
|
||||||
# should work the same as to_integral in the ROUND_DOWN mode
|
# should work the same as to_integral in the ROUND_DOWN mode
|
||||||
d = Decimal(s)
|
d = Decimal(s)
|
||||||
r = d.to_integral(ROUND_DOWN)
|
r = d.to_integral(ROUND_DOWN)
|
||||||
self.assertEqual(Decimal(trunc(d)), r)
|
self.assertEqual(Decimal(math.trunc(d)), r)
|
||||||
|
|
||||||
class ContextAPItests(unittest.TestCase):
|
class ContextAPItests(unittest.TestCase):
|
||||||
|
|
||||||
|
|
|
@ -237,6 +237,37 @@ class MathTests(unittest.TestCase):
|
||||||
self.ftest('tanh(0)', math.tanh(0), 0)
|
self.ftest('tanh(0)', math.tanh(0), 0)
|
||||||
self.ftest('tanh(1)+tanh(-1)', math.tanh(1)+math.tanh(-1), 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):
|
def testCopysign(self):
|
||||||
self.assertEqual(math.copysign(1, 42), 1.0)
|
self.assertEqual(math.copysign(1, 42), 1.0)
|
||||||
self.assertEqual(math.copysign(0., 42), 0.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))
|
self.assertEqual(R.from_float(0.0).approximate(10000), R(0))
|
||||||
|
|
||||||
def testConversions(self):
|
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.assertTypedEquals(-1, int(R(-11, 10)))
|
||||||
|
|
||||||
self.assertEquals(False, bool(R(0, 1)))
|
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:
|
# Because 10**23 can't be represented exactly as a float:
|
||||||
self.assertFalse(R(10**23) == float(10**23))
|
self.assertFalse(R(10**23) == float(10**23))
|
||||||
# The first test demonstrates why these are important.
|
# The first test demonstrates why these are important.
|
||||||
self.assertFalse(1e23 < float(R(trunc(1e23) + 1)))
|
self.assertFalse(1e23 < float(R(math.trunc(1e23) + 1)))
|
||||||
self.assertTrue(1e23 < R(trunc(1e23) + 1))
|
self.assertTrue(1e23 < R(math.trunc(1e23) + 1))
|
||||||
self.assertFalse(1e23 <= R(trunc(1e23) - 1))
|
self.assertFalse(1e23 <= R(math.trunc(1e23) - 1))
|
||||||
self.assertTrue(1e23 > R(trunc(1e23) - 1))
|
self.assertTrue(1e23 > R(math.trunc(1e23) - 1))
|
||||||
self.assertFalse(1e23 >= R(trunc(1e23) + 1))
|
self.assertFalse(1e23 >= R(math.trunc(1e23) + 1))
|
||||||
|
|
||||||
def testBigComplexComparisons(self):
|
def testBigComplexComparisons(self):
|
||||||
self.assertFalse(R(10**23) == complex(10**23))
|
self.assertFalse(R(10**23) == complex(10**23))
|
||||||
|
|
|
@ -154,6 +154,21 @@ FUNC1(tan, tan,
|
||||||
FUNC1(tanh, tanh,
|
FUNC1(tanh, tanh,
|
||||||
"tanh(x)\n\nReturn the hyperbolic tangent of x.")
|
"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 *
|
static PyObject *
|
||||||
math_frexp(PyObject *self, PyObject *arg)
|
math_frexp(PyObject *self, PyObject *arg)
|
||||||
{
|
{
|
||||||
|
@ -377,6 +392,7 @@ static PyMethodDef math_methods[] = {
|
||||||
{"sqrt", math_sqrt, METH_O, math_sqrt_doc},
|
{"sqrt", math_sqrt, METH_O, math_sqrt_doc},
|
||||||
{"tan", math_tan, METH_O, math_tan_doc},
|
{"tan", math_tan, METH_O, math_tan_doc},
|
||||||
{"tanh", math_tanh, METH_O, math_tanh_doc},
|
{"tanh", math_tanh, METH_O, math_tanh_doc},
|
||||||
|
{"trunc", math_trunc, METH_O, math_trunc_doc},
|
||||||
{NULL, NULL} /* sentinel */
|
{NULL, NULL} /* sentinel */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -2044,20 +2044,6 @@ PyDoc_STRVAR(vars_doc,
|
||||||
Without arguments, equivalent to locals().\n\
|
Without arguments, equivalent to locals().\n\
|
||||||
With an argument, equivalent to object.__dict__.");
|
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*
|
static PyObject*
|
||||||
builtin_sum(PyObject *self, PyObject *args)
|
builtin_sum(PyObject *self, PyObject *args)
|
||||||
|
@ -2406,7 +2392,6 @@ static PyMethodDef builtin_methods[] = {
|
||||||
{"unichr", builtin_unichr, METH_VARARGS, unichr_doc},
|
{"unichr", builtin_unichr, METH_VARARGS, unichr_doc},
|
||||||
#endif
|
#endif
|
||||||
{"vars", builtin_vars, METH_VARARGS, vars_doc},
|
{"vars", builtin_vars, METH_VARARGS, vars_doc},
|
||||||
{"trunc", builtin_trunc, METH_O, trunc_doc},
|
|
||||||
{"zip", builtin_zip, METH_VARARGS, zip_doc},
|
{"zip", builtin_zip, METH_VARARGS, zip_doc},
|
||||||
{NULL, NULL},
|
{NULL, NULL},
|
||||||
};
|
};
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue