Ignore:
Timestamp:
Mar 19, 2014, 11:11:30 AM (11 years ago)
Author:
dmik
Message:

python: Update vendor to 2.7.6.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • python/vendor/current/Lib/fractions.py

    r2 r388  
    55
    66from __future__ import division
     7from decimal import Decimal
    78import math
    89import numbers
     
    3132    (?=\d|\.\d)                # lookahead for digit or .digit
    3233    (?P<num>\d*)               # numerator (possibly empty)
    33     (?:                        # followed by an optional
    34        /(?P<denom>\d+)         # / and denominator
     34    (?:                        # followed by
     35       (?:/(?P<denom>\d+))?    # an optional denominator
    3536    |                          # or
    36        \.(?P<decimal>\d*)      # decimal point and fractional part
    37     )?
     37       (?:\.(?P<decimal>\d*))? # an optional fractional part
     38       (?:E(?P<exp>[-+]?\d+))? # and optional exponent
     39    )
    3840    \s*\Z                      # and optional whitespace to finish
    39 """, re.VERBOSE)
     41""", re.VERBOSE | re.IGNORECASE)
    4042
    4143
     
    4345    """This class implements rational numbers.
    4446
    45     Fraction(8, 6) will produce a rational number equivalent to
    46     4/3. Both arguments must be Integral. The numerator defaults to 0
    47     and the denominator defaults to 1 so that Fraction(3) == 3 and
    48     Fraction() == 0.
    49 
    50     Fractions can also be constructed from strings of the form
    51     '[-+]?[0-9]+((/|.)[0-9]+)?', optionally surrounded by spaces.
     47    In the two-argument form of the constructor, Fraction(8, 6) will
     48    produce a rational number equivalent to 4/3. Both arguments must
     49    be Rational. The numerator defaults to 0 and the denominator
     50    defaults to 1 so that Fraction(3) == 3 and Fraction() == 0.
     51
     52    Fractions can also be constructed from:
     53
     54      - numeric strings similar to those accepted by the
     55        float constructor (for example, '-2.3' or '1e10')
     56
     57      - strings of the form '123/456'
     58
     59      - float and Decimal instances
     60
     61      - other Rational instances (including integers)
    5262
    5363    """
     
    5666
    5767    # We're immutable, so use __new__ not __init__
    58     def __new__(cls, numerator=0, denominator=1):
     68    def __new__(cls, numerator=0, denominator=None):
    5969        """Constructs a Fraction.
    6070
    61         Takes a string like '3/2' or '1.5', another Fraction, or a
    62         numerator/denominator pair.
     71        Takes a string like '3/2' or '1.5', another Rational instance, a
     72        numerator/denominator pair, or a float.
     73
     74        Examples
     75        --------
     76
     77        >>> Fraction(10, -8)
     78        Fraction(-5, 4)
     79        >>> Fraction(Fraction(1, 7), 5)
     80        Fraction(1, 35)
     81        >>> Fraction(Fraction(1, 7), Fraction(2, 3))
     82        Fraction(3, 14)
     83        >>> Fraction('314')
     84        Fraction(314, 1)
     85        >>> Fraction('-35/4')
     86        Fraction(-35, 4)
     87        >>> Fraction('3.1415') # conversion from numeric string
     88        Fraction(6283, 2000)
     89        >>> Fraction('-47e-2') # string may include a decimal exponent
     90        Fraction(-47, 100)
     91        >>> Fraction(1.47)  # direct construction from float (exact conversion)
     92        Fraction(6620291452234629, 4503599627370496)
     93        >>> Fraction(2.25)
     94        Fraction(9, 4)
     95        >>> Fraction(Decimal('1.47'))
     96        Fraction(147, 100)
    6397
    6498        """
    6599        self = super(Fraction, cls).__new__(cls)
    66100
    67         if type(numerator) not in (int, long) and denominator == 1:
    68             if isinstance(numerator, basestring):
     101        if denominator is None:
     102            if isinstance(numerator, Rational):
     103                self._numerator = numerator.numerator
     104                self._denominator = numerator.denominator
     105                return self
     106
     107            elif isinstance(numerator, float):
     108                # Exact conversion from float
     109                value = Fraction.from_float(numerator)
     110                self._numerator = value._numerator
     111                self._denominator = value._denominator
     112                return self
     113
     114            elif isinstance(numerator, Decimal):
     115                value = Fraction.from_decimal(numerator)
     116                self._numerator = value._numerator
     117                self._denominator = value._denominator
     118                return self
     119
     120            elif isinstance(numerator, basestring):
    69121                # Handle construction from strings.
    70                 input = numerator
    71                 m = _RATIONAL_FORMAT.match(input)
     122                m = _RATIONAL_FORMAT.match(numerator)
    72123                if m is None:
    73                     raise ValueError('Invalid literal for Fraction: %r' % input)
    74                 numerator = m.group('num')
    75                 decimal = m.group('decimal')
    76                 if decimal:
    77                     # The literal is a decimal number.
    78                     numerator = int(numerator + decimal)
    79                     denominator = 10**len(decimal)
     124                    raise ValueError('Invalid literal for Fraction: %r' %
     125                                     numerator)
     126                numerator = int(m.group('num') or '0')
     127                denom = m.group('denom')
     128                if denom:
     129                    denominator = int(denom)
    80130                else:
    81                     # The literal is an integer or fraction.
    82                     numerator = int(numerator)
    83                     # Default denominator to 1.
    84                     denominator = int(m.group('denom') or 1)
    85 
     131                    denominator = 1
     132                    decimal = m.group('decimal')
     133                    if decimal:
     134                        scale = 10**len(decimal)
     135                        numerator = numerator * scale + int(decimal)
     136                        denominator *= scale
     137                    exp = m.group('exp')
     138                    if exp:
     139                        exp = int(exp)
     140                        if exp >= 0:
     141                            numerator *= 10**exp
     142                        else:
     143                            denominator *= 10**-exp
    86144                if m.group('sign') == '-':
    87145                    numerator = -numerator
    88146
    89             elif isinstance(numerator, Rational):
    90                 # Handle copies from other rationals. Integrals get
    91                 # caught here too, but it doesn't matter because
    92                 # denominator is already 1.
    93                 other_rational = numerator
    94                 numerator = other_rational.numerator
    95                 denominator = other_rational.denominator
     147            else:
     148                raise TypeError("argument should be a string "
     149                                "or a Rational instance")
     150
     151        elif (isinstance(numerator, Rational) and
     152            isinstance(denominator, Rational)):
     153            numerator, denominator = (
     154                numerator.numerator * denominator.denominator,
     155                denominator.numerator * numerator.denominator
     156                )
     157        else:
     158            raise TypeError("both arguments should be "
     159                            "Rational instances")
    96160
    97161        if denominator == 0:
    98162            raise ZeroDivisionError('Fraction(%s, 0)' % numerator)
    99         numerator = operator.index(numerator)
    100         denominator = operator.index(denominator)
    101163        g = gcd(numerator, denominator)
    102164        self._numerator = numerator // g
     
    471533            b = b.real
    472534        if isinstance(b, float):
    473             return a == a.from_float(b)
    474         else:
    475             # XXX: If b.__eq__ is implemented like this method, it may
    476             # give the wrong answer after float(a) changes a's
    477             # value. Better ways of doing this are welcome.
    478             return float(a) == b
    479 
    480     def _subtractAndCompareToZero(a, b, op):
    481         """Helper function for comparison operators.
    482 
    483         Subtracts b from a, exactly if possible, and compares the
    484         result with 0 using op, in such a way that the comparison
    485         won't recurse. If the difference raises a TypeError, returns
    486         NotImplemented instead.
     535            if math.isnan(b) or math.isinf(b):
     536                # comparisons with an infinity or nan should behave in
     537                # the same way for any finite a, so treat a as zero.
     538                return 0.0 == b
     539            else:
     540                return a == a.from_float(b)
     541        else:
     542            # Since a doesn't know how to compare with b, let's give b
     543            # a chance to compare itself with a.
     544            return NotImplemented
     545
     546    def _richcmp(self, other, op):
     547        """Helper for comparison operators, for internal use only.
     548
     549        Implement comparison between a Rational instance `self`, and
     550        either another Rational instance or a float `other`.  If
     551        `other` is not a Rational instance or a float, return
     552        NotImplemented. `op` should be one of the six standard
     553        comparison operators.
    487554
    488555        """
    489         if isinstance(b, numbers.Complex) and b.imag == 0:
    490             b = b.real
    491         if isinstance(b, float):
    492             b = a.from_float(b)
    493         try:
    494             # XXX: If b <: Real but not <: Rational, this is likely
    495             # to fall back to a float. If the actual values differ by
    496             # less than MIN_FLOAT, this could falsely call them equal,
    497             # which would make <= inconsistent with ==. Better ways of
    498             # doing this are welcome.
    499             diff = a - b
    500         except TypeError:
     556        # convert other to a Rational instance where reasonable.
     557        if isinstance(other, Rational):
     558            return op(self._numerator * other.denominator,
     559                      self._denominator * other.numerator)
     560        # comparisons with complex should raise a TypeError, for consistency
     561        # with int<->complex, float<->complex, and complex<->complex comparisons.
     562        if isinstance(other, complex):
     563            raise TypeError("no ordering relation is defined for complex numbers")
     564        if isinstance(other, float):
     565            if math.isnan(other) or math.isinf(other):
     566                return op(0.0, other)
     567            else:
     568                return op(self, self.from_float(other))
     569        else:
    501570            return NotImplemented
    502         if isinstance(diff, Rational):
    503             return op(diff.numerator, 0)
    504         return op(diff, 0)
    505571
    506572    def __lt__(a, b):
    507573        """a < b"""
    508         return a._subtractAndCompareToZero(b, operator.lt)
     574        return a._richcmp(b, operator.lt)
    509575
    510576    def __gt__(a, b):
    511577        """a > b"""
    512         return a._subtractAndCompareToZero(b, operator.gt)
     578        return a._richcmp(b, operator.gt)
    513579
    514580    def __le__(a, b):
    515581        """a <= b"""
    516         return a._subtractAndCompareToZero(b, operator.le)
     582        return a._richcmp(b, operator.le)
    517583
    518584    def __ge__(a, b):
    519585        """a >= b"""
    520         return a._subtractAndCompareToZero(b, operator.ge)
     586        return a._richcmp(b, operator.ge)
    521587
    522588    def __nonzero__(a):
Note: See TracChangeset for help on using the changeset viewer.