@@ -130,9 +130,11 @@ cdef class Fraction:
130130    """  
131131    cdef _numerator
132132    cdef _denominator
133+     cdef Py_hash_t _hash
133134
134135    def  __cinit__ (self , numerator = 0 , denominator = None , _normalize = True ):
135136        cdef Fraction value
137+         self ._hash =  - 1 
136138        if  denominator is  None :
137139            if  type (numerator) is  int  or  type (numerator) is  long :
138140                self ._numerator =  numerator
@@ -508,25 +510,30 @@ cdef class Fraction:
508510
509511    def  __hash__  (self ):
510512        """ hash(self)""" 
511- 
512-         #  XXX since this method is expensive, consider caching the result 
513+          if   self ._hash ! =   - 1 : 
514+              return   self ._hash 
513515
514516        #  In order to make sure that the hash of a Fraction agrees
515517        #  with the hash of a numerically equal integer, float or
516518        #  Decimal instance, we follow the rules for numeric hashes
517519        #  outlined in the documentation.  (See library docs, 'Built-in
518520        #  Types').
519521
522+         cdef Py_hash_t result
520523        #  dinv is the inverse of self._denominator modulo the prime
521524        #  _PyHASH_MODULUS, or 0 if self._denominator is divisible by
522525        #  _PyHASH_MODULUS.
523526        dinv =  pow (self ._denominator, _PyHASH_MODULUS -  2 , _PyHASH_MODULUS)
524527        if  not  dinv:
525-             hash_  =  _PyHASH_INF
528+             result  =  _PyHASH_INF
526529        else :
527-             hash_ =  abs (self ._numerator) *  dinv %  _PyHASH_MODULUS
528-         result =  hash_ if  self  >=  0  else  - hash_
529-         return  - 2  if  result ==  - 1  else  result
530+             result =  abs (self ._numerator) *  dinv %  _PyHASH_MODULUS
531+         if  self ._numerator <  0 :
532+             result =  - result
533+             if  result ==  - 1 :
534+                 result =  - 2 
535+         self ._hash =  result
536+         return  result
530537
531538    def  __richcmp__ (a , b , int op ):
532539        if  op ==  Py_EQ:
0 commit comments