https://github.com/python/cpython/commit/7e5d1d8fa8682b0d25f7e5b2b3b77c5306b01b9a
commit: 7e5d1d8fa8682b0d25f7e5b2b3b77c5306b01b9a
branch: main
author: Sergey B Kirpichev <[email protected]>
committer: serhiy-storchaka <[email protected]>
date: 2026-05-25T10:04:56+03:00
summary:

gh-72902: Speedup Fraction.from_decimal/float in typical cases (GH-133251)

files:
A Misc/NEWS.d/next/Library/2025-05-01-16-44-16.gh-issue-72902.19qwJW.rst
M Lib/fractions.py

diff --git a/Lib/fractions.py b/Lib/fractions.py
index c1b12e7a1c091c..84e844cdd69768 100644
--- a/Lib/fractions.py
+++ b/Lib/fractions.py
@@ -339,24 +339,24 @@ def from_float(cls, f):
         Beware that Fraction.from_float(0.3) != Fraction(3, 10).
 
         """
+        if isinstance(f, float):
+            return cls._from_coprime_ints(*f.as_integer_ratio())
         if isinstance(f, numbers.Integral):
             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())
+        raise TypeError("%s.from_float() only takes floats, not %r (%s)" %
+                        (cls.__name__, f, type(f).__name__))
 
     @classmethod
     def from_decimal(cls, dec):
         """Converts a finite Decimal instance to a rational number, exactly."""
         from decimal import Decimal
+        if isinstance(dec, Decimal):
+            return cls._from_coprime_ints(*dec.as_integer_ratio())
         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__))
-        return cls._from_coprime_ints(*dec.as_integer_ratio())
+            dec = int(dec)
+            return cls._from_coprime_ints(*dec.as_integer_ratio())
+        raise TypeError("%s.from_decimal() only takes Decimals, not %r (%s)" %
+                        (cls.__name__, dec, type(dec).__name__))
 
     @classmethod
     def _from_coprime_ints(cls, numerator, denominator, /):
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..2b7d8e44840894
--- /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.4 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.

_______________________________________________
Python-checkins mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3//lists/python-checkins.python.org
Member address: [email protected]

Reply via email to