diff options
author | Christian Heimes <christian@cheimes.de> | 2008-02-01 08:12:03 (GMT) |
---|---|---|
committer | Christian Heimes <christian@cheimes.de> | 2008-02-01 08:12:03 (GMT) |
commit | 400adb030a78c3fcb1eb458b25c990449fbf3c93 (patch) | |
tree | 8dc99c561ec91ec9d2f887eb7b04e7227d30b8ac /Lib | |
parent | a7712090f78d19d0711553d58e403c9fa44474a8 (diff) | |
download | cpython-400adb030a78c3fcb1eb458b25c990449fbf3c93.zip cpython-400adb030a78c3fcb1eb458b25c990449fbf3c93.tar.gz cpython-400adb030a78c3fcb1eb458b25c990449fbf3c93.tar.bz2 |
Merged revisions 60475-60479,60481-60488 via svnmerge from
svn+ssh://pythondev@svn.python.org/python/trunk
........
r60482 | raymond.hettinger | 2008-01-31 23:07:16 +0100 (Thu, 31 Jan 2008) | 1 line
Minor wordsmithing on docstring
........
r60483 | mark.dickinson | 2008-01-31 23:17:37 +0100 (Thu, 31 Jan 2008) | 5 lines
Issue #1678380. Fix a bug that identifies 0j and -0j when they appear
in the same code unit. The fix is essentially the same as the fix for a
previous bug identifying 0. and -0.
........
r60484 | christian.heimes | 2008-02-01 00:08:23 +0100 (Fri, 01 Feb 2008) | 1 line
Fixed bug #1983: Return from fork() is pid_t, not int
........
r60486 | jeffrey.yasskin | 2008-02-01 07:22:46 +0100 (Fri, 01 Feb 2008) | 4 lines
Move __builtins__.trunc() to math.trunc() per
http://mail.python.org/pipermail/python-dev/2008-January/076626.html and issue
1965.
........
r60487 | jeffrey.yasskin | 2008-02-01 08:05:46 +0100 (Fri, 01 Feb 2008) | 3 lines
Roll back r60248. It's useful to encourage users not to change Rational
instances.
........
r60488 | neal.norwitz | 2008-02-01 08:22:59 +0100 (Fri, 01 Feb 2008) | 1 line
Fix refleak
........
Diffstat (limited to 'Lib')
-rwxr-xr-x | Lib/rational.py | 29 | ||||
-rw-r--r-- | Lib/test/test_abstract_numbers.py | 12 | ||||
-rw-r--r-- | Lib/test/test_builtin.py | 31 | ||||
-rw-r--r-- | Lib/test/test_complex.py | 7 | ||||
-rw-r--r-- | Lib/test/test_decimal.py | 5 | ||||
-rw-r--r-- | Lib/test/test_math.py | 32 | ||||
-rw-r--r-- | Lib/test/test_rational.py | 23 |
7 files changed, 84 insertions, 55 deletions
diff --git a/Lib/rational.py b/Lib/rational.py index 06002a3..55d4a41 100755 --- a/Lib/rational.py +++ b/Lib/rational.py @@ -42,7 +42,7 @@ class Rational(RationalAbc): """ - __slots__ = ('numerator', 'denominator') + __slots__ = ('_numerator', '_denominator') # We're immutable, so use __new__ not __init__ def __new__(cls, numerator=0, denominator=1): @@ -92,8 +92,8 @@ class Rational(RationalAbc): raise ZeroDivisionError('Rational(%s, 0)' % numerator) g = gcd(numerator, denominator) - self.numerator = int(numerator // g) - self.denominator = int(denominator // g) + self._numerator = int(numerator // g) + self._denominator = int(denominator // g) return self @classmethod @@ -167,6 +167,14 @@ class Rational(RationalAbc): result = new return result + @property + def numerator(a): + return a._numerator + + @property + def denominator(a): + return a._denominator + def __repr__(self): """repr(self)""" return ('Rational(%r,%r)' % (self.numerator, self.denominator)) @@ -192,20 +200,20 @@ class Rational(RationalAbc): Rational, that means that we define __add__ and __radd__ as: def __add__(self, other): + # Both types have numerators/denominator attributes, + # so do the operation directly if isinstance(other, (int, Rational)): - # Do the real operation. return Rational(self.numerator * other.denominator + other.numerator * self.denominator, self.denominator * other.denominator) - # float and complex don't follow this protocol, and - # Rational knows about them, so special case them. + # float and complex don't have those operations, but we + # know about those types, so special case them. elif isinstance(other, float): return float(self) + other elif isinstance(other, complex): return complex(self) + other - else: - # Let the other type take over. - return NotImplemented + # Let the other type take over. + return NotImplemented def __radd__(self, other): # radd handles more types than add because there's @@ -218,8 +226,7 @@ class Rational(RationalAbc): return float(other) + float(self) elif isinstance(other, Complex): return complex(other) + complex(self) - else: - return NotImplemented + return NotImplemented There are 5 different cases for a mixed-type addition on diff --git a/Lib/test/test_abstract_numbers.py b/Lib/test/test_abstract_numbers.py index aa383da..317d333 100644 --- a/Lib/test/test_abstract_numbers.py +++ b/Lib/test/test_abstract_numbers.py @@ -1,11 +1,12 @@ """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): @@ -37,7 +38,8 @@ class TestNumbers(unittest.TestCase): self.failUnless(issubclass(complex, Inexact)) c1, c2 = complex(3, 2), complex(4,1) - self.assertRaises(TypeError, trunc, c1) + # XXX: This is not ideal, but see the comment in math_trunc(). + self.assertRaises(TypeError, math.trunc, c1) self.assertRaises(TypeError, operator.mod, c1, c2) self.assertRaises(TypeError, divmod, c1, c2) self.assertRaises(TypeError, operator.floordiv, c1, c2) diff --git a/Lib/test/test_builtin.py b/Lib/test/test_builtin.py index 8582862..35cdcd4 100644 --- a/Lib/test/test_builtin.py +++ b/Lib/test/test_builtin.py @@ -1643,37 +1643,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: - def __trunc__(self): - return 23 - - class TestNoTrunc: - pass - - self.assertEqual(trunc(TestTrunc()), 23) - - self.assertRaises(TypeError, trunc) - self.assertRaises(TypeError, trunc, 1, 2) - self.assertRaises(TypeError, trunc, TestNoTrunc()) - - t = TestNoTrunc() - t.__trunc__ = lambda *args: args - self.assertRaises(TypeError, trunc, t) - self.assertRaises(TypeError, trunc, t, 0) - def test_tuple(self): self.assertEqual(tuple(()), ()) t0_3 = (0, 1, 2, 3) diff --git a/Lib/test/test_complex.py b/Lib/test/test_complex.py index 1bb31dd..42dc3cf 100644 --- a/Lib/test/test_complex.py +++ b/Lib/test/test_complex.py @@ -338,6 +338,13 @@ class ComplexTest(unittest.TestCase): except (OSError, IOError): pass + if float.__getformat__("double").startswith("IEEE"): + def test_plus_minus_0j(self): + # test that -0j and 0j literals are not identified + z1, z2 = 0j, -0j + self.assertEquals(atan2(z1.imag, -1.), atan2(0., -1.)) + self.assertEquals(atan2(z2.imag, -1.), atan2(-0., -1.)) + def test_main(): test_support.run_unittest(ComplexTest) diff --git a/Lib/test/test_decimal.py b/Lib/test/test_decimal.py index 1d3765a..e051ada 100644 --- a/Lib/test/test_decimal.py +++ b/Lib/test/test_decimal.py @@ -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) @@ -1213,7 +1214,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): diff --git a/Lib/test/test_math.py b/Lib/test/test_math.py index 2333392..aa44253 100644 --- a/Lib/test/test_math.py +++ b/Lib/test/test_math.py @@ -233,6 +233,38 @@ 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) + self.assertRaises(TypeError, math.trunc, TestNoTrunc()) + + # XXX Doesn't work because the method is looked up on + # the type only. + #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) diff --git a/Lib/test/test_rational.py b/Lib/test/test_rational.py index 284a42a..c9a129f 100644 --- a/Lib/test/test_rational.py +++ b/Lib/test/test_rational.py @@ -117,6 +117,17 @@ class RationalTest(unittest.TestCase): r.__init__(2, 15) self.assertEquals((7, 3), _components(r)) + self.assertRaises(AttributeError, setattr, r, 'numerator', 12) + self.assertRaises(AttributeError, setattr, r, 'denominator', 6) + self.assertEquals((7, 3), _components(r)) + + # But if you _really_ need to: + r._numerator = 4 + r._denominator = 2 + self.assertEquals((4, 2), _components(r)) + # Which breaks some important operations: + self.assertNotEquals(R(4, 2), r) + def testFromFloat(self): self.assertRaisesMessage( TypeError, "Rational.from_float() only takes floats, not 3 (int)", @@ -193,7 +204,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(-2, math.floor(R(-11, 10))) self.assertTypedEquals(-1, math.ceil(R(-11, 10))) self.assertTypedEquals(-1, math.ceil(R(-10, 10))) @@ -337,11 +348,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)) |