Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit572b0b0

Browse files
[3.13]gh-119189: Add more tests for mixed Fraction arithmetic (GH-119236) (GH-119255)
(cherry picked from commitfe67af1)Co-authored-by: Serhiy Storchaka <storchaka@gmail.com>
1 parentb4462aa commit572b0b0

File tree

1 file changed

+263
-0
lines changed

1 file changed

+263
-0
lines changed

‎Lib/test/test_fractions.py‎

Lines changed: 263 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
"""Tests for Lib/fractions.py."""
22

3+
importcmath
34
fromdecimalimportDecimal
45
fromtest.supportimportrequires_IEEE_754
56
importmath
@@ -91,6 +92,187 @@ class DummyFraction(fractions.Fraction):
9192
def_components(r):
9293
return (r.numerator,r.denominator)
9394

95+
deftyped_approx_eq(a,b):
96+
returntype(a)==type(b)and (a==bormath.isclose(a,b))
97+
98+
classSymbolic:
99+
"""Simple non-numeric class for testing mixed arithmetic.
100+
It is not Integral, Rational, Real or Complex, and cannot be conveted
101+
to int, float or complex. but it supports some arithmetic operations.
102+
"""
103+
def__init__(self,value):
104+
self.value=value
105+
def__mul__(self,other):
106+
ifisinstance(other,F):
107+
returnNotImplemented
108+
returnself.__class__(f'{self} *{other}')
109+
def__rmul__(self,other):
110+
returnself.__class__(f'{other} *{self}')
111+
def__truediv__(self,other):
112+
ifisinstance(other,F):
113+
returnNotImplemented
114+
returnself.__class__(f'{self} /{other}')
115+
def__rtruediv__(self,other):
116+
returnself.__class__(f'{other} /{self}')
117+
def__mod__(self,other):
118+
ifisinstance(other,F):
119+
returnNotImplemented
120+
returnself.__class__(f'{self} %{other}')
121+
def__rmod__(self,other):
122+
returnself.__class__(f'{other} %{self}')
123+
def__pow__(self,other):
124+
ifisinstance(other,F):
125+
returnNotImplemented
126+
returnself.__class__(f'{self} **{other}')
127+
def__rpow__(self,other):
128+
returnself.__class__(f'{other} **{self}')
129+
def__eq__(self,other):
130+
ifother.__class__!=self.__class__:
131+
returnNotImplemented
132+
returnself.value==other.value
133+
def__str__(self):
134+
returnf'{self.value}'
135+
def__repr__(self):
136+
returnf'{self.__class__.__name__}({self.value!r})'
137+
138+
classRat:
139+
"""Simple Rational class for testing mixed arithmetic."""
140+
def__init__(self,n,d):
141+
self.numerator=n
142+
self.denominator=d
143+
def__mul__(self,other):
144+
ifisinstance(other,F):
145+
returnNotImplemented
146+
returnself.__class__(self.numerator*other.numerator,
147+
self.denominator*other.denominator)
148+
def__rmul__(self,other):
149+
returnself.__class__(other.numerator*self.numerator,
150+
other.denominator*self.denominator)
151+
def__truediv__(self,other):
152+
ifisinstance(other,F):
153+
returnNotImplemented
154+
returnself.__class__(self.numerator*other.denominator,
155+
self.denominator*other.numerator)
156+
def__rtruediv__(self,other):
157+
returnself.__class__(other.numerator*self.denominator,
158+
other.denominator*self.numerator)
159+
def__mod__(self,other):
160+
ifisinstance(other,F):
161+
returnNotImplemented
162+
d=self.denominator*other.numerator
163+
returnself.__class__(self.numerator*other.denominator%d,d)
164+
def__rmod__(self,other):
165+
d=other.denominator*self.numerator
166+
returnself.__class__(other.numerator*self.denominator%d,d)
167+
168+
returnself.__class__(other.numerator/self.numerator,
169+
other.denominator/self.denominator)
170+
def__pow__(self,other):
171+
ifisinstance(other,F):
172+
returnNotImplemented
173+
returnself.__class__(self.numerator**other,
174+
self.denominator**other)
175+
def__float__(self):
176+
returnself.numerator/self.denominator
177+
def__eq__(self,other):
178+
ifself.__class__!=other.__class__:
179+
returnNotImplemented
180+
return (typed_approx_eq(self.numerator,other.numerator)and
181+
typed_approx_eq(self.denominator,other.denominator))
182+
def__repr__(self):
183+
returnf'{self.__class__.__name__}({self.numerator!r},{self.denominator!r})'
184+
numbers.Rational.register(Rat)
185+
186+
classRoot:
187+
"""Simple Real class for testing mixed arithmetic."""
188+
def__init__(self,v,n=F(2)):
189+
self.base=v
190+
self.degree=n
191+
def__mul__(self,other):
192+
ifisinstance(other,F):
193+
returnNotImplemented
194+
returnself.__class__(self.base*other**self.degree,self.degree)
195+
def__rmul__(self,other):
196+
returnself.__class__(other**self.degree*self.base,self.degree)
197+
def__truediv__(self,other):
198+
ifisinstance(other,F):
199+
returnNotImplemented
200+
returnself.__class__(self.base/other**self.degree,self.degree)
201+
def__rtruediv__(self,other):
202+
returnself.__class__(other**self.degree/self.base,self.degree)
203+
def__pow__(self,other):
204+
ifisinstance(other,F):
205+
returnNotImplemented
206+
returnself.__class__(self.base,self.degree/other)
207+
def__float__(self):
208+
returnfloat(self.base)** (1/float(self.degree))
209+
def__eq__(self,other):
210+
ifself.__class__!=other.__class__:
211+
returnNotImplemented
212+
returntyped_approx_eq(self.base,other.base)andtyped_approx_eq(self.degree,other.degree)
213+
def__repr__(self):
214+
returnf'{self.__class__.__name__}({self.base!r},{self.degree!r})'
215+
numbers.Real.register(Root)
216+
217+
classPolar:
218+
"""Simple Complex class for testing mixed arithmetic."""
219+
def__init__(self,r,phi):
220+
self.r=r
221+
self.phi=phi
222+
def__mul__(self,other):
223+
ifisinstance(other,F):
224+
returnNotImplemented
225+
returnself.__class__(self.r*other,self.phi)
226+
def__rmul__(self,other):
227+
returnself.__class__(other*self.r,self.phi)
228+
def__truediv__(self,other):
229+
ifisinstance(other,F):
230+
returnNotImplemented
231+
returnself.__class__(self.r/other,self.phi)
232+
def__rtruediv__(self,other):
233+
returnself.__class__(other/self.r,-self.phi)
234+
def__pow__(self,other):
235+
ifisinstance(other,F):
236+
returnNotImplemented
237+
returnself.__class__(self.r**other,self.phi*other)
238+
def__eq__(self,other):
239+
ifself.__class__!=other.__class__:
240+
returnNotImplemented
241+
returntyped_approx_eq(self.r,other.r)andtyped_approx_eq(self.phi,other.phi)
242+
def__repr__(self):
243+
returnf'{self.__class__.__name__}({self.r!r},{self.phi!r})'
244+
numbers.Complex.register(Polar)
245+
246+
classRect:
247+
"""Other simple Complex class for testing mixed arithmetic."""
248+
def__init__(self,x,y):
249+
self.x=x
250+
self.y=y
251+
def__mul__(self,other):
252+
ifisinstance(other,F):
253+
returnNotImplemented
254+
returnself.__class__(self.x*other,self.y*other)
255+
def__rmul__(self,other):
256+
returnself.__class__(other*self.x,other*self.y)
257+
def__truediv__(self,other):
258+
ifisinstance(other,F):
259+
returnNotImplemented
260+
returnself.__class__(self.x/other,self.y/other)
261+
def__rtruediv__(self,other):
262+
r=self.x*self.x+self.y*self.y
263+
returnself.__class__(other* (self.x/r),other* (self.y/r))
264+
def__rpow__(self,other):
265+
returnPolar(other**self.x,math.log(other)*self.y)
266+
def__complex__(self):
267+
returncomplex(self.x,self.y)
268+
def__eq__(self,other):
269+
ifself.__class__!=other.__class__:
270+
returnNotImplemented
271+
returntyped_approx_eq(self.x,other.x)andtyped_approx_eq(self.y,other.y)
272+
def__repr__(self):
273+
returnf'{self.__class__.__name__}({self.x!r},{self.y!r})'
274+
numbers.Complex.register(Rect)
275+
94276

