@@ -183,7 +183,7 @@ class Fraction(numbers.Rational):
183183 __slots__ = ('_numerator' , '_denominator' )
184184
185185 # We're immutable, so use __new__ not __init__
186- def __new__ (cls , numerator = 0 , denominator = None , * , _normalize = True ):
186+ def __new__ (cls , numerator = 0 , denominator = None ):
187187 """Constructs a Rational.
188188
189189 Takes a string like '3/2' or '1.5', another Rational instance, a
@@ -279,12 +279,11 @@ def __new__(cls, numerator=0, denominator=None, *, _normalize=True):
279279
280280 if denominator == 0 :
281281 raise ZeroDivisionError ('Fraction(%s, 0)' % numerator )
282- if _normalize :
283- g = math .gcd (numerator , denominator )
284- if denominator < 0 :
285- g = - g
286- numerator //= g
287- denominator //= g
282+ g = math .gcd (numerator , denominator )
283+ if denominator < 0 :
284+ g = - g
285+ numerator //= g
286+ denominator //= g
288287 self ._numerator = numerator
289288 self ._denominator = denominator
290289 return self
@@ -301,7 +300,7 @@ def from_float(cls, f):
301300 elif not isinstance (f , float ):
302301 raise TypeError ("%s.from_float() only takes floats, not %r (%s)" %
303302 (cls .__name__ , f , type (f ).__name__ ))
304- return cls (* f .as_integer_ratio ())
303+ return cls . _from_coprime_ints (* f .as_integer_ratio ())
305304
306305 @classmethod
307306 def from_decimal (cls , dec ):
@@ -313,7 +312,19 @@ def from_decimal(cls, dec):
313312 raise TypeError (
314313 "%s.from_decimal() only takes Decimals, not %r (%s)" %
315314 (cls .__name__ , dec , type (dec ).__name__ ))
316- return cls (* dec .as_integer_ratio ())
315+ return cls ._from_coprime_ints (* dec .as_integer_ratio ())
316+
317+ @classmethod
318+ def _from_coprime_ints (cls , numerator , denominator , / ):
319+ """Convert a pair of ints to a rational number, for internal use.
320+
321+ The ratio of integers should be in lowest terms and the denominator
322+ should be positive.
323+ """
324+ obj = super (Fraction , cls ).__new__ (cls )
325+ obj ._numerator = numerator
326+ obj ._denominator = denominator
327+ return obj
317328
318329 def is_integer (self ):
319330 """Return True if the Fraction is an integer."""
@@ -380,9 +391,9 @@ def limit_denominator(self, max_denominator=1000000):
380391 # the distance from p1/q1 to self is d/(q1*self._denominator). So we
381392 # need to compare 2*(q0+k*q1) with self._denominator/d.
382393 if 2 * d * (q0 + k * q1 ) <= self ._denominator :
383- return Fraction (p1 , q1 , _normalize = False )
394+ return Fraction . _from_coprime_ints (p1 , q1 )
384395 else :
385- return Fraction (p0 + k * p1 , q0 + k * q1 , _normalize = False )
396+ return Fraction . _from_coprime_ints (p0 + k * p1 , q0 + k * q1 )
386397
387398 @property
388399 def numerator (a ):
@@ -703,13 +714,13 @@ def _add(a, b):
703714 nb , db = b ._numerator , b ._denominator
704715 g = math .gcd (da , db )
705716 if g == 1 :
706- return Fraction (na * db + da * nb , da * db , _normalize = False )
717+ return Fraction . _from_coprime_ints (na * db + da * nb , da * db )
707718 s = da // g
708719 t = na * (db // g ) + nb * s
709720 g2 = math .gcd (t , g )
710721 if g2 == 1 :
711- return Fraction (t , s * db , _normalize = False )
712- return Fraction (t // g2 , s * (db // g2 ), _normalize = False )
722+ return Fraction . _from_coprime_ints (t , s * db )
723+ return Fraction . _from_coprime_ints (t // g2 , s * (db // g2 ))
713724
714725 __add__ , __radd__ = _operator_fallbacks (_add , operator .add )
715726
@@ -719,13 +730,13 @@ def _sub(a, b):
719730 nb , db = b ._numerator , b ._denominator
720731 g = math .gcd (da , db )
721732 if g == 1 :
722- return Fraction (na * db - da * nb , da * db , _normalize = False )
733+ return Fraction . _from_coprime_ints (na * db - da * nb , da * db )
723734 s = da // g
724735 t = na * (db // g ) - nb * s
725736 g2 = math .gcd (t , g )
726737 if g2 == 1 :
727- return Fraction (t , s * db , _normalize = False )
728- return Fraction (t // g2 , s * (db // g2 ), _normalize = False )
738+ return Fraction . _from_coprime_ints (t , s * db )
739+ return Fraction . _from_coprime_ints (t // g2 , s * (db // g2 ))
729740
730741 __sub__ , __rsub__ = _operator_fallbacks (_sub , operator .sub )
731742
@@ -741,15 +752,17 @@ def _mul(a, b):
741752 if g2 > 1 :
742753 nb //= g2
743754 da //= g2
744- return Fraction (na * nb , db * da , _normalize = False )
755+ return Fraction . _from_coprime_ints (na * nb , db * da )
745756
746757 __mul__ , __rmul__ = _operator_fallbacks (_mul , operator .mul )
747758
748759 def _div (a , b ):
749760 """a / b"""
750761 # Same as _mul(), with inversed b.
751- na , da = a ._numerator , a ._denominator
752762 nb , db = b ._numerator , b ._denominator
763+ if nb == 0 :
764+ raise ZeroDivisionError ('Fraction(%s, 0)' % db )
765+ na , da = a ._numerator , a ._denominator
753766 g1 = math .gcd (na , nb )
754767 if g1 > 1 :
755768 na //= g1
@@ -761,7 +774,7 @@ def _div(a, b):
761774 n , d = na * db , nb * da
762775 if d < 0 :
763776 n , d = - n , - d
764- return Fraction (n , d , _normalize = False )
777+ return Fraction . _from_coprime_ints (n , d )
765778
766779 __truediv__ , __rtruediv__ = _operator_fallbacks (_div , operator .truediv )
767780
@@ -798,17 +811,17 @@ def __pow__(a, b):
798811 if b .denominator == 1 :
799812 power = b .numerator
800813 if power >= 0 :
801- return Fraction (a ._numerator ** power ,
802- a ._denominator ** power ,
803- _normalize = False )
804- elif a ._numerator >= 0 :
805- return Fraction (a ._denominator ** - power ,
806- a ._numerator ** - power ,
807- _normalize = False )
814+ return Fraction ._from_coprime_ints (a ._numerator ** power ,
815+ a ._denominator ** power )
816+ elif a ._numerator > 0 :
817+ return Fraction ._from_coprime_ints (a ._denominator ** - power ,
818+ a ._numerator ** - power )
819+ elif a ._numerator == 0 :
820+ raise ZeroDivisionError ('Fraction(%s, 0)' %
821+ a ._denominator ** - power )
808822 else :
809- return Fraction ((- a ._denominator ) ** - power ,
810- (- a ._numerator ) ** - power ,
811- _normalize = False )
823+ return Fraction ._from_coprime_ints ((- a ._denominator ) ** - power ,
824+ (- a ._numerator ) ** - power )
812825 else :
813826 # A fractional power will generally produce an
814827 # irrational number.
@@ -832,15 +845,15 @@ def __rpow__(b, a):
832845
833846 def __pos__ (a ):
834847 """+a: Coerces a subclass instance to Fraction"""
835- return Fraction (a ._numerator , a ._denominator , _normalize = False )
848+ return Fraction . _from_coprime_ints (a ._numerator , a ._denominator )
836849
837850 def __neg__ (a ):
838851 """-a"""
839- return Fraction (- a ._numerator , a ._denominator , _normalize = False )
852+ return Fraction . _from_coprime_ints (- a ._numerator , a ._denominator )
840853
841854 def __abs__ (a ):
842855 """abs(a)"""
843- return Fraction (abs (a ._numerator ), a ._denominator , _normalize = False )
856+ return Fraction . _from_coprime_ints (abs (a ._numerator ), a ._denominator )
844857
845858 def __int__ (a , _index = operator .index ):
846859 """int(a)"""
0 commit comments