mirror of
				https://github.com/python/cpython.git
				synced 2025-10-31 13:41:24 +00:00 
			
		
		
		
	 292d351fc1
			
		
	
	
		292d351fc1
		
	
	
	
	
		
			
			svn+ssh://pythondev@svn.python.org/python/trunk
NOTE: I blocked the following revisions:
      svnmerge.py block -r 60521,60522,60528,60529,60534,60539
      The new tests must be merged with lots of manual work.
........
  r60493 | georg.brandl | 2008-02-01 12:59:08 +0100 (Fri, 01 Feb 2008) | 2 lines
  Update IPv6 RFC number.
........
  r60497 | georg.brandl | 2008-02-01 16:50:15 +0100 (Fri, 01 Feb 2008) | 2 lines
  Add link checker builder, written for GHOP by Thomas Lamb.
........
  r60500 | georg.brandl | 2008-02-01 19:08:09 +0100 (Fri, 01 Feb 2008) | 2 lines
  Rename batch file.
........
  r60504 | christian.heimes | 2008-02-01 19:49:26 +0100 (Fri, 01 Feb 2008) | 1 line
  More int -> pid_t.
........
  r60507 | georg.brandl | 2008-02-01 20:24:01 +0100 (Fri, 01 Feb 2008) | 2 lines
  Wording nit.
........
  r60510 | georg.brandl | 2008-02-01 21:45:33 +0100 (Fri, 01 Feb 2008) | 2 lines
  Update for latest sphinx latex writer.
........
  r60511 | raymond.hettinger | 2008-02-01 22:30:23 +0100 (Fri, 01 Feb 2008) | 1 line
  Issue #1996: float.as_integer_ratio() should return fraction in lowest terms.
........
  r60512 | raymond.hettinger | 2008-02-01 23:15:52 +0100 (Fri, 01 Feb 2008) | 1 line
  Integer ratio should return ints instead of longs whereever possible.
........
  r60513 | raymond.hettinger | 2008-02-01 23:22:50 +0100 (Fri, 01 Feb 2008) | 1 line
  labs() takes a long for an input.
........
  r60514 | raymond.hettinger | 2008-02-01 23:42:59 +0100 (Fri, 01 Feb 2008) | 1 line
  Test round-trip on float.as_integer_ratio() and float.__truediv__().
........
  r60515 | marc-andre.lemburg | 2008-02-01 23:58:17 +0100 (Fri, 01 Feb 2008) | 3 lines
  Bump distutils version number to match Python version.
........
  r60516 | raymond.hettinger | 2008-02-02 00:12:19 +0100 (Sat, 02 Feb 2008) | 1 line
  Fix int/long typecase.  Add check for non-binary floating point.
........
  r60517 | raymond.hettinger | 2008-02-02 00:45:44 +0100 (Sat, 02 Feb 2008) | 1 line
  Add protection from weirdness while scaling the mantissa to an integer.
........
  r60518 | raymond.hettinger | 2008-02-02 06:11:40 +0100 (Sat, 02 Feb 2008) | 1 line
  Simpler solution to handling non-IEEE 754 environments.
........
  r60519 | raymond.hettinger | 2008-02-02 06:24:44 +0100 (Sat, 02 Feb 2008) | 1 line
  Neaten-up a bit.
........
  r60520 | georg.brandl | 2008-02-02 10:56:20 +0100 (Sat, 02 Feb 2008) | 2 lines
  Amendments to the urllib2 docs, written for GHOP by Thomas Lamb.
........
  r60525 | georg.brandl | 2008-02-02 11:49:58 +0100 (Sat, 02 Feb 2008) | 3 lines
  Add email example how to send a multipart message.
  Written for GHOP by Martin Matejek.
........
  r60526 | georg.brandl | 2008-02-02 12:05:00 +0100 (Sat, 02 Feb 2008) | 2 lines
  Rewrite test_socketserver as unittest, written for GHOP by Benjamin Petersen.
