[Python-checkins] r71834 - in python/branches/py3k: Lib/fractions.py Lib/test/test_fractions.py Misc/NEWS

mark.dickinson python-checkins at python.org
Fri Apr 24 16:06:19 CEST 2009


Author: mark.dickinson
Date: Fri Apr 24 16:06:19 2009
New Revision: 71834

Log:
Merged revisions 71832 via svnmerge from 
svn+ssh://pythondev@svn.python.org/python/trunk

........
  r71832 | mark.dickinson | 2009-04-24 14:56:07 +0100 (Fri, 24 Apr 2009) | 3 lines
  
  Issue #5812: The two-argument form of the Fraction constructor
  now accepts arbitrary Rational instances.
........


Modified:
   python/branches/py3k/   (props changed)
   python/branches/py3k/Lib/fractions.py
   python/branches/py3k/Lib/test/test_fractions.py
   python/branches/py3k/Misc/NEWS

Modified: python/branches/py3k/Lib/fractions.py
==============================================================================
--- python/branches/py3k/Lib/fractions.py	(original)
+++ python/branches/py3k/Lib/fractions.py	Fri Apr 24 16:06:19 2009
@@ -54,7 +54,7 @@
     __slots__ = ('_numerator', '_denominator')
 
     # We're immutable, so use __new__ not __init__
-    def __new__(cls, numerator=0, denominator=1):
+    def __new__(cls, numerator=0, denominator=None):
         """Constructs a Rational.
 
         Takes a string like '3/2' or '1.5', another Rational, or a
@@ -63,8 +63,13 @@
         """
         self = super(Fraction, cls).__new__(cls)
 
-        if not isinstance(numerator, int) and denominator == 1:
-            if isinstance(numerator, str):
+        if denominator is None:
+            if isinstance(numerator, numbers.Rational):
+                self._numerator = numerator.numerator
+                self._denominator = numerator.denominator
+                return self
+
+            elif isinstance(numerator, str):
                 # Handle construction from strings.
                 m = _RATIONAL_FORMAT.match(numerator)
                 if m is None:
@@ -91,18 +96,22 @@
                 if m.group('sign') == '-':
                     numerator = -numerator
 
-            elif isinstance(numerator, numbers.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
+            else:
+                raise TypeError("argument should be a string "
+                                "or a Rational instance")
+
+        elif (isinstance(numerator, numbers.Rational) and
+            isinstance(denominator, numbers.Rational)):
+            numerator, denominator = (
+                numerator.numerator * denominator.denominator,
+                denominator.numerator * numerator.denominator
+                )
+        else:
+            raise TypeError("both arguments should be "
+                            "Rational instances")
 
         if denominator == 0:
             raise ZeroDivisionError('Fraction(%s, 0)' % numerator)
-        numerator = operator.index(numerator)
-        denominator = operator.index(denominator)
         g = gcd(numerator, denominator)
         self._numerator = numerator // g
         self._denominator = denominator // g

Modified: python/branches/py3k/Lib/test/test_fractions.py
==============================================================================
--- python/branches/py3k/Lib/test/test_fractions.py	(original)
+++ python/branches/py3k/Lib/test/test_fractions.py	Fri Apr 24 16:06:19 2009
@@ -60,13 +60,19 @@
         self.assertEquals((7, 15), _components(F(7, 15)))
         self.assertEquals((10**23, 1), _components(F(10**23)))
 
+        self.assertEquals((3, 77), _components(F(F(3, 7), 11)))
+        self.assertEquals((-9, 5), _components(F(2, F(-10, 9))))
+        self.assertEquals((2486, 2485), _components(F(F(22, 7), F(355, 113))))
+
         self.assertRaisesMessage(ZeroDivisionError, "Fraction(12, 0)",
                                  F, 12, 0)
         self.assertRaises(TypeError, F, 1.5)
         self.assertRaises(TypeError, F, 1.5 + 3j)
 
-        self.assertRaises(TypeError, F, F(1, 2), 3)
         self.assertRaises(TypeError, F, "3/2", 3)
+        self.assertRaises(TypeError, F, 3, 0j)
+        self.assertRaises(TypeError, F, 3, 1j)
+
 
     def testFromString(self):
         self.assertEquals((5, 1), _components(F("5")))

Modified: python/branches/py3k/Misc/NEWS
==============================================================================
--- python/branches/py3k/Misc/NEWS	(original)
+++ python/branches/py3k/Misc/NEWS	Fri Apr 24 16:06:19 2009
@@ -77,6 +77,10 @@
 Library
 -------
 
+- Issue #5812: For the two-argument form of the Fraction constructor,
+  Fraction(m, n), m and n are permitted to be arbitrary Rational
+  instances.
+
 - Issue #5812: Fraction('1e6') is valid: more generally, any string
   that's valid for float() is now valid for Fraction(), with the
   exception of strings representing NaNs and infinities.


More information about the Python-checkins mailing list