[Python-checkins] r60785 - in python/trunk/Lib: fractions.py test/test_fractions.py

jeffrey.yasskin python-checkins at python.org
Thu Feb 14 07:12:24 CET 2008


Author: jeffrey.yasskin
Date: Thu Feb 14 07:12:24 2008
New Revision: 60785

Modified:
   python/trunk/Lib/fractions.py
   python/trunk/Lib/test/test_fractions.py
Log:
Performance optimizations on Fraction's constructor.

  ./python.exe -m timeit -s 'from fractions import Fraction' 'Fraction(3)`
31.7 usec/loop -> 9.2 usec/loop

  ./python.exe -m timeit -s 'from fractions import Fraction' 'Fraction(3, 2)'`
27.7 usec/loop -> 9.32 usec/loop

  ./python.exe -m timeit -s 'from fractions import Fraction; f = Fraction(3, 2)' 'Fraction(f)'
31.9 usec/loop -> 14.3 usec/loop


Modified: python/trunk/Lib/fractions.py
==============================================================================
--- python/trunk/Lib/fractions.py	(original)
+++ python/trunk/Lib/fractions.py	Thu Feb 14 07:12:24 2008
@@ -64,7 +64,7 @@
         """
         self = super(Fraction, cls).__new__(cls)
 
-        if denominator == 1:
+        if type(numerator) not in (int, long) and denominator == 1:
             if isinstance(numerator, basestring):
                 # Handle construction from strings.
                 input = numerator
@@ -86,24 +86,22 @@
                 if m.group('sign') == '-':
                     numerator = -numerator
 
-            elif (not isinstance(numerator, numbers.Integral) and
-                  isinstance(numerator, Rational)):
-                # Handle copies from other rationals.
+            elif isinstance(numerator, Rational):
+                # Handle copies from other rationals. Integrals get
+                # caught here too, but it doesn't matter because
+                # denominator is already 1.
                 other_rational = numerator
                 numerator = other_rational.numerator
                 denominator = other_rational.denominator
 
-        if (not isinstance(numerator, numbers.Integral) or
-            not isinstance(denominator, numbers.Integral)):
-            raise TypeError("Fraction(%(numerator)s, %(denominator)s):"
-                            " Both arguments must be integral." % locals())
-
         if denominator == 0:
             raise ZeroDivisionError('Fraction(%s, 0)' % numerator)
 
+        numerator = numerator.__index__()
+        denominator = denominator.__index__()
         g = gcd(numerator, denominator)
-        self._numerator = int(numerator // g)
-        self._denominator = int(denominator // g)
+        self._numerator = numerator // g
+        self._denominator = denominator // g
         return self
 
     @classmethod

Modified: python/trunk/Lib/test/test_fractions.py
==============================================================================
--- python/trunk/Lib/test/test_fractions.py	(original)
+++ python/trunk/Lib/test/test_fractions.py	Thu Feb 14 07:12:24 2008
@@ -62,11 +62,11 @@
 
         self.assertRaisesMessage(ZeroDivisionError, "Fraction(12, 0)",
                                  F, 12, 0)
-        self.assertRaises(TypeError, F, 1.5)
-        self.assertRaises(TypeError, F, 1.5 + 3j)
+        self.assertRaises(AttributeError, F, 1.5)
+        self.assertRaises(AttributeError, F, 1.5 + 3j)
 
-        self.assertRaises(TypeError, F, F(1, 2), 3)
-        self.assertRaises(TypeError, F, "3/2", 3)
+        self.assertRaises(AttributeError, F, F(1, 2), 3)
+        self.assertRaises(AttributeError, F, "3/2", 3)
 
     def testFromString(self):
         self.assertEquals((5, 1), _components(F("5")))


More information about the Python-checkins mailing list