........
  r60527 | georg.brandl | 2008-02-02 12:05:34 +0100 (Sat, 02 Feb 2008) | 2 lines
  Add GHOP contributor.
........
  r60530 | mark.dickinson | 2008-02-02 18:16:13 +0100 (Sat, 02 Feb 2008) | 2 lines
  Make the Rational constructor accept '3.' and '.2' as well as '3.2'.
........
  r60531 | neal.norwitz | 2008-02-02 19:52:51 +0100 (Sat, 02 Feb 2008) | 1 line
  Update the leaky tests (ie, ignore these tests if they report leaks).  This version has been running for a while.
........
  r60533 | skip.montanaro | 2008-02-02 20:11:57 +0100 (Sat, 02 Feb 2008) | 7 lines
  Split the refleak mail body into two parts, the first being those failing
  tests which are deemed more important issues, the second those which are
  known to have difficult to solve problems and are generally expected to
  leak.  Hopefully this doesn't break the script...
........
  r60535 | georg.brandl | 2008-02-03 01:04:50 +0100 (Sun, 03 Feb 2008) | 3 lines
  Wait for a delay before reaping children -- this should fix the
  test_socketserver failures on several platforms.
........
  r60536 | brett.cannon | 2008-02-03 03:07:55 +0100 (Sun, 03 Feb 2008) | 2 lines
  Fix a minor typo.
........
  r60537 | brett.cannon | 2008-02-03 03:08:45 +0100 (Sun, 03 Feb 2008) | 3 lines
  Directories from CPPFLAGS and LDFLAGS were being added in the reverse order for
  searches as to how they were listed in the environment variable.
........
  r60538 | brett.cannon | 2008-02-03 03:34:14 +0100 (Sun, 03 Feb 2008) | 2 lines
  Remove extra tick marks and add a missing closing parenthesis.
........
  r60540 | andrew.macintyre | 2008-02-03 07:58:06 +0100 (Sun, 03 Feb 2008) | 2 lines
  Update OS/2 EMX build bits for 2.6.
........
  r60541 | andrew.macintyre | 2008-02-03 08:01:11 +0100 (Sun, 03 Feb 2008) | 2 lines
  Rename module definition file to reflect v2.6.
........
  r60542 | andrew.macintyre | 2008-02-03 08:07:31 +0100 (Sun, 03 Feb 2008) | 6 lines
  The wrapper function is supposed to be for spawnvpe() so that's
  what we should call [this wrapper only available on OS/2].
  Backport candidate to 2.5.
........
  r60544 | gregory.p.smith | 2008-02-03 08:20:53 +0100 (Sun, 03 Feb 2008) | 6 lines
  Merge this fix from the pybsddb tree:
  r293 | jcea | 2008-01-31 01:08:19 -0800 (Thu, 31 Jan 2008) | 4 lines
  Solved memory leak when using cursors with
  databases without environment.
........
  r60546 | gregory.p.smith | 2008-02-03 09:01:46 +0100 (Sun, 03 Feb 2008) | 2 lines
  remove a repeated occurance of a hardcoded berkeleydb library version number
........
  r60549 | brett.cannon | 2008-02-03 10:59:21 +0100 (Sun, 03 Feb 2008) | 2 lines
  Add an entry for r60537.
........
  r60550 | georg.brandl | 2008-02-03 13:29:00 +0100 (Sun, 03 Feb 2008) | 2 lines
  #2003: fix sentence.
........
  r60551 | christian.heimes | 2008-02-03 15:34:18 +0100 (Sun, 03 Feb 2008) | 2 lines
  Fixed paths to Windows build directories in build_ext.py
  Use vsbuild instead of devenv in build.bat and _bsddb.vcproj
........
		
	
			
		
			
				
	
	
		
			425 lines
		
	
	
	
		
			17 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			425 lines
		
	
	
	
		
			17 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
| """Tests for Lib/rational.py."""
 | |
| 
 | |
| from decimal import Decimal
 | |
| from test.test_support import run_unittest, verbose
 | |
