blob: 2779162200514919b64c19dcee677c8f891dda97 [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
Christian Heimes68f5fbe2008-02-14 08:27:37 +0000305 def testLimitDenominator(self):
306 rpi = F('3.1415926535897932')
307 self.assertEqual(rpi.limit_denominator(10000), F(355, 113))
308 self.assertEqual(-rpi.limit_denominator(10000), F(-355, 113))
309 self.assertEqual(rpi.limit_denominator(113), F(355, 113))
310 self.assertEqual(rpi.limit_denominator(112), F(333, 106))
311 self.assertEqual(F(201, 200).limit_denominator(100), F(1))
312 self.assertEqual(F(201, 200).limit_denominator(101), F(102, 101))
313 self.assertEqual(F(0).limit_denominator(10000), F(0))
Ezio Melotti682d3742012-02-29 14:05:53 +0200314 for i in (0, -1):
315 self.assertRaisesMessage(
316 ValueError, "max_denominator should be at least 1",
317 F(1).limit_denominator, i)
Christian Heimesbbffeb62008-01-24 09:42:52 +0000318
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000319 def testConversions(self):
Christian Heimes68f5fbe2008-02-14 08:27:37 +0000320 self.assertTypedEquals(-1, math.trunc(F(-11, 10)))
Ezio Melotti682d3742012-02-29 14:05:53 +0200321 self.assertTypedEquals(1, math.trunc(F(11, 10)))
Christian Heimes68f5fbe2008-02-14 08:27:37 +0000322 self.assertTypedEquals(-2, math.floor(F(-11, 10)))
323 self.assertTypedEquals(-1, math.ceil(F(-11, 10)))
324 self.assertTypedEquals(-1, math.ceil(F(-10, 10)))
325 self.assertTypedEquals(-1, int(F(-11, 10)))
326 self.assertTypedEquals(0, round(F(-1, 10)))
327 self.assertTypedEquals(0, round(F(-5, 10)))
328 self.assertTypedEquals(-2, round(F(-15, 10)))
329 self.assertTypedEquals(-1, round(F(-7, 10)))
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000330
Ezio Melottib3aedd42010-11-20 19:04:17 +0000331 self.assertEqual(False, bool(F(0, 1)))
332 self.assertEqual(True, bool(F(3, 2)))
Christian Heimes68f5fbe2008-02-14 08:27:37 +0000333 self.assertTypedEquals(0.1, float(F(1, 10)))
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000334
335 # Check that __float__ isn't implemented by converting the
336 # numerator and denominator to float before dividing.
337 self.assertRaises(OverflowError, float, int('2'*400+'7'))
Ezio Melottib3aedd42010-11-20 19:04:17 +0000338 self.assertAlmostEqual(2.0/3,
339 float(F(int('2'*400+'7'), int('3'*400+'1'))))
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000340
Christian Heimes68f5fbe2008-02-14 08:27:37 +0000341 self.assertTypedEquals(0.1+0j, complex(F(1,10)))
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000342
343 def testRound(self):
Christian Heimes68f5fbe2008-02-14 08:27:37 +0000344 self.assertTypedEquals(F(-200), round(F(-150), -2))
345 self.assertTypedEquals(F(-200), round(F(-250), -2))
346 self.assertTypedEquals(F(30), round(F(26), -1))
347 self.assertTypedEquals(F(-2, 10), round(F(-15, 100), 1))
348 self.assertTypedEquals(F(-2, 10), round(F(-25, 100), 1))
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000349
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000350 def testArithmetic(self):
Ezio Melottib3aedd42010-11-20 19:04:17 +0000351 self.assertEqual(F(1, 2), F(1, 10) + F(2, 5))
352 self.assertEqual(F(-3, 10), F(1, 10) - F(2, 5))
353 self.assertEqual(F(1, 25), F(1, 10) * F(2, 5))
354 self.assertEqual(F(1, 4), F(1, 10) / F(2, 5))
Christian Heimes68f5fbe2008-02-14 08:27:37 +0000355 self.assertTypedEquals(2, F(9, 10) // F(2, 5))
356 self.assertTypedEquals(10**23, F(10**23, 1) // F(1))
Stefan Behnel3a374e02019-01-02 13:22:06 +0100357 self.assertEqual(F(5, 6), F(7, 3) % F(3, 2))
Ezio Melottib3aedd42010-11-20 19:04:17 +0000358 self.assertEqual(F(2, 3), F(-7, 3) % F(3, 2))
Stefan Behnel3a374e02019-01-02 13:22:06 +0100359 self.assertEqual((F(1), F(5, 6)), divmod(F(7, 3), F(3, 2)))
360 self.assertEqual((F(-2), F(2, 3)), divmod(F(-7, 3), F(3, 2)))
Ezio Melottib3aedd42010-11-20 19:04:17 +0000361 self.assertEqual(F(8, 27), F(2, 3) ** F(3))
362 self.assertEqual(F(27, 8), F(2, 3) ** F(-3))
Christian Heimes68f5fbe2008-02-14 08:27:37 +0000363 self.assertTypedEquals(2.0, F(4) ** F(1, 2))
Ezio Melotti682d3742012-02-29 14:05:53 +0200364 self.assertEqual(F(1, 1), +F(1, 1))
Christian Heimes68f5fbe2008-02-14 08:27:37 +0000365 z = pow(F(-1), F(1, 2))
Ezio Melottib3aedd42010-11-20 19:04:17 +0000366 self.assertAlmostEqual(z.real, 0)
367 self.assertEqual(z.imag, 1)
Mark Dickinson84479652016-08-22 10:50:53 +0100368 # Regression test for #27539.
369 p = F(-1, 2) ** 0
370 self.assertEqual(p, F(1, 1))
371 self.assertEqual(p.numerator, 1)
372 self.assertEqual(p.denominator, 1)
373 p = F(-1, 2) ** -1
374 self.assertEqual(p, F(-2, 1))
375 self.assertEqual(p.numerator, -2)
376 self.assertEqual(p.denominator, 1)
377 p = F(-1, 2) ** -2
378 self.assertEqual(p, F(4, 1))
379 self.assertEqual(p.numerator, 4)
380 self.assertEqual(p.denominator, 1)
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000381
Stefan Behnel3a374e02019-01-02 13:22:06 +0100382 def testLargeArithmetic(self):
383 self.assertTypedEquals(
384 F(10101010100808080808080808101010101010000000000000000,
385 1010101010101010101010101011111111101010101010101010101010101),
386 F(10**35+1, 10**27+1) % F(10**27+1, 10**35-1)
387 )
388 self.assertTypedEquals(
389 F(7, 1901475900342344102245054808064),
390 F(-2**100, 3) % F(5, 2**100)
391 )
392 self.assertTypedTupleEquals(
393 (9999999999999999,
394 F(10101010100808080808080808101010101010000000000000000,
395 1010101010101010101010101011111111101010101010101010101010101)),
396 divmod(F(10**35+1, 10**27+1), F(10**27+1, 10**35-1))
397 )
398 self.assertTypedEquals(
399 -2 ** 200 // 15,
400 F(-2**100, 3) // F(5, 2**100)
401 )
402 self.assertTypedEquals(
403 1,
404 F(5, 2**100) // F(3, 2**100)
405 )
406 self.assertTypedEquals(
407 (1, F(2, 2**100)),
408 divmod(F(5, 2**100), F(3, 2**100))
409 )
410 self.assertTypedTupleEquals(
411 (-2 ** 200 // 15,
412 F(7, 1901475900342344102245054808064)),
413 divmod(F(-2**100, 3), F(5, 2**100))
414 )
415
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000416 def testMixedArithmetic(self):
Christian Heimes68f5fbe2008-02-14 08:27:37 +0000417 self.assertTypedEquals(F(11, 10), F(1, 10) + 1)
418 self.assertTypedEquals(1.1, F(1, 10) + 1.0)
419 self.assertTypedEquals(1.1 + 0j, F(1, 10) + (1.0 + 0j))
420 self.assertTypedEquals(F(11, 10), 1 + F(1, 10))
421 self.assertTypedEquals(1.1, 1.0 + F(1, 10))
422 self.assertTypedEquals(1.1 + 0j, (1.0 + 0j) + F(1, 10))
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000423
Christian Heimes68f5fbe2008-02-14 08:27:37 +0000424 self.assertTypedEquals(F(-9, 10), F(1, 10) - 1)
425 self.assertTypedEquals(-0.9, F(1, 10) - 1.0)
426 self.assertTypedEquals(-0.9 + 0j, F(1, 10) - (1.0 + 0j))
427 self.assertTypedEquals(F(9, 10), 1 - F(1, 10))
428 self.assertTypedEquals(0.9, 1.0 - F(1, 10))
429 self.assertTypedEquals(0.9 + 0j, (1.0 + 0j) - F(1, 10))
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000430
Christian Heimes68f5fbe2008-02-14 08:27:37 +0000431 self.assertTypedEquals(F(1, 10), F(1, 10) * 1)
432 self.assertTypedEquals(0.1, F(1, 10) * 1.0)
433 self.assertTypedEquals(0.1 + 0j, F(1, 10) * (1.0 + 0j))
434 self.assertTypedEquals(F(1, 10), 1 * F(1, 10))
435 self.assertTypedEquals(0.1, 1.0 * F(1, 10))
436 self.assertTypedEquals(0.1 + 0j, (1.0 + 0j) * F(1, 10))
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000437
Christian Heimes68f5fbe2008-02-14 08:27:37 +0000438 self.assertTypedEquals(F(1, 10), F(1, 10) / 1)
439 self.assertTypedEquals(0.1, F(1, 10) / 1.0)
440 self.assertTypedEquals(0.1 + 0j, F(1, 10) / (1.0 + 0j))
441 self.assertTypedEquals(F(10, 1), 1 / F(1, 10))
442 self.assertTypedEquals(10.0, 1.0 / F(1, 10))
443 self.assertTypedEquals(10.0 + 0j, (1.0 + 0j) / F(1, 10))
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000444
Christian Heimes68f5fbe2008-02-14 08:27:37 +0000445 self.assertTypedEquals(0, F(1, 10) // 1)
Elias Zamaria393f1ff2018-08-26 23:59:28 -0700446 self.assertTypedEquals(0.0, F(1, 10) // 1.0)
Christian Heimes68f5fbe2008-02-14 08:27:37 +0000447 self.assertTypedEquals(10, 1 // F(1, 10))
448 self.assertTypedEquals(10**23, 10**22 // F(1, 10))
Elias Zamaria393f1ff2018-08-26 23:59:28 -0700449 self.assertTypedEquals(1.0 // 0.1, 1.0 // F(1, 10))
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000450
Christian Heimes68f5fbe2008-02-14 08:27:37 +0000451 self.assertTypedEquals(F(1, 10), F(1, 10) % 1)
452 self.assertTypedEquals(0.1, F(1, 10) % 1.0)
453 self.assertTypedEquals(F(0, 1), 1 % F(1, 10))
Elias Zamaria393f1ff2018-08-26 23:59:28 -0700454 self.assertTypedEquals(1.0 % 0.1, 1.0 % F(1, 10))
455 self.assertTypedEquals(0.1, F(1, 10) % float('inf'))
456 self.assertTypedEquals(float('-inf'), F(1, 10) % float('-inf'))
457 self.assertTypedEquals(float('inf'), F(-1, 10) % float('inf'))
458 self.assertTypedEquals(-0.1, F(-1, 10) % float('-inf'))
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000459
Stefan Behnel3a374e02019-01-02 13:22:06 +0100460 self.assertTypedTupleEquals((0, F(1, 10)), divmod(F(1, 10), 1))
461 self.assertTypedTupleEquals(divmod(0.1, 1.0), divmod(F(1, 10), 1.0))
462 self.assertTypedTupleEquals((10, F(0)), divmod(1, F(1, 10)))
463 self.assertTypedTupleEquals(divmod(1.0, 0.1), divmod(1.0, F(1, 10)))
464 self.assertTypedTupleEquals(divmod(0.1, float('inf')), divmod(F(1, 10), float('inf')))
465 self.assertTypedTupleEquals(divmod(0.1, float('-inf')), divmod(F(1, 10), float('-inf')))
466 self.assertTypedTupleEquals(divmod(-0.1, float('inf')), divmod(F(-1, 10), float('inf')))
467 self.assertTypedTupleEquals(divmod(-0.1, float('-inf')), divmod(F(-1, 10), float('-inf')))
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000468
469 # ** has more interesting conversion rules.
Christian Heimes68f5fbe2008-02-14 08:27:37 +0000470 self.assertTypedEquals(F(100, 1), F(1, 10) ** -2)
471 self.assertTypedEquals(F(100, 1), F(10, 1) ** 2)
472 self.assertTypedEquals(0.1, F(1, 10) ** 1.0)
473 self.assertTypedEquals(0.1 + 0j, F(1, 10) ** (1.0 + 0j))
474 self.assertTypedEquals(4 , 2 ** F(2, 1))
475 z = pow(-1, F(1, 2))
Ezio Melottib3aedd42010-11-20 19:04:17 +0000476 self.assertAlmostEqual(0, z.real)
477 self.assertEqual(1, z.imag)
Christian Heimes68f5fbe2008-02-14 08:27:37 +0000478 self.assertTypedEquals(F(1, 4) , 2 ** F(-2, 1))
479 self.assertTypedEquals(2.0 , 4 ** F(1, 2))
480 self.assertTypedEquals(0.25, 2.0 ** F(-2, 1))
481 self.assertTypedEquals(1.0 + 0j, (1.0 + 0j) ** F(1, 10))
Mark Dickinson3c286e22014-04-05 09:29:00 +0100482 self.assertRaises(ZeroDivisionError, operator.pow,
483 F(0, 1), -2)
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000484
485 def testMixingWithDecimal(self):
Mark Dickinson08ade6f2010-06-11 10:44:52 +0000486 # Decimal refuses mixed arithmetic (but not mixed comparisons)
Stefan Krah1919b7e2012-03-21 18:25:23 +0100487 self.assertRaises(TypeError, operator.add,
488 F(3,11), Decimal('3.1415926'))
489 self.assertRaises(TypeError, operator.add,
490 Decimal('3.1415926'), F(3,11))
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000491
492 def testComparisons(self):
Christian Heimes68f5fbe2008-02-14 08:27:37 +0000493 self.assertTrue(F(1, 2) < F(2, 3))
494 self.assertFalse(F(1, 2) < F(1, 2))
495 self.assertTrue(F(1, 2) <= F(2, 3))
496 self.assertTrue(F(1, 2) <= F(1, 2))
497 self.assertFalse(F(2, 3) <= F(1, 2))
498 self.assertTrue(F(1, 2) == F(1, 2))
499 self.assertFalse(F(1, 2) == F(1, 3))
500 self.assertFalse(F(1, 2) != F(1, 2))
501 self.assertTrue(F(1, 2) != F(1, 3))
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000502
Mark Dickinson85424c92009-07-18 14:41:42 +0000503 def testComparisonsDummyRational(self):
504 self.assertTrue(F(1, 2) == DummyRational(1, 2))
505 self.assertTrue(DummyRational(1, 2) == F(1, 2))
506 self.assertFalse(F(1, 2) == DummyRational(3, 4))
507 self.assertFalse(DummyRational(3, 4) == F(1, 2))
508
509 self.assertTrue(F(1, 2) < DummyRational(3, 4))
510 self.assertFalse(F(1, 2) < DummyRational(1, 2))
511 self.assertFalse(F(1, 2) < DummyRational(1, 7))
512 self.assertFalse(F(1, 2) > DummyRational(3, 4))
513 self.assertFalse(F(1, 2) > DummyRational(1, 2))
514 self.assertTrue(F(1, 2) > DummyRational(1, 7))
515 self.assertTrue(F(1, 2) <= DummyRational(3, 4))
516 self.assertTrue(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.assertTrue(F(1, 2) >= DummyRational(1, 2))
520 self.assertTrue(F(1, 2) >= DummyRational(1, 7))
521
522 self.assertTrue(DummyRational(1, 2) < F(3, 4))
523 self.assertFalse(DummyRational(1, 2) < F(1, 2))
524 self.assertFalse(DummyRational(1, 2) < F(1, 7))
525 self.assertFalse(DummyRational(1, 2) > F(3, 4))
526 self.assertFalse(DummyRational(1, 2) > F(1, 2))
527 self.assertTrue(DummyRational(1, 2) > F(1, 7))
528 self.assertTrue(DummyRational(1, 2) <= F(3, 4))
529 self.assertTrue(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.assertTrue(DummyRational(1, 2) >= F(1, 2))
533 self.assertTrue(DummyRational(1, 2) >= F(1, 7))
534
535 def testComparisonsDummyFloat(self):
536 x = DummyFloat(1./3.)
537 y = F(1, 3)
538 self.assertTrue(x != y)
539 self.assertTrue(x < y or x > y)
540 self.assertFalse(x == y)
541 self.assertFalse(x <= y and x >= y)
542 self.assertTrue(y != x)
543 self.assertTrue(y < x or y > x)
544 self.assertFalse(y == x)
545 self.assertFalse(y <= x and y >= x)
546
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000547 def testMixedLess(self):
Christian Heimes68f5fbe2008-02-14 08:27:37 +0000548 self.assertTrue(2 < F(5, 2))
549 self.assertFalse(2 < F(4, 2))
550 self.assertTrue(F(5, 2) < 3)
551 self.assertFalse(F(4, 2) < 2)
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000552
Christian Heimes68f5fbe2008-02-14 08:27:37 +0000553 self.assertTrue(F(1, 2) < 0.6)
554 self.assertFalse(F(1, 2) < 0.4)
555 self.assertTrue(0.4 < F(1, 2))
556 self.assertFalse(0.5 < F(1, 2))
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000557
Mark Dickinson85424c92009-07-18 14:41:42 +0000558 self.assertFalse(float('inf') < F(1, 2))
559 self.assertTrue(float('-inf') < F(0, 10))
560 self.assertFalse(float('nan') < F(-3, 7))
561 self.assertTrue(F(1, 2) < float('inf'))
562 self.assertFalse(F(17, 12) < float('-inf'))
563 self.assertFalse(F(144, -89) < float('nan'))
564
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000565 def testMixedLessEqual(self):
Christian Heimes68f5fbe2008-02-14 08:27:37 +0000566 self.assertTrue(0.5 <= F(1, 2))
567 self.assertFalse(0.6 <= F(1, 2))
568 self.assertTrue(F(1, 2) <= 0.5)
569 self.assertFalse(F(1, 2) <= 0.4)
570 self.assertTrue(2 <= F(4, 2))
571 self.assertFalse(2 <= F(3, 2))
572 self.assertTrue(F(4, 2) <= 2)
573 self.assertFalse(F(5, 2) <= 2)
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000574
Mark Dickinson85424c92009-07-18 14:41:42 +0000575 self.assertFalse(float('inf') <= F(1, 2))
576 self.assertTrue(float('-inf') <= F(0, 10))
577 self.assertFalse(float('nan') <= F(-3, 7))
578 self.assertTrue(F(1, 2) <= float('inf'))
579 self.assertFalse(F(17, 12) <= float('-inf'))
580 self.assertFalse(F(144, -89) <= float('nan'))
581
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000582 def testBigFloatComparisons(self):
583 # Because 10**23 can't be represented exactly as a float:
Christian Heimes68f5fbe2008-02-14 08:27:37 +0000584 self.assertFalse(F(10**23) == float(10**23))
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000585 # The first test demonstrates why these are important.
Christian Heimes68f5fbe2008-02-14 08:27:37 +0000586 self.assertFalse(1e23 < float(F(math.trunc(1e23) + 1)))
587 self.assertTrue(1e23 < F(math.trunc(1e23) + 1))
588 self.assertFalse(1e23 <= F(math.trunc(1e23) - 1))
589 self.assertTrue(1e23 > F(math.trunc(1e23) - 1))
590 self.assertFalse(1e23 >= F(math.trunc(1e23) + 1))
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000591
592 def testBigComplexComparisons(self):
Christian Heimes68f5fbe2008-02-14 08:27:37 +0000593 self.assertFalse(F(10**23) == complex(10**23))
Mark Dickinson327f02c2010-03-27 11:11:13 +0000594 self.assertRaises(TypeError, operator.gt, F(10**23), complex(10**23))
595 self.assertRaises(TypeError, operator.le, F(10**23), complex(10**23))
596
597 x = F(3, 8)
598 z = complex(0.375, 0.0)
599 w = complex(0.375, 0.2)
600 self.assertTrue(x == z)
601 self.assertFalse(x != z)
602 self.assertFalse(x == w)
603 self.assertTrue(x != w)
604 for op in operator.lt, operator.le, operator.gt, operator.ge:
605 self.assertRaises(TypeError, op, x, z)
606 self.assertRaises(TypeError, op, z, x)
607 self.assertRaises(TypeError, op, x, w)
608 self.assertRaises(TypeError, op, w, x)
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000609
610 def testMixedEqual(self):
Christian Heimes68f5fbe2008-02-14 08:27:37 +0000611 self.assertTrue(0.5 == F(1, 2))
612 self.assertFalse(0.6 == F(1, 2))
613 self.assertTrue(F(1, 2) == 0.5)
614 self.assertFalse(F(1, 2) == 0.4)
615 self.assertTrue(2 == F(4, 2))
616 self.assertFalse(2 == F(3, 2))
617 self.assertTrue(F(4, 2) == 2)
618 self.assertFalse(F(5, 2) == 2)
Mark Dickinson85424c92009-07-18 14:41:42 +0000619 self.assertFalse(F(5, 2) == float('nan'))
620 self.assertFalse(float('nan') == F(3, 7))
621 self.assertFalse(F(5, 2) == float('inf'))
622 self.assertFalse(float('-inf') == F(2, 5))
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000623
624 def testStringification(self):
Ezio Melottib3aedd42010-11-20 19:04:17 +0000625 self.assertEqual("Fraction(7, 3)", repr(F(7, 3)))
626 self.assertEqual("Fraction(6283185307, 2000000000)",
627 repr(F('3.1415926535')))
628 self.assertEqual("Fraction(-1, 100000000000000000000)",
629 repr(F(1, -10**20)))
630 self.assertEqual("7/3", str(F(7, 3)))
631 self.assertEqual("7", str(F(7, 1)))
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000632
633 def testHash(self):
Ezio Melotti682d3742012-02-29 14:05:53 +0200634 hmod = sys.hash_info.modulus
635 hinf = sys.hash_info.inf
Ezio Melottib3aedd42010-11-20 19:04:17 +0000636 self.assertEqual(hash(2.5), hash(F(5, 2)))
637 self.assertEqual(hash(10**50), hash(F(10**50)))
638 self.assertNotEqual(hash(float(10**23)), hash(F(10**23)))
Ezio Melotti682d3742012-02-29 14:05:53 +0200639 self.assertEqual(hinf, hash(F(1, hmod)))
Mark Dickinsonfec66202010-11-13 10:27:38 +0000640 # Check that __hash__ produces the same value as hash(), for
641 # consistency with int and Decimal. (See issue #10356.)
Ezio Melottib3aedd42010-11-20 19:04:17 +0000642 self.assertEqual(hash(F(-1)), F(-1).__hash__())
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000643
644 def testApproximatePi(self):
645 # Algorithm borrowed from
646 # http://docs.python.org/lib/decimal-recipes.html
Christian Heimes68f5fbe2008-02-14 08:27:37 +0000647 three = F(3)
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000648 lasts, t, s, n, na, d, da = 0, three, 3, 1, 0, 0, 24
Christian Heimes68f5fbe2008-02-14 08:27:37 +0000649 while abs(s - lasts) > F(1, 10**9):
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000650 lasts = s
651 n, na = n+na, na+8
652 d, da = d+da, da+32
653 t = (t * n) / d
654 s += t
Ezio Melottib3aedd42010-11-20 19:04:17 +0000655 self.assertAlmostEqual(math.pi, s)
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000656
657 def testApproximateCos1(self):
658 # Algorithm borrowed from
659 # http://docs.python.org/lib/decimal-recipes.html
Christian Heimes68f5fbe2008-02-14 08:27:37 +0000660 x = F(1)
661 i, lasts, s, fact, num, sign = 0, 0, F(1), 1, 1, 1
662 while abs(s - lasts) > F(1, 10**9):
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000663 lasts = s
664 i += 2
665 fact *= i * (i-1)
666 num *= x * x
667 sign *= -1
668 s += num / fact * sign
Ezio Melottib3aedd42010-11-20 19:04:17 +0000669 self.assertAlmostEqual(math.cos(1), s)
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000670
Christian Heimes969fe572008-01-25 11:23:10 +0000671 def test_copy_deepcopy_pickle(self):
Christian Heimes68f5fbe2008-02-14 08:27:37 +0000672 r = F(13, 7)
Ezio Melotti682d3742012-02-29 14:05:53 +0200673 dr = DummyFraction(13, 7)
Christian Heimes969fe572008-01-25 11:23:10 +0000674 self.assertEqual(r, loads(dumps(r)))
675 self.assertEqual(id(r), id(copy(r)))
676 self.assertEqual(id(r), id(deepcopy(r)))
Ezio Melotti682d3742012-02-29 14:05:53 +0200677 self.assertNotEqual(id(dr), id(copy(dr)))
678 self.assertNotEqual(id(dr), id(deepcopy(dr)))
679 self.assertTypedEquals(dr, copy(dr))
680 self.assertTypedEquals(dr, deepcopy(dr))
Christian Heimes969fe572008-01-25 11:23:10 +0000681
Mark Dickinsonc28ad272009-02-12 17:58:36 +0000682 def test_slots(self):
683 # Issue 4998
684 r = F(13, 7)
685 self.assertRaises(AttributeError, setattr, r, 'a', 10)
686
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000687if __name__ == '__main__':
Zachary Ware38c707e2015-04-13 15:00:43 -0500688 unittest.main()