From caa608f66c5e117412b943d6888a81fa7f7569a5 Mon Sep 17 00:00:00 2001 From: Sergey B Kirpichev Date: Thu, 1 May 2025 16:44:20 +0300 Subject: [PATCH 1/2] gh-72902: speedup Fraction.from_Decimal/float in typical cases --- Lib/fractions.py | 20 +++++++++---------- ...5-05-01-16-44-16.gh-issue-72902.19qwJW.rst | 3 +++ 2 files changed, 13 insertions(+), 10 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2025-05-01-16-44-16.gh-issue-72902.19qwJW.rst 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..c253510ee8f0f9 --- /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. From 1ea8f6a37909ec4bfa7e35e7191bd7604a9dc884 Mon Sep 17 00:00:00 2001 From: Sergey B Kirpichev Date: Thu, 1 May 2025 16:55:27 +0300 Subject: [PATCH 2/2] +1 --- .../next/Library/2025-05-01-16-44-16.gh-issue-72902.19qwJW.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 index c253510ee8f0f9..471ac8ce5c9dc5 100644 --- 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 @@ -1,3 +1,3 @@ -Optimize (~x1.40-50 speedup) :meth:`fractions.Fraction.from_Decimal` and +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.