| import math
 | |
| import operator
 | |
| import rational
 | |
| import unittest
 | |
| from copy import copy, deepcopy
 | |
| from pickle import dumps, loads
 | |
| R = rational.Rational
 | |
| gcd = rational.gcd
 | |
| 
 | |
| 
 | |
| class GcdTest(unittest.TestCase):
 | |
| 
 | |
|     def testMisc(self):
 | |
|         self.assertEquals(0, gcd(0, 0))
 | |
|         self.assertEquals(1, gcd(1, 0))
 | |
|         self.assertEquals(-1, gcd(-1, 0))
 | |
|         self.assertEquals(1, gcd(0, 1))
 | |
|         self.assertEquals(-1, gcd(0, -1))
 | |
|         self.assertEquals(1, gcd(7, 1))
 | |
|         self.assertEquals(-1, gcd(7, -1))
 | |
|         self.assertEquals(1, gcd(-23, 15))
 | |
|         self.assertEquals(12, gcd(120, 84))
 | |
|         self.assertEquals(-12, gcd(84, -120))
 | |
| 
 | |
| 
 | |
| def _components(r):
 | |
|     return (r.numerator, r.denominator)
 | |
| 
 | |
| 
 | |
| class RationalTest(unittest.TestCase):
 | |
| 
 | |
|     def assertTypedEquals(self, expected, actual):
 | |
|         """Asserts that both the types and values are the same."""
 | |
|         self.assertEquals(type(expected), type(actual))
 | |
|         self.assertEquals(expected, actual)
 | |
| 
 | |
|     def assertRaisesMessage(self, exc_type, message,
 | |
|                             callable, *args, **kwargs):
 | |
|         """Asserts that callable(*args, **kwargs) raises exc_type(message)."""
 | |
|         try:
 | |
|             callable(*args, **kwargs)
 | |
|         except exc_type as e:
 | |
|             self.assertEquals(message, str(e))
 | |
|         else:
 | |
|             self.fail("%s not raised" % exc_type.__name__)
 | |
| 
 | |
|     def testInit(self):
 | |
|         self.assertEquals((0, 1), _components(R()))
 | |
|         self.assertEquals((7, 1), _components(R(7)))
 | |
|         self.assertEquals((7, 3), _components(R(R(7, 3))))
 | |
| 
 | |
|         self.assertEquals((-1, 1), _components(R(-1, 1)))
 | |
|         self.assertEquals((-1, 1), _components(R(1, -1)))
 | |
|         self.assertEquals((1, 1), _components(R(-2, -2)))
 | |
|         self.assertEquals((1, 2), _components(R(5, 10)))
 | |
|         self.assertEquals((7, 15), _components(R(7, 15)))
 | |
|         self.assertEquals((10**23, 1), _components(R(10**23)))
 | |
| 
 | |
|         self.assertRaisesMessage(ZeroDivisionError, "Rational(12, 0)",
 | |
|                                  R, 12, 0)
 | |
|         self.assertRaises(TypeError, R, 1.5)
 | |
|         self.assertRaises(TypeError, R, 1.5 + 3j)
 | |
| 
 | |
|         self.assertRaises(TypeError, R, R(1, 2), 3)
 | |
|         self.assertRaises(TypeError, R, "3/2", 3)
 | |
| 
 | |
|     def testFromString(self):
 | |
|         self.assertEquals((5, 1), _components(R("5")))
 | |
|         self.assertEquals((3, 2), _components(R("3/2")))
 | |
|         self.assertEquals((3, 2), _components(R(" \n  +3/2")))
 | |
|         self.assertEquals((-3, 2), _components(R("-3/2  ")))
 | |
|         self.assertEquals((3, 2), _components(R("    03/02 \n  ")))
 | |
|         self.assertEquals((3, 2), _components(R("    03/02 \n  ")))
 | |
|         self.assertEquals((16, 5), _components(R(" 3.2 ")))
 | |