95277
classFractionTest(unittest.TestCase):
96278

@@ -593,20 +775,57 @@ def testMixedArithmetic(self):
593775
self.assertTypedEquals(0.9,1.0-F(1,10))
594776
self.assertTypedEquals(0.9+0j, (1.0+0j)-F(1,10))
595777

778+
deftestMixedMultiplication(self):
596779
self.assertTypedEquals(F(1,10),F(1,10)*1)
597780
self.assertTypedEquals(0.1,F(1,10)*1.0)
598781
self.assertTypedEquals(0.1+0j,F(1,10)* (1.0+0j))
599782
self.assertTypedEquals(F(1,10),1*F(1,10))
600783
self.assertTypedEquals(0.1,1.0*F(1,10))
601784
self.assertTypedEquals(0.1+0j, (1.0+0j)*F(1,10))
602785

786+
self.assertTypedEquals(F(3,2)*DummyFraction(5,3),F(5,2))
787+
self.assertTypedEquals(DummyFraction(5,3)*F(3,2),F(5,2))
788+
self.assertTypedEquals(F(3,2)*Rat(5,3),Rat(15,6))
789+
self.assertTypedEquals(Rat(5,3)*F(3,2),F(5,2))
790+
791+
self.assertTypedEquals(F(3,2)*Root(4),Root(F(9,1)))
792+
self.assertTypedEquals(Root(4)*F(3,2),3.0)
793+
794+
self.assertTypedEquals(F(3,2)*Polar(4,2),Polar(F(6,1),2))
795+
self.assertTypedEquals(F(3,2)*Polar(4.0,2),Polar(6.0,2))
796+
self.assertTypedEquals(F(3,2)*Rect(4,3),Rect(F(6,1),F(9,2)))
797+
self.assertRaises(TypeError,operator.mul,Polar(4,2),F(3,2))
798+
self.assertTypedEquals(Rect(4,3)*F(3,2),6.0+4.5j)
799+
800+
self.assertEqual(F(3,2)*Symbolic('X'),Symbolic('3/2 * X'))
801+
self.assertRaises(TypeError,operator.mul,Symbolic('X'),F(3,2))
802+
803+
deftestMixedDivision(self):
603804
self.assertTypedEquals(F(1,10),F(1,10)/1)
604805
self.assertTypedEquals(0.1,F(1,10)/1.0)
605806
self.assertTypedEquals(0.1+0j,F(1,10)/ (1.0+0j))
606807
self.assertTypedEquals(F(10,1),1/F(1,10))
607808
self.assertTypedEquals(10.0,1.0/F(1,10))
608809
self.assertTypedEquals(10.0+0j, (1.0+0j)/F(1,10))
609810

