diff --git a/Lib/fractions.py b/Lib/fractions.py index fa722589fb4f67..adf7da93fd19c2 100644 --- a/Lib/fractions.py +++ b/Lib/fractions.py @@ -335,23 +335,23 @@ def from_float(cls, f): Beware that Fraction.from_float(0.3) != Fraction(3, 10). """ - if isinstance(f, numbers.Integral): + if not isinstance(f, float): + if not isinstance(f, numbers.Integral): + raise TypeError("%s.from_float() only takes floats, not %r (%s)" % + (cls.__name__, f, type(f).__name__)) return cls(f) - elif not isinstance(f, float): - raise TypeError("%s.from_float() only takes floats, not %r (%s)" % - (cls.__name__, f, type(f).__name__)) return cls._from_coprime_ints(*f.as_integer_ratio()) @classmethod def from_decimal(cls, dec): """Converts a finite Decimal instance to a rational number, exactly.""" from decimal import Decimal - if isinstance(dec, numbers.Integral): - dec = Decimal(int(dec)) - elif not isinstance(dec, Decimal): - raise TypeError( - "%s.from_decimal() only takes Decimals, not %r (%s)" % - (cls.__name__, dec, type(dec).__name__)) + if not isinstance(dec, Decimal): + if not isinstance(dec, numbers.Integral): + raise TypeError( + "%s.from_decimal() only takes Decimals, not %r (%s)" % + (cls.__name__, dec, type(dec).__name__)) + dec = int(dec) return cls._from_coprime_ints(*dec.as_integer_ratio()) @classmethod diff --git a/Misc/NEWS.d/next/Library/2025-05-01-16-44-16.gh-issue-72902.19qwJW.rst b/Misc/NEWS.d/next/Library/2025-05-01-16-44-16.gh-issue-72902.19qwJW.rst new file mode 100644 index 00000000000000..471ac8ce5c9dc5 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2025-05-01-16-44-16.gh-issue-72902.19qwJW.rst @@ -0,0 +1,3 @@ +Optimize (~x1.40-50 speedup) :meth:`fractions.Fraction.from_decimal` and +:meth:`fractions.Fraction.from_float` for :class:`~decimal.Decimal` and +:class:`float` inputs, respectively. Patch by Sergey B Kirpichev.