|         self.assertEquals((-16, 5), _components(R(" -3.2 ")))
 | |
|         self.assertEquals((-3, 1), _components(R(" -3. ")))
 | |
|         self.assertEquals((3, 5), _components(R(" .6 ")))
 | |
| 
 | |
|         self.assertRaisesMessage(
 | |
|             ZeroDivisionError, "Rational(3, 0)",
 | |
|             R, "3/0")
 | |
|         self.assertRaisesMessage(
 | |
|             ValueError, "Invalid literal for Rational: 3/",
 | |
|             R, "3/")
 | |
|         self.assertRaisesMessage(
 | |
|             ValueError, "Invalid literal for Rational: 3 /2",
 | |
|             R, "3 /2")
 | |
|         self.assertRaisesMessage(
 | |
|             # Denominators don't need a sign.
 | |
|             ValueError, "Invalid literal for Rational: 3/+2",
 | |
|             R, "3/+2")
 | |
|         self.assertRaisesMessage(
 | |
|             # Imitate float's parsing.
 | |
|             ValueError, "Invalid literal for Rational: + 3/2",
 | |
|             R, "+ 3/2")
 | |
|         self.assertRaisesMessage(
 | |
|             # Avoid treating '.' as a regex special character.
 | |
|             ValueError, "Invalid literal for Rational: 3a2",
 | |
|             R, "3a2")
 | |
|         self.assertRaisesMessage(
 | |
|             # Only parse ordinary decimals, not scientific form.
 | |
|             ValueError, "Invalid literal for Rational: 3.2e4",
 | |
|             R, "3.2e4")
 | |
|         self.assertRaisesMessage(
 | |
|             # Don't accept combinations of decimals and rationals.
 | |
|             ValueError, "Invalid literal for Rational: 3/7.2",
 | |
|             R, "3/7.2")
 | |
|         self.assertRaisesMessage(
 | |
|             # Don't accept combinations of decimals and rationals.
 | |
|             ValueError, "Invalid literal for Rational: 3.2/7",
 | |
|             R, "3.2/7")
 | |
|         self.assertRaisesMessage(
 | |
|             # Allow 3. and .3, but not .
 | |
|             ValueError, "Invalid literal for Rational: .",
 | |
|             R, ".")
 | |
| 
 | |
|     def testImmutable(self):
 | |
|         r = R(7, 3)
 | |
|         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)",
 | |
|             R.from_float, 3)
 | |
| 
 | |
|         self.assertEquals((0, 1), _components(R.from_float(-0.0)))
 | |
|         self.assertEquals((10, 1), _components(R.from_float(10.0)))
 | |
|         self.assertEquals((-5, 2), _components(R.from_float(-2.5)))
 | |
|         self.assertEquals((99999999999999991611392, 1),
 | |
|                           _components(R.from_float(1e23)))
 | |
|         self.assertEquals(float(10**23), float(R.from_float(1e23)))
 | |
|         self.assertEquals((3602879701896397, 1125899906842624),
 | |
|                           _components(R.from_float(3.2)))
 | |
|         self.assertEquals(3.2, float(R.from_float(3.2)))
 | |
| 
 | |
|         inf = 1e1000
 | |
|         nan = inf - inf
 | |
|         self.assertRaisesMessage(
 | |
|             TypeError, "Cannot convert inf to Rational.",
 | |
|             R.from_float, inf)
 | |
|         self.assertRaisesMessage(
 | |
|             TypeError, "Cannot convert -inf to Rational.",
 | |
|             R.from_float, -inf)
 | |
|         self.assertRaisesMessage(
 | |
|             TypeError, "Cannot convert nan to Rational.",
 | |
|             R.from_float, nan)
 | |
| 
 | |
|     def testFromDecimal(self):
 | |
|         self.assertRaisesMessage(
 | |
|             TypeError,
 | |
|             "Rational.from_decimal() only takes Decimals, not 3 (int)",
 | |
|             R.from_decimal, 3)
 | |
