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.
........
diff --git a/Lib/fractions.py b/Lib/fractions.py
index 5242f8f..fcebb4f 100755
--- a/Lib/fractions.py
+++ b/Lib/fractions.py
@@ -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