blob: 18ab28cfebe0c8f099fedaafb3f04fdb8ed2d952 [file] [log] [blame]
Christian Heimes3feef612008-02-11 06:19:17 +00001"""Tests for Lib/fractions.py."""
Guido van Rossum7736b5b2008-01-15 21:44:53 +00002
3from decimal import Decimal
Zachary Ware38c707e2015-04-13 15:00:43 -05004from test.support import requires_IEEE_754
Guido van Rossum7736b5b2008-01-15 21:44:53 +00005import math
Mark Dickinson85424c92009-07-18 14:41:42 +00006import numbers
Guido van Rossum7736b5b2008-01-15 21:44:53 +00007import operator
Christian Heimes3feef612008-02-11 06:19:17 +00008import fractions
Ezio Melotti682d3742012-02-29 14:05:53 +02009import sys
Guido van Rossum7736b5b2008-01-15 21:44:53 +000010import unittest
Serhiy Storchaka48e47aa2015-05-13 00:19:51 +030011import warnings
Christian Heimes969fe572008-01-25 11:23:10 +000012from copy import copy, deepcopy
Neal Norwitz6ff93fe2008-01-26 21:52:30 +000013from pickle import dumps, loads
Christian Heimes68f5fbe2008-02-14 08:27:37 +000014F = fractions.Fraction
Christian Heimes3feef612008-02-11 06:19:17 +000015gcd = fractions.gcd
Christian Heimesaf98da12008-01-27 15:18:18 +000016
Mark Dickinson85424c92009-07-18 14:41:42 +000017class DummyFloat(object):
18 """Dummy float class for testing comparisons with Fractions"""
19
20 def __init__(self, value):
21 if not isinstance(value, float):
22 raise TypeError("DummyFloat can only be initialized from float")
23 self.value = value
24
25 def _richcmp(self, other, op):
26 if isinstance(other, numbers.Rational):
27 return op(F.from_float(self.value), other)
28 elif isinstance(other, DummyFloat):
29 return op(self.value, other.value)
30 else:
31 return NotImplemented
32
33 def __eq__(self, other): return self._richcmp(other, operator.eq)
34 def __le__(self, other): return self._richcmp(other, operator.le)
35 def __lt__(self, other): return self._richcmp(other, operator.lt)
36 def __ge__(self, other): return self._richcmp(other, operator.ge)
37 def __gt__(self, other): return self._richcmp(other, operator.gt)
38
39 # shouldn't be calling __float__ at all when doing comparisons
40 def __float__(self):
41 assert False, "__float__ should not be invoked for comparisons"
42
43 # same goes for subtraction
44 def __sub__(self, other):
45 assert False, "__sub__ should not be invoked for comparisons"
46 __rsub__ = __sub__
47
48
49class DummyRational(object):
50 """Test comparison of Fraction with a naive rational implementation."""
51
52 def __init__(self, num, den):
Serhiy Storchaka48e47aa2015-05-13 00:19:51 +030053 g = math.gcd(num, den)
Mark Dickinson85424c92009-07-18 14:41:42 +000054 self.num = num // g
55 self.den = den // g
56
57 def __eq__(self, other):
58 if isinstance(other, fractions.Fraction):
59 return (self.num == other._numerator and
60 self.den == other._denominator)
61 else:
62 return NotImplemented
63
64 def __lt__(self, other):
65 return(self.num * other._denominator < self.den * other._numerator)
66
67 def __gt__(self, other):
68 return(self.num * other._denominator > self.den * other._numerator)
69
70 def __le__(self, other):
71 return(self.num * other._denominator <= self.den * other._numerator)
72
73 def __ge__(self, other):
74 return(self.num * other._denominator >= self.den * other._numerator)
75
76 # this class is for testing comparisons; conversion to float
77 # should never be used for a comparison, since it loses accuracy
78 def __float__(self):
79 assert False, "__float__ should not be invoked"
Christian Heimesaf98da12008-01-27 15:18:18 +000080
Ezio Melotti682d3742012-02-29 14:05:53 +020081class DummyFraction(fractions.Fraction):
82 """Dummy Fraction subclass for copy and deepcopy testing."""
83
Christian Heimesaf98da12008-01-27 15:18:18 +000084class GcdTest(unittest.TestCase):
85
86 def testMisc(self):
Serhiy Storchaka48e47aa2015-05-13 00:19:51 +030087 # fractions.gcd() is deprecated
88 with self.assertWarnsRegex(DeprecationWarning, r'fractions\.gcd'):
89 gcd(1, 1)
90 with warnings.catch_warnings():
91 warnings.filterwarnings('ignore', r'fractions\.gcd',
92 DeprecationWarning)
93 self.assertEqual(0, gcd(0, 0))
94 self.assertEqual(1, gcd(1, 0))
95 self.assertEqual(-1, gcd(-1, 0))
96 self.assertEqual(1, gcd(0, 1))
97 self.assertEqual(-1, gcd(0, -1))
98 self.assertEqual(1, gcd(7, 1))
99 self.assertEqual(-1, gcd(7, -1))
100 self.assertEqual(1, gcd(-23, 15))
101 self.assertEqual(12, gcd(120, 84))
102 self.assertEqual(-12, gcd(84, -120))
103 self.assertEqual(gcd(120.0, 84), 12.0)
104 self.assertEqual(gcd(120, 84.0), 12.0)
105 self.assertEqual(gcd(F(120), F(84)), F(12))
106 self.assertEqual(gcd(F(120, 77), F(84, 55)), F(12, 385))
Christian Heimesaf98da12008-01-27 15:18:18 +0000107
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000108
109def _components(r):
110 return (r.numerator, r.denominator)
111
Christian Heimesaf98da12008-01-27 15:18:18 +0000112
Christian Heimes3feef612008-02-11 06:19:17 +0000113class FractionTest(unittest.TestCase):
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000114
115 def assertTypedEquals(self, expected, actual):
116 """Asserts that both the types and values are the same."""
Ezio Melottib3aedd42010-11-20 19:04:17 +0000117 self.assertEqual(type(expected), type(actual))
118 self.assertEqual(expected, actual)
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000119
Stefan Behnel3a374e02019-01-02 13:22:06 +0100120 def assertTypedTupleEquals(self, expected, actual):
121 """Asserts that both the types and values in the tuples are the same."""
122 self.assertTupleEqual(expected, actual)
123 self.assertListEqual(list(map(type, expected)), list(map(type, actual)))
124
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000125 def assertRaisesMessage(self, exc_type, message,
126 callable, *args, **kwargs):
127 """Asserts that callable(*args, **kwargs) raises exc_type(message)."""
128 try:
129 callable(*args, **kwargs)
130 except exc_type as e:
Ezio Melottib3aedd42010-11-20 19:04:17 +0000131 self.assertEqual(message, str(e))
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000132 else:
133 self.fail("%s not raised" % exc_type.__name__)
134
135 def testInit(self):
Ezio Melottib3aedd42010-11-20 19:04:17 +0000136 self.assertEqual((0, 1), _components(F()))
137 self.assertEqual((7, 1), _components(F(7)))
138 self.assertEqual((7, 3), _components(F(F(7, 3))))
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000139
Ezio Melottib3aedd42010-11-20 19:04:17 +0000140 self.assertEqual((-1, 1), _components(F(-1, 1)))
141 self.assertEqual((-1, 1), _components(F(1, -1)))
142 self.assertEqual((1, 1), _components(F(-2, -2)))
143 self.assertEqual((1, 2), _components(F(5, 10)))
144 self.assertEqual((7, 15), _components(F(7, 15)))
145 self.assertEqual((10**23, 1), _components(F(10**23)))
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000146
Ezio Melottib3aedd42010-11-20 19:04:17 +0000147 self.assertEqual((3, 77), _components(F(F(3, 7), 11)))
148 self.assertEqual((-9, 5), _components(F(2, F(-10, 9))))
149 self.assertEqual((2486, 2485), _components(F(F(22, 7), F(355, 113))))
Mark Dickinsond4d95f82009-04-24 14:06:19 +0000150
Christian Heimes3feef612008-02-11 06:19:17 +0000151 self.assertRaisesMessage(ZeroDivisionError, "Fraction(12, 0)",
Christian Heimes68f5fbe2008-02-14 08:27:37 +0000152 F, 12, 0)
Georg Brandl86b2fb92008-07-16 03:43:04 +0000153 self.assertRaises(TypeError, F, 1.5 + 3j)
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000154
Georg Brandl86b2fb92008-07-16 03:43:04 +0000155 self.assertRaises(TypeError, F, "3/2", 3)
Mark Dickinsond4d95f82009-04-24 14:06:19 +0000156 self.assertRaises(TypeError, F, 3, 0j)
157 self.assertRaises(TypeError, F, 3, 1j)
Mark Dickinson7caf9082016-08-23 16:16:52 +0100158 self.assertRaises(TypeError, F, 1, 2, 3)
Mark Dickinsond4d95f82009-04-24 14:06:19 +0000159
Mark Dickinson98127c32010-04-03 11:18:52 +0000160 @requires_IEEE_754
161 def testInitFromFloat(self):
Ezio Melottib3aedd42010-11-20 19:04:17 +0000162 self.assertEqual((5, 2), _components(F(2.5)))
163 self.assertEqual((0, 1), _components(F(-0.0)))
164 self.assertEqual((3602879701896397, 36028797018963968),
165 _components(F(0.1)))
Mark Dickinson73726aa2012-11-15 20:58:40 +0000166 # bug 16469: error types should be consistent with float -> int
167 self.assertRaises(ValueError, F, float('nan'))
168 self.assertRaises(OverflowError, F, float('inf'))
169 self.assertRaises(OverflowError, F, float('-inf'))
Mark Dickinson98127c32010-04-03 11:18:52 +0000170
171 def testInitFromDecimal(self):
Ezio Melottib3aedd42010-11-20 19:04:17 +0000172 self.assertEqual((11, 10),
173 _components(F(Decimal('1.1'))))
174 self.assertEqual((7, 200),
175 _components(F(Decimal('3.5e-2'))))
176 self.assertEqual((0, 1),
177 _components(F(Decimal('.000e20'))))
Mark Dickinson73726aa2012-11-15 20:58:40 +0000178 # bug 16469: error types should be consistent with decimal -> int
179 self.assertRaises(ValueError, F, Decimal('nan'))
180 self.assertRaises(ValueError, F, Decimal('snan'))
181 self.assertRaises(OverflowError, F, Decimal('inf'))
182 self.assertRaises(OverflowError, F, Decimal('-inf'))
Christian Heimes587c2bf2008-01-19 16:21:02 +0000183
184 def testFromString(self):
Ezio Melottib3aedd42010-11-20 19:04:17 +0000185 self.assertEqual((5, 1), _components(F("5")))
186 self.assertEqual((3, 2), _components(F("3/2")))
187 self.assertEqual((3, 2), _components(F(" \n +3/2")))
188 self.assertEqual((-3, 2), _components(F("-3/2 ")))
189 self.assertEqual((13, 2), _components(F(" 013/02 \n ")))
190 self.assertEqual((16, 5), _components(F(" 3.2 ")))
191 self.assertEqual((-16, 5), _components(F(" -3.2 ")))
192 self.assertEqual((-3, 1), _components(F(" -3. ")))
193 self.assertEqual((3, 5), _components(F(" .6 ")))
194 self.assertEqual((1, 3125), _components(F("32.e-5")))
195 self.assertEqual((1000000, 1), _components(F("1E+06")))
196 self.assertEqual((-12300, 1), _components(F("-1.23e4")))
197 self.assertEqual((0, 1), _components(F(" .0e+0\t")))
198 self.assertEqual((0, 1), _components(F("-0.000e0")))
Christian Heimes587c2bf2008-01-19 16:21:02 +0000199
200 self.assertRaisesMessage(
Christian Heimes3feef612008-02-11 06:19:17 +0000201 ZeroDivisionError, "Fraction(3, 0)",
Christian Heimes68f5fbe2008-02-14 08:27:37 +0000202 F, "3/0")
Christian Heimes587c2bf2008-01-19 16:21:02 +0000203 self.assertRaisesMessage(
Benjamin Petersondcf97b92008-07-02 17:30:14 +0000204 ValueError, "Invalid literal for Fraction: '3/'",
Christian Heimes68f5fbe2008-02-14 08:27:37 +0000205 F, "3/")
Christian Heimes587c2bf2008-01-19 16:21:02 +0000206 self.assertRaisesMessage(
Mark Dickinsoncf63f2f2009-04-22 17:50:21 +0000207 ValueError, "Invalid literal for Fraction: '/2'",
208 F, "/2")
209 self.assertRaisesMessage(
Benjamin Petersondcf97b92008-07-02 17:30:14 +0000210 ValueError, "Invalid literal for Fraction: '3 /2'",
Christian Heimes68f5fbe2008-02-14 08:27:37 +0000211 F, "3 /2")
Christian Heimes587c2bf2008-01-19 16:21:02 +0000212 self.assertRaisesMessage(
213 # Denominators don't need a sign.
Benjamin Petersondcf97b92008-07-02 17:30:14 +0000214 ValueError, "Invalid literal for Fraction: '3/+2'",
Christian Heimes68f5fbe2008-02-14 08:27:37 +0000215 F, "3/+2")
Christian Heimes587c2bf2008-01-19 16:21:02 +0000216 self.assertRaisesMessage(
217 # Imitate float's parsing.
Benjamin Petersondcf97b92008-07-02 17:30:14 +0000218 ValueError, "Invalid literal for Fraction: '+ 3/2'",
Christian Heimes68f5fbe2008-02-14 08:27:37 +0000219 F, "+ 3/2")
Christian Heimes587c2bf2008-01-19 16:21:02 +0000220 self.assertRaisesMessage(
Christian Heimesaf98da12008-01-27 15:18:18 +0000221 # Avoid treating '.' as a regex special character.
Benjamin Petersondcf97b92008-07-02 17:30:14 +0000222 ValueError, "Invalid literal for Fraction: '3a2'",
Christian Heimes68f5fbe2008-02-14 08:27:37 +0000223 F, "3a2")
Christian Heimesaf98da12008-01-27 15:18:18 +0000224 self.assertRaisesMessage(
Christian Heimesaf98da12008-01-27 15:18:18 +0000225 # Don't accept combinations of decimals and rationals.
Benjamin Petersondcf97b92008-07-02 17:30:14 +0000226 ValueError, "Invalid literal for Fraction: '3/7.2'",
Christian Heimes68f5fbe2008-02-14 08:27:37 +0000227 F, "3/7.2")
Christian Heimesaf98da12008-01-27 15:18:18 +0000228 self.assertRaisesMessage(
229 # Don't accept combinations of decimals and rationals.
Benjamin Petersondcf97b92008-07-02 17:30:14 +0000230 ValueError, "Invalid literal for Fraction: '3.2/7'",
Christian Heimes68f5fbe2008-02-14 08:27:37 +0000231 F, "3.2/7")
Christian Heimes292d3512008-02-03 16:51:08 +0000232 self.assertRaisesMessage(
233 # Allow 3. and .3, but not .
Benjamin Petersondcf97b92008-07-02 17:30:14 +0000234 ValueError, "Invalid literal for Fraction: '.'",
Christian Heimes68f5fbe2008-02-14 08:27:37 +0000235 F, ".")
Christian Heimes587c2bf2008-01-19 16:21:02 +0000236
237 def testImmutable(self):
Christian Heimes68f5fbe2008-02-14 08:27:37 +0000238 r = F(7, 3)
Christian Heimes587c2bf2008-01-19 16:21:02 +0000239 r.__init__(2, 15)
Ezio Melottib3aedd42010-11-20 19:04:17 +0000240 self.assertEqual((7, 3), _components(r))
Christian Heimes587c2bf2008-01-19 16:21:02 +0000241
Christian Heimes400adb02008-02-01 08:12:03 +0000242 self.assertRaises(AttributeError, setattr, r, 'numerator', 12)
243 self.assertRaises(AttributeError, setattr, r, 'denominator', 6)
Ezio Melottib3aedd42010-11-20 19:04:17 +0000244 self.assertEqual((7, 3), _components(r))
Christian Heimes400adb02008-02-01 08:12:03 +0000245
246 # But if you _really_ need to:
247 r._numerator = 4
248 r._denominator = 2
Ezio Melottib3aedd42010-11-20 19:04:17 +0000249 self.assertEqual((4, 2), _components(r))
Christian Heimes400adb02008-02-01 08:12:03 +0000250 # Which breaks some important operations:
Ezio Melottib3aedd42010-11-20 19:04:17 +0000251 self.assertNotEqual(F(4, 2), r)
Christian Heimes400adb02008-02-01 08:12:03 +0000252
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000253 def testFromFloat(self):
Georg Brandl2ee470f2008-07-16 12:55:28 +0000254 self.assertRaises(TypeError, F.from_float, 3+4j)
Ezio Melottib3aedd42010-11-20 19:04:17 +0000255 self.assertEqual((10, 1), _components(F.from_float(10)))
Georg Brandl3a9b0622009-01-03 22:07:57 +0000256 bigint = 1234567890123456789
Ezio Melottib3aedd42010-11-20 19:04:17 +0000257 self.assertEqual((bigint, 1), _components(F.from_float(bigint)))
258 self.assertEqual((0, 1), _components(F.from_float(-0.0)))
259 self.assertEqual((10, 1), _components(F.from_float(10.0)))
260 self.assertEqual((-5, 2), _components(F.from_float(-2.5)))
261 self.assertEqual((99999999999999991611392, 1),
262 _components(F.from_float(1e23)))
263 self.assertEqual(float(10**23), float(F.from_float(1e23)))
264 self.assertEqual((3602879701896397, 1125899906842624),
265 _components(F.from_float(3.2)))
266 self.assertEqual(3.2, float(F.from_float(3.2)))
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000267
268 inf = 1e1000
269 nan = inf - inf
Mark Dickinson73726aa2012-11-15 20:58:40 +0000270 # bug 16469: error types should be consistent with float -> int
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000271 self.assertRaisesMessage(
Serhiy Storchaka0d250bc2015-12-29 22:34:23 +0200272 OverflowError, "cannot convert Infinity to integer ratio",
Christian Heimes68f5fbe2008-02-14 08:27:37 +0000273 F.from_float, inf)
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000274 self.assertRaisesMessage(
Serhiy Storchaka0d250bc2015-12-29 22:34:23 +0200275 OverflowError, "cannot convert Infinity to integer ratio",
Christian Heimes68f5fbe2008-02-14 08:27:37 +0000276 F.from_float, -inf)
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000277 self.assertRaisesMessage(
Serhiy Storchaka0d250bc2015-12-29 22:34:23 +0200278 ValueError, "cannot convert NaN to integer ratio",
Christian Heimes68f5fbe2008-02-14 08:27:37 +0000279 F.from_float, nan)
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000280
Christian Heimes587c2bf2008-01-19 16:21:02 +0000281 def testFromDecimal(self):
Georg Brandl2ee470f2008-07-16 12:55:28 +0000282 self.assertRaises(TypeError, F.from_decimal, 3+4j)
Ezio Melottib3aedd42010-11-20 19:04:17 +0000283 self.assertEqual(F(10, 1), F.from_decimal(10))
284 self.assertEqual(F(0), F.from_decimal(Decimal("-0")))
285 self.assertEqual(F(5, 10), F.from_decimal(Decimal("0.5")))
286 self.assertEqual(F(5, 1000), F.from_decimal(Decimal("5e-3")))
287 self.assertEqual(F(5000), F.from_decimal(Decimal("5e3")))
288 self.assertEqual(1 - F(1, 10**30),
289 F.from_decimal(Decimal("0." + "9" * 30)))
Christian Heimes587c2bf2008-01-19 16:21:02 +0000290
Mark Dickinson73726aa2012-11-15 20:58:40 +0000291 # bug 16469: error types should be consistent with decimal -> int
Christian Heimes587c2bf2008-01-19 16:21:02 +0000292 self.assertRaisesMessage(
Serhiy Storchaka0d250bc2015-12-29 22:34:23 +0200293 OverflowError, "cannot convert Infinity to integer ratio",
Christian Heimes68f5fbe2008-02-14 08:27:37 +0000294 F.from_decimal, Decimal("inf"))
Christian Heimes587c2bf2008-01-19 16:21:02 +0000295 self.assertRaisesMessage(
Serhiy Storchaka0d250bc2015-12-29 22:34:23 +0200296 OverflowError, "cannot convert Infinity to integer ratio",
Christian Heimes68f5fbe2008-02-14 08:27:37 +0000297 F.from_decimal, Decimal("-inf"))
Christian Heimes587c2bf2008-01-19 16:21:02 +0000298 self.assertRaisesMessage(
Serhiy Storchaka0d250bc2015-12-29 22:34:23 +0200299 ValueError, "cannot convert NaN to integer ratio",
Christian Heimes68f5fbe2008-02-14 08:27:37 +0000300 F.from_decimal, Decimal("nan"))
Christian Heimes587c2bf2008-01-19 16:21:02 +0000301 self.assertRaisesMessage(
Serhiy Storchaka0d250bc2015-12-29 22:34:23 +0200302 ValueError, "cannot convert NaN to integer ratio",
Christian Heimes68f5fbe2008-02-14 08:27:37 +0000303 F.from_decimal, Decimal("snan"))
Christian Heimes587c2bf2008-01-19 16:21:02 +0000304
Miss Islington (bot)5ba1cb02019-08-11 15:02:23 -0700305 def test_as_integer_ratio(self):
306 self.assertEqual(F(4, 6).as_integer_ratio(), (2, 3))
307 self.assertEqual(F(-4, 6).as_integer_ratio(), (-2, 3))
308 self.assertEqual(F(4, -6).as_integer_ratio(), (-2, 3))
309 self.assertEqual(F(0, 6).as_integer_ratio(), (0, 1))
310
Christian Heimes68f5fbe2008-02-14 08:27:37 +0000311 def testLimitDenominator(self):
312 rpi = F('3.1415926535897932')
313 self.assertEqual(rpi.limit_denominator(10000), F(355, 113))
314 self.assertEqual(-rpi.limit_denominator(10000), F(-355, 113))
315 self.assertEqual(rpi.limit_denominator(113), F(355, 113))
316 self.assertEqual(rpi.limit_denominator(112), F(333, 106))
317 self.assertEqual(F(201, 200).limit_denominator(100), F(1))
318 self.assertEqual(F(201, 200).limit_denominator(101), F(102, 101))
319 self.assertEqual(F(0).limit_denominator(10000), F(0))
Ezio Melotti682d3742012-02-29 14:05:53 +0200320 for i in (0, -1):
321 self.assertRaisesMessage(
322 ValueError, "max_denominator should be at least 1",
323 F(1).limit_denominator, i)
Christian Heimesbbffeb62008-01-24 09:42:52 +0000324
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000325 def testConversions(self):
Christian Heimes68f5fbe2008-02-14 08:27:37 +0000326 self.assertTypedEquals(-1, math.trunc(F(-11, 10)))
Ezio Melotti682d3742012-02-29 14:05:53 +0200327 self.assertTypedEquals(1, math.trunc(F(11, 10)))
Christian Heimes68f5fbe2008-02-14 08:27:37 +0000328 self.assertTypedEquals(-2, math.floor(F(-11, 10)))
329 self.assertTypedEquals(-1, math.ceil(F(-11, 10)))
330 self.assertTypedEquals(-1, math.ceil(F(-10, 10)))
331 self.assertTypedEquals(-1, int(F(-11, 10)))
332 self.assertTypedEquals(0, round(F(-1, 10)))
333 self.assertTypedEquals(0, round(F(-5, 10)))
334 self.assertTypedEquals(-2, round(F(-15, 10)))
335 self.assertTypedEquals(-1, round(F(-7, 10)))
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000336
Ezio Melottib3aedd42010-11-20 19:04:17 +0000337 self.assertEqual(False, bool(F(0, 1)))
338 self.assertEqual(True, bool(F(3, 2)))
Christian Heimes68f5fbe2008-02-14 08:27:37 +0000339 self.assertTypedEquals(0.1, float(F(1, 10)))
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000340
341 # Check that __float__ isn't implemented by converting the
342 # numerator and denominator to float before dividing.
343 self.assertRaises(OverflowError, float, int('2'*400+'7'))
Ezio Melottib3aedd42010-11-20 19:04:17 +0000344 self.assertAlmostEqual(2.0/3,
345 float(F(int('2'*400+'7'), int('3'*400+'1'))))
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000346
Christian Heimes68f5fbe2008-02-14 08:27:37 +0000347 self.assertTypedEquals(0.1+0j, complex(F(1,10)))
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000348
349 def testRound(self):
Christian Heimes68f5fbe2008-02-14 08:27:37 +0000350 self.assertTypedEquals(F(-200), round(F(-150), -2))
351 self.assertTypedEquals(F(-200), round(F(-250), -2))
352 self.assertTypedEquals(F(30), round(F(26), -1))
353 self.assertTypedEquals(F(-2, 10), round(F(-15, 100), 1))
354 self.assertTypedEquals(F(-2, 10), round(F(-25, 100), 1))
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000355
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000356 def testArithmetic(self):
Ezio Melottib3aedd42010-11-20 19:04:17 +0000357 self.assertEqual(F(1, 2), F(1, 10) + F(2, 5))
358 self.assertEqual(F(-3, 10), F(1, 10) - F(2, 5))
359 self.assertEqual(F(1, 25), F(1, 10) * F(2, 5))
360 self.assertEqual(F(1, 4), F(1, 10) / F(2, 5))
Christian Heimes68f5fbe2008-02-14 08:27:37 +0000361 self.assertTypedEquals(2, F(9, 10) // F(2, 5))
362 self.assertTypedEquals(10**23, F(10**23, 1) // F(1))
Stefan Behnel3a374e02019-01-02 13:22:06 +0100363 self.assertEqual(F(5, 6), F(7, 3) % F(3, 2))
Ezio Melottib3aedd42010-11-20 19:04:17 +0000364 self.assertEqual(F(2, 3), F(-7, 3) % F(3, 2))
Stefan Behnel3a374e02019-01-02 13:22:06 +0100365 self.assertEqual((F(1), F(5, 6)), divmod(F(7, 3), F(3, 2)))
366 self.assertEqual((F(-2), F(2, 3)), divmod(F(-7, 3), F(3, 2)))
Ezio Melottib3aedd42010-11-20 19:04:17 +0000367 self.assertEqual(F(8, 27), F(2, 3) ** F(3))
368 self.assertEqual(F(27, 8), F(2, 3) ** F(-3))
Christian Heimes68f5fbe2008-02-14 08:27:37 +0000369 self.assertTypedEquals(2.0, F(4) ** F(1, 2))
Ezio Melotti682d3742012-02-29 14:05:53 +0200370 self.assertEqual(F(1, 1), +F(1, 1))
Christian Heimes68f5fbe2008-02-14 08:27:37 +0000371 z = pow(F(-1), F(1, 2))
Ezio Melottib3aedd42010-11-20 19:04:17 +0000372 self.assertAlmostEqual(z.real, 0)
373 self.assertEqual(z.imag, 1)
Mark Dickinson84479652016-08-22 10:50:53 +0100374 # Regression test for #27539.
375 p = F(-1, 2) ** 0
376 self.assertEqual(p, F(1, 1))
377 self.assertEqual(p.numerator, 1)
378 self.assertEqual(p.denominator, 1)
379 p = F(-1, 2) ** -1
380 self.assertEqual(p, F(-2, 1))
381 self.assertEqual(p.numerator, -2)
382 self.assertEqual(p.denominator, 1)
383 p = F(-1, 2) ** -2
384 self.assertEqual(p, F(4, 1))
385 self.assertEqual(p.numerator, 4)
386 self.assertEqual(p.denominator, 1)
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000387
Stefan Behnel3a374e02019-01-02 13:22:06 +0100388 def testLargeArithmetic(self):
389 self.assertTypedEquals(
390 F(10101010100808080808080808101010101010000000000000000,
391 1010101010101010101010101011111111101010101010101010101010101),
392 F(10**35+1, 10**27+1) % F(10**27+1, 10**35-1)
393 )
394 self.assertTypedEquals(
395 F(7, 1901475900342344102245054808064),
396 F(-2**100, 3) % F(5, 2**100)
397 )
398 self.assertTypedTupleEquals(
399 (9999999999999999,
400 F(10101010100808080808080808101010101010000000000000000,
401 1010101010101010101010101011111111101010101010101010101010101)),
402 divmod(F(10**35+1, 10**27+1), F(10**27+1, 10**35-1))
403 )
404 self.assertTypedEquals(
405 -2 ** 200 // 15,
406 F(-2**100, 3) // F(5, 2**100)
407 )
408 self.assertTypedEquals(
409 1,
410 F(5, 2**100) // F(3, 2**100)
411 )
412 self.assertTypedEquals(
413 (1, F(2, 2**100)),
414 divmod(F(5, 2**100), F(3, 2**100))
415 )
416 self.assertTypedTupleEquals(
417 (-2 ** 200 // 15,
418 F(7, 1901475900342344102245054808064)),
419 divmod(F(-2**100, 3), F(5, 2**100))
420 )
421
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000422 def testMixedArithmetic(self):
Christian Heimes68f5fbe2008-02-14 08:27:37 +0000423 self.assertTypedEquals(F(11, 10), F(1, 10) + 1)
424 self.assertTypedEquals(1.1, F(1, 10) + 1.0)
425 self.assertTypedEquals(1.1 + 0j, F(1, 10) + (1.0 + 0j))
426 self.assertTypedEquals(F(11, 10), 1 + F(1, 10))
427 self.assertTypedEquals(1.1, 1.0 + F(1, 10))
428 self.assertTypedEquals(1.1 + 0j, (1.0 + 0j) + F(1, 10))
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000429
Christian Heimes68f5fbe2008-02-14 08:27:37 +0000430 self.assertTypedEquals(F(-9, 10), F(1, 10) - 1)
431 self.assertTypedEquals(-0.9, F(1, 10) - 1.0)
432 self.assertTypedEquals(-0.9 + 0j, F(1, 10) - (1.0 + 0j))
433 self.assertTypedEquals(F(9, 10), 1 - F(1, 10))
434 self.assertTypedEquals(0.9, 1.0 - F(1, 10))
435 self.assertTypedEquals(0.9 + 0j, (1.0 + 0j) - F(1, 10))
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000436
Christian Heimes68f5fbe2008-02-14 08:27:37 +0000437 self.assertTypedEquals(F(1, 10), F(1, 10) * 1)
438 self.assertTypedEquals(0.1, F(1, 10) * 1.0)
439 self.assertTypedEquals(0.1 + 0j, F(1, 10) * (1.0 + 0j))
440 self.assertTypedEquals(F(1, 10), 1 * F(1, 10))
441 self.assertTypedEquals(0.1, 1.0 * F(1, 10))
442 self.assertTypedEquals(0.1 + 0j, (1.0 + 0j) * F(1, 10))
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000443
Christian Heimes68f5fbe2008-02-14 08:27:37 +0000444 self.assertTypedEquals(F(1, 10), F(1, 10) / 1)
445 self.assertTypedEquals(0.1, F(1, 10) / 1.0)
446 self.assertTypedEquals(0.1 + 0j, F(1, 10) / (1.0 + 0j))
447 self.assertTypedEquals(F(10, 1), 1 / F(1, 10))
448 self.assertTypedEquals(10.0, 1.0 / F(1, 10))
449 self.assertTypedEquals(10.0 + 0j, (1.0 + 0j) / F(1, 10))
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000450
Christian Heimes68f5fbe2008-02-14 08:27:37 +0000451 self.assertTypedEquals(0, F(1, 10) // 1)
Elias Zamaria393f1ff2018-08-26 23:59:28 -0700452 self.assertTypedEquals(0.0, F(1, 10) // 1.0)
Christian Heimes68f5fbe2008-02-14 08:27:37 +0000453 self.assertTypedEquals(10, 1 // F(1, 10))
454 self.assertTypedEquals(10**23, 10**22 // F(1, 10))
Elias Zamaria393f1ff2018-08-26 23:59:28 -0700455 self.assertTypedEquals(1.0 // 0.1, 1.0 // F(1, 10))
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000456
Christian Heimes68f5fbe2008-02-14 08:27:37 +0000457 self.assertTypedEquals(F(1, 10), F(1, 10) % 1)
458 self.assertTypedEquals(0.1, F(1, 10) % 1.0)
459 self.assertTypedEquals(F(0, 1), 1 % F(1, 10))
Elias Zamaria393f1ff2018-08-26 23:59:28 -0700460 self.assertTypedEquals(1.0 % 0.1, 1.0 % F(1, 10))
461 self.assertTypedEquals(0.1, F(1, 10) % float('inf'))
462 self.assertTypedEquals(float('-inf'), F(1, 10) % float('-inf'))
463 self.assertTypedEquals(float('inf'), F(-1, 10) % float('inf'))
464 self.assertTypedEquals(-0.1, F(-1, 10) % float('-inf'))
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000465
Stefan Behnel3a374e02019-01-02 13:22:06 +0100466 self.assertTypedTupleEquals((0, F(1, 10)), divmod(F(1, 10), 1))
467 self.assertTypedTupleEquals(divmod(0.1, 1.0), divmod(F(1, 10), 1.0))
468 self.assertTypedTupleEquals((10, F(0)), divmod(1, F(1, 10)))
469 self.assertTypedTupleEquals(divmod(1.0, 0.1), divmod(1.0, F(1, 10)))
470 self.assertTypedTupleEquals(divmod(0.1, float('inf')), divmod(F(1, 10), float('inf')))
471 self.assertTypedTupleEquals(divmod(0.1, float('-inf')), divmod(F(1, 10), float('-inf')))
472 self.assertTypedTupleEquals(divmod(-0.1, float('inf')), divmod(F(-1, 10), float('inf')))
473 self.assertTypedTupleEquals(divmod(-0.1, float('-inf')), divmod(F(-1, 10), float('-inf')))
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000474
475 # ** has more interesting conversion rules.
Christian Heimes68f5fbe2008-02-14 08:27:37 +0000476 self.assertTypedEquals(F(100, 1), F(1, 10) ** -2)
477 self.assertTypedEquals(F(100, 1), F(10, 1) ** 2)
478 self.assertTypedEquals(0.1, F(1, 10) ** 1.0)
479 self.assertTypedEquals(0.1 + 0j, F(1, 10) ** (1.0 + 0j))
480 self.assertTypedEquals(4 , 2 ** F(2, 1))
481 z = pow(-1, F(1, 2))
Ezio Melottib3aedd42010-11-20 19:04:17 +0000482 self.assertAlmostEqual(0, z.real)
483 self.assertEqual(1, z.imag)
Christian Heimes68f5fbe2008-02-14 08:27:37 +0000484 self.assertTypedEquals(F(1, 4) , 2 ** F(-2, 1))
485 self.assertTypedEquals(2.0 , 4 ** F(1, 2))
486 self.assertTypedEquals(0.25, 2.0 ** F(-2, 1))
487 self.assertTypedEquals(1.0 + 0j, (1.0 + 0j) ** F(1, 10))
Mark Dickinson3c286e22014-04-05 09:29:00 +0100488 self.assertRaises(ZeroDivisionError, operator.pow,
489 F(0, 1), -2)
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000490
491 def testMixingWithDecimal(self):
Mark Dickinson08ade6f2010-06-11 10:44:52 +0000492 # Decimal refuses mixed arithmetic (but not mixed comparisons)
Stefan Krah1919b7e2012-03-21 18:25:23 +0100493 self.assertRaises(TypeError, operator.add,
494 F(3,11), Decimal('3.1415926'))
495 self.assertRaises(TypeError, operator.add,
496 Decimal('3.1415926'), F(3,11))
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000497
498 def testComparisons(self):
Christian Heimes68f5fbe2008-02-14 08:27:37 +0000499 self.assertTrue(F(1, 2) < F(2, 3))
500 self.assertFalse(F(1, 2) < F(1, 2))
501 self.assertTrue(F(1, 2) <= F(2, 3))
502 self.assertTrue(F(1, 2) <= F(1, 2))
503 self.assertFalse(F(2, 3) <= F(1, 2))
504 self.assertTrue(F(1, 2) == F(1, 2))
505 self.assertFalse(F(1, 2) == F(1, 3))
506 self.assertFalse(F(1, 2) != F(1, 2))
507 self.assertTrue(F(1, 2) != F(1, 3))
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000508
Mark Dickinson85424c92009-07-18 14:41:42 +0000509 def testComparisonsDummyRational(self):
510 self.assertTrue(F(1, 2) == DummyRational(1, 2))
511 self.assertTrue(DummyRational(1, 2) == F(1, 2))
512 self.assertFalse(F(1, 2) == DummyRational(3, 4))
513 self.assertFalse(DummyRational(3, 4) == F(1, 2))
514
515 self.assertTrue(F(1, 2) < DummyRational(3, 4))
516 self.assertFalse(F(1, 2) < DummyRational(1, 2))
517 self.assertFalse(F(1, 2) < DummyRational(1, 7))
518 self.assertFalse(F(1, 2) > DummyRational(3, 4))
519 self.assertFalse(F(1, 2) > DummyRational(1, 2))
520 self.assertTrue(F(1, 2) > DummyRational(1, 7))
521 self.assertTrue(F(1, 2) <= DummyRational(3, 4))
522 self.assertTrue(F(1, 2) <= DummyRational(1, 2))
523 self.assertFalse(F(1, 2) <= DummyRational(1, 7))
524 self.assertFalse(F(1, 2) >= DummyRational(3, 4))
525 self.assertTrue(F(1, 2) >= DummyRational(1, 2))
526 self.assertTrue(F(1, 2) >= DummyRational(1, 7))
527
528 self.assertTrue(DummyRational(1, 2) < F(3, 4))
529 self.assertFalse(DummyRational(1, 2) < F(1, 2))
530 self.assertFalse(DummyRational(1, 2) < F(1, 7))
531 self.assertFalse(DummyRational(1, 2) > F(3, 4))
532 self.assertFalse(DummyRational(1, 2) > F(1, 2))
533 self.assertTrue(DummyRational(1, 2) > F(1, 7))
534 self.assertTrue(DummyRational(1, 2) <= F(3, 4))
535 self.assertTrue(DummyRational(1, 2) <= F(1, 2))
536 self.assertFalse(DummyRational(1, 2) <= F(1, 7))
537 self.assertFalse(DummyRational(1, 2) >= F(3, 4))
538 self.assertTrue(DummyRational(1, 2) >= F(1, 2))
539 self.assertTrue(DummyRational(1, 2) >= F(1, 7))
540
541 def testComparisonsDummyFloat(self):
542 x = DummyFloat(1./3.)
543 y = F(1, 3)
544 self.assertTrue(x != y)
545 self.assertTrue(x < y or x > y)
546 self.assertFalse(x == y)
547 self.assertFalse(x <= y and x >= y)
548 self.assertTrue(y != x)
549 self.assertTrue(y < x or y > x)
550 self.assertFalse(y == x)
551 self.assertFalse(y <= x and y >= x)
552
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000553 def testMixedLess(self):
Christian Heimes68f5fbe2008-02-14 08:27:37 +0000554 self.assertTrue(2 < F(5, 2))
555 self.assertFalse(2 < F(4, 2))
556 self.assertTrue(F(5, 2) < 3)
557 self.assertFalse(F(4, 2) < 2)
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000558
Christian Heimes68f5fbe2008-02-14 08:27:37 +0000559 self.assertTrue(F(1, 2) < 0.6)
560 self.assertFalse(F(1, 2) < 0.4)
561 self.assertTrue(0.4 < F(1, 2))
562 self.assertFalse(0.5 < F(1, 2))
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000563
Mark Dickinson85424c92009-07-18 14:41:42 +0000564 self.assertFalse(float('inf') < F(1, 2))
565 self.assertTrue(float('-inf') < F(0, 10))
566 self.assertFalse(float('nan') < F(-3, 7))
567 self.assertTrue(F(1, 2) < float('inf'))
568 self.assertFalse(F(17, 12) < float('-inf'))
569 self.assertFalse(F(144, -89) < float('nan'))
570
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000571 def testMixedLessEqual(self):
Christian Heimes68f5fbe2008-02-14 08:27:37 +0000572 self.assertTrue(0.5 <= F(1, 2))
573 self.assertFalse(0.6 <= F(1, 2))
574 self.assertTrue(F(1, 2) <= 0.5)
575 self.assertFalse(F(1, 2) <= 0.4)
576 self.assertTrue(2 <= F(4, 2))
577 self.assertFalse(2 <= F(3, 2))
578 self.assertTrue(F(4, 2) <= 2)
579 self.assertFalse(F(5, 2) <= 2)
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000580
Mark Dickinson85424c92009-07-18 14:41:42 +0000581 self.assertFalse(float('inf') <= F(1, 2))
582 self.assertTrue(float('-inf') <= F(0, 10))
583 self.assertFalse(float('nan') <= F(-3, 7))
584 self.assertTrue(F(1, 2) <= float('inf'))
585 self.assertFalse(F(17, 12) <= float('-inf'))
586 self.assertFalse(F(144, -89) <= float('nan'))
587
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000588 def testBigFloatComparisons(self):
589 # Because 10**23 can't be represented exactly as a float:
Christian Heimes68f5fbe2008-02-14 08:27:37 +0000590 self.assertFalse(F(10**23) == float(10**23))
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000591 # The first test demonstrates why these are important.
Christian Heimes68f5fbe2008-02-14 08:27:37 +0000592 self.assertFalse(1e23 < float(F(math.trunc(1e23) + 1)))
593 self.assertTrue(1e23 < F(math.trunc(1e23) + 1))
594 self.assertFalse(1e23 <= F(math.trunc(1e23) - 1))
595 self.assertTrue(1e23 > F(math.trunc(1e23) - 1))
596 self.assertFalse(1e23 >= F(math.trunc(1e23) + 1))
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000597
598 def testBigComplexComparisons(self):
Christian Heimes68f5fbe2008-02-14 08:27:37 +0000599 self.assertFalse(F(10**23) == complex(10**23))
Mark Dickinson327f02c2010-03-27 11:11:13 +0000600 self.assertRaises(TypeError, operator.gt, F(10**23), complex(10**23))
601 self.assertRaises(TypeError, operator.le, F(10**23), complex(10**23))
602
603 x = F(3, 8)
604 z = complex(0.375, 0.0)
605 w = complex(0.375, 0.2)
606 self.assertTrue(x == z)
607 self.assertFalse(x != z)
608 self.assertFalse(x == w)
609 self.assertTrue(x != w)
610 for op in operator.lt, operator.le, operator.gt, operator.ge:
611 self.assertRaises(TypeError, op, x, z)
612 self.assertRaises(TypeError, op, z, x)
613 self.assertRaises(TypeError, op, x, w)
614 self.assertRaises(TypeError, op, w, x)
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000615
616 def testMixedEqual(self):
Christian Heimes68f5fbe2008-02-14 08:27:37 +0000617 self.assertTrue(0.5 == F(1, 2))
618 self.assertFalse(0.6 == F(1, 2))
619 self.assertTrue(F(1, 2) == 0.5)
620 self.assertFalse(F(1, 2) == 0.4)
621 self.assertTrue(2 == F(4, 2))
622 self.assertFalse(2 == F(3, 2))
623 self.assertTrue(F(4, 2) == 2)
624 self.assertFalse(F(5, 2) == 2)
Mark Dickinson85424c92009-07-18 14:41:42 +0000625 self.assertFalse(F(5, 2) == float('nan'))
626 self.assertFalse(float('nan') == F(3, 7))
627 self.assertFalse(F(5, 2) == float('inf'))
628 self.assertFalse(float('-inf') == F(2, 5))
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000629
630 def testStringification(self):
Ezio Melottib3aedd42010-11-20 19:04:17 +0000631 self.assertEqual("Fraction(7, 3)", repr(F(7, 3)))
632 self.assertEqual("Fraction(6283185307, 2000000000)",
633 repr(F('3.1415926535')))
634 self.assertEqual("Fraction(-1, 100000000000000000000)",
635 repr(F(1, -10**20)))
636 self.assertEqual("7/3", str(F(7, 3)))
637 self.assertEqual("7", str(F(7, 1)))
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000638
639 def testHash(self):
Ezio Melotti682d3742012-02-29 14:05:53 +0200640 hmod = sys.hash_info.modulus
641 hinf = sys.hash_info.inf
Ezio Melottib3aedd42010-11-20 19:04:17 +0000642 self.assertEqual(hash(2.5), hash(F(5, 2)))
643 self.assertEqual(hash(10**50), hash(F(10**50)))
644 self.assertNotEqual(hash(float(10**23)), hash(F(10**23)))
Ezio Melotti682d3742012-02-29 14:05:53 +0200645 self.assertEqual(hinf, hash(F(1, hmod)))
Mark Dickinsonfec66202010-11-13 10:27:38 +0000646 # Check that __hash__ produces the same value as hash(), for
647 # consistency with int and Decimal. (See issue #10356.)
Ezio Melottib3aedd42010-11-20 19:04:17 +0000648 self.assertEqual(hash(F(-1)), F(-1).__hash__())
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000649
650 def testApproximatePi(self):
651 # Algorithm borrowed from
652 # http://docs.python.org/lib/decimal-recipes.html
Christian Heimes68f5fbe2008-02-14 08:27:37 +0000653 three = F(3)
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000654 lasts, t, s, n, na, d, da = 0, three, 3, 1, 0, 0, 24
Christian Heimes68f5fbe2008-02-14 08:27:37 +0000655 while abs(s - lasts) > F(1, 10**9):
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000656 lasts = s
657 n, na = n+na, na+8
658 d, da = d+da, da+32
659 t = (t * n) / d
660 s += t
Ezio Melottib3aedd42010-11-20 19:04:17 +0000661 self.assertAlmostEqual(math.pi, s)
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000662
663 def testApproximateCos1(self):
664 # Algorithm borrowed from
665 # http://docs.python.org/lib/decimal-recipes.html
Christian Heimes68f5fbe2008-02-14 08:27:37 +0000666 x = F(1)
667 i, lasts, s, fact, num, sign = 0, 0, F(1), 1, 1, 1
668 while abs(s - lasts) > F(1, 10**9):
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000669 lasts = s
670 i += 2
671 fact *= i * (i-1)
672 num *= x * x
673 sign *= -1
674 s += num / fact * sign
Ezio Melottib3aedd42010-11-20 19:04:17 +0000675 self.assertAlmostEqual(math.cos(1), s)
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000676
Christian Heimes969fe572008-01-25 11:23:10 +0000677 def test_copy_deepcopy_pickle(self):
Christian Heimes68f5fbe2008-02-14 08:27:37 +0000678 r = F(13, 7)
Ezio Melotti682d3742012-02-29 14:05:53 +0200679 dr = DummyFraction(13, 7)
Christian Heimes969fe572008-01-25 11:23:10 +0000680 self.assertEqual(r, loads(dumps(r)))
681 self.assertEqual(id(r), id(copy(r)))
682 self.assertEqual(id(r), id(deepcopy(r)))
Ezio Melotti682d3742012-02-29 14:05:53 +0200683 self.assertNotEqual(id(dr), id(copy(dr)))
684 self.assertNotEqual(id(dr), id(deepcopy(dr)))
685 self.assertTypedEquals(dr, copy(dr))
686 self.assertTypedEquals(dr, deepcopy(dr))
Christian Heimes969fe572008-01-25 11:23:10 +0000687
Mark Dickinsonc28ad272009-02-12 17:58:36 +0000688 def test_slots(self):
689 # Issue 4998
690 r = F(13, 7)
691 self.assertRaises(AttributeError, setattr, r, 'a', 10)
692
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000693if __name__ == '__main__':
Zachary Ware38c707e2015-04-13 15:00:43 -0500694 unittest.main()