|         self.assertEquals(R(0), R.from_decimal(Decimal("-0")))
 | |
|         self.assertEquals(R(5, 10), R.from_decimal(Decimal("0.5")))
 | |
|         self.assertEquals(R(5, 1000), R.from_decimal(Decimal("5e-3")))
 | |
|         self.assertEquals(R(5000), R.from_decimal(Decimal("5e3")))
 | |
|         self.assertEquals(1 - R(1, 10**30),
 | |
|                           R.from_decimal(Decimal("0." + "9" * 30)))
 | |
| 
 | |
|         self.assertRaisesMessage(
 | |
|             TypeError, "Cannot convert Infinity to Rational.",
 | |
|             R.from_decimal, Decimal("inf"))
 | |
|         self.assertRaisesMessage(
 | |
|             TypeError, "Cannot convert -Infinity to Rational.",
 | |
|             R.from_decimal, Decimal("-inf"))
 | |
|         self.assertRaisesMessage(
 | |
|             TypeError, "Cannot convert NaN to Rational.",
 | |
|             R.from_decimal, Decimal("nan"))
 | |
|         self.assertRaisesMessage(
 | |
|             TypeError, "Cannot convert sNaN to Rational.",
 | |
|             R.from_decimal, Decimal("snan"))
 | |
| 
 | |
|     def testFromContinuedFraction(self):
 | |
|         self.assertRaises(TypeError, R.from_continued_fraction, None)
 | |
|         phi = R.from_continued_fraction([1]*100)
 | |
|         self.assertEquals(round(phi - (1 + 5 ** 0.5) / 2, 10), 0.0)
 | |
| 
 | |
|         minusphi = R.from_continued_fraction([-1]*100)
 | |
|         self.assertEquals(round(minusphi + (1 + 5 ** 0.5) / 2, 10), 0.0)
 | |
| 
 | |
|         self.assertEquals(R.from_continued_fraction([0]), R(0))
 | |
|         self.assertEquals(R.from_continued_fraction([]), R(0))
 | |
| 
 | |
|     def testAsContinuedFraction(self):
 | |
|         self.assertEqual(R.from_float(math.pi).as_continued_fraction()[:15],
 | |
|                          [3, 7, 15, 1, 292, 1, 1, 1, 2, 1, 3, 1, 14, 3, 3])
 | |
|         self.assertEqual(R.from_float(-math.pi).as_continued_fraction()[:16],
 | |
|                          [-4, 1, 6, 15, 1, 292, 1, 1, 1, 2, 1, 3, 1, 14, 3, 3])
 | |
|         self.assertEqual(R(0).as_continued_fraction(), [0])
 | |
| 
 | |
|     def testApproximateFrom(self):
 | |
|         self.assertEqual(R.from_float(math.pi).approximate(10000), R(355, 113))
 | |
|         self.assertEqual(R.from_float(-math.pi).approximate(10000), R(-355, 113))
 | |
|         self.assertEqual(R.from_float(0.0).approximate(10000), R(0))
 | |
| 
 | |
|     def testConversions(self):
 | |
|         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)))
 | |
|         self.assertTypedEquals(-1, int(R(-11, 10)))
 | |
| 
 | |
|         self.assertTypedEquals(0, round(R(-1, 10)))
 | |
|         self.assertTypedEquals(0, round(R(-5, 10)))
 | |
|         self.assertTypedEquals(-2, round(R(-15, 10)))
 | |
|         self.assertTypedEquals(-1, round(R(-7, 10)))
 | |
| 
 | |
|         self.assertEquals(False, bool(R(0, 1)))
 | |
|         self.assertEquals(True, bool(R(3, 2)))
 | |
|         self.assertTypedEquals(0.1, float(R(1, 10)))
 | |
| 
 | |
|         # Check that __float__ isn't implemented by converting the
 | |
|         # numerator and denominator to float before dividing.
 | |
|         self.assertRaises(OverflowError, float, int('2'*400+'7'))
 | |