811+
self.assertTypedEquals(F(3,2)/DummyFraction(3,5),F(5,2))
812+
self.assertTypedEquals(DummyFraction(5,3)/F(2,3),F(5,2))
813+
self.assertTypedEquals(F(3,2)/Rat(3,5),Rat(15,6))
814+
self.assertTypedEquals(Rat(5,3)/F(2,3),F(5,2))
815+
816+
self.assertTypedEquals(F(2,3)/Root(4),Root(F(1,9)))
817+
self.assertTypedEquals(Root(4)/F(2,3),3.0)
818+
819+
self.assertTypedEquals(F(3,2)/Polar(4,2),Polar(F(3,8),-2))
820+
self.assertTypedEquals(F(3,2)/Polar(4.0,2),Polar(0.375,-2))
821+
self.assertTypedEquals(F(3,2)/Rect(4,3),Rect(0.24,0.18))
822+
self.assertRaises(TypeError,operator.truediv,Polar(4,2),F(2,3))
823+
self.assertTypedEquals(Rect(4,3)/F(2,3),6.0+4.5j)
824+
825+
self.assertEqual(F(3,2)/Symbolic('X'),Symbolic('3/2 / X'))
826+
self.assertRaises(TypeError,operator.truediv,Symbolic('X'),F(2,3))
827+
828+
deftestMixedIntegerDivision(self):
610829
self.assertTypedEquals(0,F(1,10)//1)
611830
self.assertTypedEquals(0.0,F(1,10)//1.0)
612831
self.assertTypedEquals(10,1//F(1,10))
@@ -631,6 +850,21 @@ def testMixedArithmetic(self):
631850
self.assertTypedTupleEquals(divmod(-0.1,float('inf')),divmod(F(-1,10),float('inf')))
632851
self.assertTypedTupleEquals(divmod(-0.1,float('-inf')),divmod(F(-1,10),float('-inf')))
633852

853+
self.assertTypedEquals(F(3,2)%DummyFraction(3,5),F(3,10))
854+
self.assertTypedEquals(DummyFraction(5,3)%F(2,3),F(1,3))
855+
self.assertTypedEquals(F(3,2)%Rat(3,5),Rat(3,6))
856+
self.assertTypedEquals(Rat(5,3)%F(2,3),F(1,3))
857+
858+
self.assertRaises(TypeError,operator.mod,F(2,3),Root(4))
859+
self.assertTypedEquals(Root(4)%F(3,2),0.5)
860+
861+
self.assertRaises(TypeError,operator.mod,F(3,2),Polar(4,2))
862+
self.assertRaises(TypeError,operator.mod,Rect(4,3),F(2,3))
863+
864+
self.assertEqual(F(3,2)%Symbolic('X'),Symbolic('3/2 % X'))
865+
self.assertRaises(TypeError,operator.mod,Symbolic('X'),F(2,3))
866+
867+
deftestMixedPower(self):
634868
# ** has more interesting conversion rules.
635869
self.assertTypedEquals(F(100,1),F(1,10)**-2)
636870
self.assertTypedEquals(F(100,1),F(10,1)**2)
@@ -647,6 +881,35 @@ def testMixedArithmetic(self):
647881
self.assertRaises(ZeroDivisionError,operator.pow,
648882
F(0,1),-2)
649883

884+
self.assertTypedEquals(F(3,2)**Rat(3,1),F(27,8))
885+
self.assertTypedEquals(F(3,2)**Rat(-3,1),F(8,27))
886+
self.assertTypedEquals(F(-3,2)**Rat(-3,1),F(-8,27))
887+
self.assertTypedEquals(F(9,4)**Rat(3,2),3.375)
888+
self.assertIsInstance(F(4,9)**Rat(-3,2),float)
889+
self.assertAlmostEqual(F(4,9)**Rat(-3,2),3.375)
890+
self.assertAlmostEqual(F(-4,9)**Rat(-3,2),3.375j)
891+
892+
self.assertTypedEquals(Rat(9,4)**F(3,2),3.375)
893+
self.assertTypedEquals(Rat(3,2)**F(3,1),Rat(27,8))
894+
self.assertTypedEquals(Rat(3,2)**F(-3,1),F(8,27))
895+
self.assertIsInstance(Rat(4,9)**F(-3,2),float)
896+
self.assertAlmostEqual(Rat(4,9)**F(-3,2),3.375)
897+
898+
self.assertTypedEquals(Root(4)**F(2,3),Root(4,3.0))
899+
self.assertTypedEquals(Root(4)**F(2,1),Root(4,F(1)))
900+
self.assertTypedEquals(Root(4)**F(-2,1),Root(4,-F(1)))
901+
self.assertTypedEquals(Root(4)**F(-2,3),Root(4,-3.0))
902+
903+
self.assertTypedEquals(F(3,2)**Rect(2,0),Polar(2.25,0.0))
904+
self.assertTypedEquals(F(1,1)**Rect(2,3),Polar(1.0,0.0))
905+
self.assertTypedEquals(Polar(4,2)**F(3,2),Polar(8.0,3.0))
906+
self.assertTypedEquals(Polar(4,2)**F(3,1),Polar(64,6))
907+
self.assertTypedEquals(Polar(4,2)**F(-3,1),Polar(0.015625,-6))
908+
self.assertTypedEquals(Polar(4,2)**F(-3,2),Polar(0.125,-3.0))
909+
910+
self.assertTypedEquals(F(3,2)**Symbolic('X'),Symbolic('1.5 ** X'))
911+
self.assertTypedEquals(Symbolic('X')**F(3,2),Symbolic('X ** 1.5'))
912+
650913
deftestMixingWithDecimal(self):
651914
# Decimal refuses mixed arithmetic (but not mixed comparisons)
652915
self.assertRaises(TypeError,operator.add,

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp