Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 5319c66

Browse files
authored
gh-102840: Fix confused traceback when floordiv or mod operations happens between Fraction and complex objects (GH-102842)
1 parent 597fad0 commit 5319c66

File tree

3 files changed

+37
-6
lines changed

3 files changed

+37
-6
lines changed

Lib/fractions.py

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -579,7 +579,8 @@ def __format__(self, format_spec, /):
579579
f"for object of type {type(self).__name__!r}"
580580
)
581581

582-
def _operator_fallbacks(monomorphic_operator, fallback_operator):
582+
def _operator_fallbacks(monomorphic_operator, fallback_operator,
583+
handle_complex=True):
583584
"""Generates forward and reverse operators given a purely-rational
584585
operator and a function from the operator module.
585586
@@ -666,7 +667,7 @@ def forward(a, b):
666667
return monomorphic_operator(a, Fraction(b))
667668
elif isinstance(b, float):
668669
return fallback_operator(float(a), b)
669-
elif isinstance(b, complex):
670+
elif handle_complex and isinstance(b, complex):
670671
return fallback_operator(complex(a), b)
671672
else:
672673
return NotImplemented
@@ -679,7 +680,7 @@ def reverse(b, a):
679680
return monomorphic_operator(Fraction(a), b)
680681
elif isinstance(a, numbers.Real):
681682
return fallback_operator(float(a), float(b))
682-
elif isinstance(a, numbers.Complex):
683+
elif handle_complex and isinstance(a, numbers.Complex):
683684
return fallback_operator(complex(a), complex(b))
684685
else:
685686
return NotImplemented
@@ -830,22 +831,22 @@ def _floordiv(a, b):
830831
"""a // b"""
831832
return (a.numerator * b.denominator) // (a.denominator * b.numerator)
832833

833-
__floordiv__, __rfloordiv__ = _operator_fallbacks(_floordiv, operator.floordiv)
834+
__floordiv__, __rfloordiv__ = _operator_fallbacks(_floordiv, operator.floordiv, False)
834835

835836
def _divmod(a, b):
836837
"""(a // b, a % b)"""
837838
da, db = a.denominator, b.denominator
838839
div, n_mod = divmod(a.numerator * db, da * b.numerator)
839840
return div, Fraction(n_mod, da * db)
840841

841-
__divmod__, __rdivmod__ = _operator_fallbacks(_divmod, divmod)
842+
__divmod__, __rdivmod__ = _operator_fallbacks(_divmod, divmod, False)
842843

843844
def _mod(a, b):
844845
"""a % b"""
845846
da, db = a.denominator, b.denominator
846847
return Fraction((a.numerator * db) % (b.numerator * da), da * db)
847848

848-
__mod__, __rmod__ = _operator_fallbacks(_mod, operator.mod)
849+
__mod__, __rmod__ = _operator_fallbacks(_mod, operator.mod, False)
849850

850851
def __pow__(a, b):
851852
"""a ** b

Lib/test/test_fractions.py

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1314,6 +1314,33 @@ def test_float_format_testfile(self):
13141314
self.assertEqual(float(format(f, fmt2)), float(rhs))
13151315
self.assertEqual(float(format(-f, fmt2)), float('-' + rhs))
13161316

1317+
def test_complex_handling(self):
1318+
# See issue gh-102840 for more details.
1319+
1320+
a = F(1, 2)
1321+
b = 1j
1322+
message = "unsupported operand type(s) for %s: '%s' and '%s'"
1323+
# test forward
1324+
self.assertRaisesMessage(TypeError,
1325+
message % ("%", "Fraction", "complex"),
1326+
operator.mod, a, b)
1327+
self.assertRaisesMessage(TypeError,
1328+
message % ("//", "Fraction", "complex"),
1329+
operator.floordiv, a, b)
1330+
self.assertRaisesMessage(TypeError,
1331+
message % ("divmod()", "Fraction", "complex"),
1332+
divmod, a, b)
1333+
# test reverse
1334+
self.assertRaisesMessage(TypeError,
1335+
message % ("%", "complex", "Fraction"),
1336+
operator.mod, b, a)
1337+
self.assertRaisesMessage(TypeError,
1338+
message % ("//", "complex", "Fraction"),
1339+
operator.floordiv, b, a)
1340+
self.assertRaisesMessage(TypeError,
1341+
message % ("divmod()", "complex", "Fraction"),
1342+
divmod, b, a)
1343+
13171344

13181345
if __name__ == '__main__':
13191346
unittest.main()
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
Fix confused traceback when floordiv, mod, or divmod operations happens
2+
between instances of :class:`fractions.Fraction` and :class:`complex`.
3+

0 commit comments

Comments
 (0)