|         self.assertAlmostEquals(2.0/3,
 | |
|                                 float(R(int('2'*400+'7'), int('3'*400+'1'))))
 | |
| 
 | |
|         self.assertTypedEquals(0.1+0j, complex(R(1,10)))
 | |
| 
 | |
|     def testRound(self):
 | |
|         self.assertTypedEquals(R(-200), round(R(-150), -2))
 | |
|         self.assertTypedEquals(R(-200), round(R(-250), -2))
 | |
|         self.assertTypedEquals(R(30), round(R(26), -1))
 | |
|         self.assertTypedEquals(R(-2, 10), round(R(-15, 100), 1))
 | |
|         self.assertTypedEquals(R(-2, 10), round(R(-25, 100), 1))
 | |
| 
 | |
| 
 | |
|     def testArithmetic(self):
 | |
|         self.assertEquals(R(1, 2), R(1, 10) + R(2, 5))
 | |
|         self.assertEquals(R(-3, 10), R(1, 10) - R(2, 5))
 | |
|         self.assertEquals(R(1, 25), R(1, 10) * R(2, 5))
 | |
|         self.assertEquals(R(1, 4), R(1, 10) / R(2, 5))
 | |
|         self.assertTypedEquals(2, R(9, 10) // R(2, 5))
 | |
|         self.assertTypedEquals(10**23, R(10**23, 1) // R(1))
 | |
|         self.assertEquals(R(2, 3), R(-7, 3) % R(3, 2))
 | |
|         self.assertEquals(R(8, 27), R(2, 3) ** R(3))
 | |
|         self.assertEquals(R(27, 8), R(2, 3) ** R(-3))
 | |
|         self.assertTypedEquals(2.0, R(4) ** R(1, 2))
 | |
|         z = pow(R(-1), R(1, 2))
 | |
|         self.assertAlmostEquals(z.real, 0)
 | |
|         self.assertEquals(z.imag, 1)
 | |
| 
 | |
|     def testMixedArithmetic(self):
 | |
|         self.assertTypedEquals(R(11, 10), R(1, 10) + 1)
 | |
|         self.assertTypedEquals(1.1, R(1, 10) + 1.0)
 | |
|         self.assertTypedEquals(1.1 + 0j, R(1, 10) + (1.0 + 0j))
 | |
|         self.assertTypedEquals(R(11, 10), 1 + R(1, 10))
 | |
|         self.assertTypedEquals(1.1, 1.0 + R(1, 10))
 | |
|         self.assertTypedEquals(1.1 + 0j, (1.0 + 0j) + R(1, 10))
 | |
| 
 | |
|         self.assertTypedEquals(R(-9, 10), R(1, 10) - 1)
 | |
|         self.assertTypedEquals(-0.9, R(1, 10) - 1.0)
 | |
|         self.assertTypedEquals(-0.9 + 0j, R(1, 10) - (1.0 + 0j))
 | |
|         self.assertTypedEquals(R(9, 10), 1 - R(1, 10))
 | |
|         self.assertTypedEquals(0.9, 1.0 - R(1, 10))
 | |
|         self.assertTypedEquals(0.9 + 0j, (1.0 + 0j) - R(1, 10))
 | |
| 
 | |
|         self.assertTypedEquals(R(1, 10), R(1, 10) * 1)
 | |
|         self.assertTypedEquals(0.1, R(1, 10) * 1.0)
 | |
|         self.assertTypedEquals(0.1 + 0j, R(1, 10) * (1.0 + 0j))
 | |
|         self.assertTypedEquals(R(1, 10), 1 * R(1, 10))
 | |
|         self.assertTypedEquals(0.1, 1.0 * R(1, 10))
 | |
|         self.assertTypedEquals(0.1 + 0j, (1.0 + 0j) * R(1, 10))
 | |
| 
 | |
|         self.assertTypedEquals(R(1, 10), R(1, 10) / 1)
 | |
|         self.assertTypedEquals(0.1, R(1, 10) / 1.0)
 | |
|         self.assertTypedEquals(0.1 + 0j, R(1, 10) / (1.0 + 0j))
 | |
|         self.assertTypedEquals(R(10, 1), 1 / R(1, 10))
 | |
|         self.assertTypedEquals(10.0, 1.0 / R(1, 10))
 | |
|         self.assertTypedEquals(10.0 + 0j, (1.0 + 0j) / R(1, 10))
 | |
| 
 | |
|         self.assertTypedEquals(0, R(1, 10) // 1)
 | |
|         self.assertTypedEquals(0, R(1, 10) // 1.0)
 | |
|         self.assertTypedEquals(10, 1 // R(1, 10))
 | |
|         self.assertTypedEquals(10**23, 10**22 // R(1, 10))
 | |
|         self.assertTypedEquals(10, 1.0 // R(1, 10))
 | |
| 
 | |
|         self.assertTypedEquals(R(1, 10), R(1, 10) % 1)
 | |
|         self.assertTypedEquals(0.1, R(1, 10) % 1.0)
 | |
|         self.assertTypedEquals(R(0, 1), 1 % R(1, 10))
 | |
|         self.assertTypedEquals(0.0, 1.0 % R(1, 10))
 | |
| 
 | |
|         # No need for divmod since we don't override it.
 | |
| 
 | |
|         # ** has more interesting conversion rules.
 | |
|         self.assertTypedEquals(R(100, 1), R(1, 10) ** -2)
 | |
|         self.assertTypedEquals(R(100, 1), R(10, 1) ** 2)
 | |
|         self.assertTypedEquals(0.1, R(1, 10) ** 1.0)
 | |
|         self.assertTypedEquals(0.1 + 0j, R(1, 10) ** (1.0 + 0j))
 | |
|         self.assertTypedEquals(4 , 2 ** R(2, 1))
 | |
|         z = pow(-1, R(1, 2))
 | |
|         self.assertAlmostEquals(0, z.real)
 | |
|         self.assertEquals(1, z.imag)
 | |
|         self.assertTypedEquals(R(1, 4) , 2 ** R(-2, 1))
 | |
|         self.assertTypedEquals(2.0 , 4 ** R(1, 2))
 | |
|         self.assertTypedEquals(0.25, 2.0 ** R(-2, 1))
 | |
|         self.assertTypedEquals(1.0 + 0j, (1.0 + 0j) ** R(1, 10))
 | |
| 
 | |
|     def testMixingWithDecimal(self):
 | |
|         # Decimal refuses mixed comparisons.
 | |
|         self.assertRaisesMessage(
 | |
|             TypeError,
 | |
|             "unsupported operand type(s) for +: 'Rational' and 'Decimal'",
 | |
|             operator.add, R(3,11), Decimal('3.1415926'))
 | |
|         self.assertNotEquals(R(5, 2), Decimal('2.5'))
 | |
| 
 | |
|     def testComparisons(self):
 | |
|         self.assertTrue(R(1, 2) < R(2, 3))
 | |
|         self.assertFalse(R(1, 2) < R(1, 2))
 | |
|         self.assertTrue(R(1, 2) <= R(2, 3))
 | |
|         self.assertTrue(R(1, 2) <= R(1, 2))
 | |
|         self.assertFalse(R(2, 3) <= R(1, 2))
 | |
|         self.assertTrue(R(1, 2) == R(1, 2))
 | |
|         self.assertFalse(R(1, 2) == R(1, 3))
 | |
| 
 | |
|     def testMixedLess(self):
 | |
|         self.assertTrue(2 < R(5, 2))
 | |
|         self.assertFalse(2 < R(4, 2))
 | |
|         self.assertTrue(R(5, 2) < 3)
 | |
|         self.assertFalse(R(4, 2) < 2)
 | |
| 
 | |
|         self.assertTrue(R(1, 2) < 0.6)
 | |
|         self.assertFalse(R(1, 2) < 0.4)
 | |
|         self.assertTrue(0.4 < R(1, 2))
 | |
|         self.assertFalse(0.5 < R(1, 2))
 | |
| 
 | |
|     def testMixedLessEqual(self):
 | |
|         self.assertTrue(0.5 <= R(1, 2))
 | |
|         self.assertFalse(0.6 <= R(1, 2))
 | |
|         self.assertTrue(R(1, 2) <= 0.5)
 | |
|         self.assertFalse(R(1, 2) <= 0.4)
 | |
|         self.assertTrue(2 <= R(4, 2))
 | |
|         self.assertFalse(2 <= R(3, 2))
 | |
|         self.assertTrue(R(4, 2) <= 2)
 | |
|         self.assertFalse(R(5, 2) <= 2)
 | |
| 
 | |
|     def testBigFloatComparisons(self):
 | |
|         # 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(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))
 | |
|         self.assertTrue(R(10**23) > complex(10**23))
 | |
|         self.assertFalse(R(10**23) <= complex(10**23))
 | |
| 
 | |
|     def testMixedEqual(self):
 | |
|         self.assertTrue(0.5 == R(1, 2))
 | |
|         self.assertFalse(0.6 == R(1, 2))
 | |
|         self.assertTrue(R(1, 2) == 0.5)
 | |
|         self.assertFalse(R(1, 2) == 0.4)
 | |
|         self.assertTrue(2 == R(4, 2))
 | |
|         self.assertFalse(2 == R(3, 2))
 | |
|         self.assertTrue(R(4, 2) == 2)
 | |
|         self.assertFalse(R(5, 2) == 2)
 | |
| 
 | |
|     def testStringification(self):
 | |
|         self.assertEquals("Rational(7,3)", repr(R(7, 3)))
 | |
|         self.assertEquals("7/3", str(R(7, 3)))
 | |
|         self.assertEquals("7", str(R(7, 1)))
 | |
| 
 | |
|     def testHash(self):
 | |
|         self.assertEquals(hash(2.5), hash(R(5, 2)))
 | |
|         self.assertEquals(hash(10**50), hash(R(10**50)))
 | |
|         self.assertNotEquals(hash(float(10**23)), hash(R(10**23)))
 | |
| 
 | |
|     def testApproximatePi(self):
 | |
|         # Algorithm borrowed from
 | |
|         # http://docs.python.org/lib/decimal-recipes.html
 | |
|         three = R(3)
 | |
|         lasts, t, s, n, na, d, da = 0, three, 3, 1, 0, 0, 24
 | |
|         while abs(s - lasts) > R(1, 10**9):
 | |
|             lasts = s
 | |
|             n, na = n+na, na+8
 | |
|             d, da = d+da, da+32
 | |
|             t = (t * n) / d
 | |
|             s += t
 | |
|         self.assertAlmostEquals(math.pi, s)
 | |
| 
 | |
|     def testApproximateCos1(self):
 | |
|         # Algorithm borrowed from
 | |
|         # http://docs.python.org/lib/decimal-recipes.html
 | |
|         x = R(1)
 | |
|         i, lasts, s, fact, num, sign = 0, 0, R(1), 1, 1, 1
 | |
|         while abs(s - lasts) > R(1, 10**9):
 | |
|             lasts = s
 | |
|             i += 2
 | |
|             fact *= i * (i-1)
 | |
|             num *= x * x
 | |
|             sign *= -1
 | |
|             s += num / fact * sign
 | |
|         self.assertAlmostEquals(math.cos(1), s)
 | |
| 
 | |
|     def test_copy_deepcopy_pickle(self):
 | |
|         r = R(13, 7)
 | |
|         self.assertEqual(r, loads(dumps(r)))
 | |
|         self.assertEqual(id(r), id(copy(r)))
 | |
|         self.assertEqual(id(r), id(deepcopy(r)))
 | |
| 
 | |
| def test_main():
 | |
|     run_unittest(RationalTest, GcdTest)
 | |
| 
 | |
| if __name__ == '__main__':
 | |
|     test_main()
 |