Ticket #14058: 14058-weak-binop-morphisms.patch

File 14058-weak-binop-morphisms.patch, 5.2 KB (added by robertwb, 9 years ago)
  • sage/categories/map.pxd

    # HG changeset patch
    # User Robert Bradshaw <robertwb@gmail.com>
    # Date 1360095789 28800
    # Node ID 51947b92c7a546d5ee5a96be316812cf40ac1397
    # Parent  b936e7334beb18eafcfc2e5533be7836da061900
    Remove strong references to parents used in binary operations in the coercion model.
    
    diff -r b936e7334beb -r 51947b92c7a5 sage/categories/map.pxd
    a b  
    22from sage.structure.element cimport Element
    33
    44cdef class Map(Element):
     5    cdef object __weakref__
    56    cdef Parent _domain
    67    cdef Parent _codomain
    78
  • sage/structure/coerce.pyx

    diff -r b936e7334beb -r 51947b92c7a5 sage/structure/coerce.pyx
    a b  
    8080
    8181import operator
    8282
     83from cpython.weakref cimport PyWeakref_GET_OBJECT, PyWeakref_NewRef
     84
    8385from sage_object cimport SageObject
    8486from sage.categories.map cimport Map
    8587import sage.categories.morphism
     
    228230        Now lets see what happens when we do a binary operations with
    229231        an integer and a rational::
    230232       
    231             sage: left_morphism, right_morphism = maps[ZZ, QQ]
    232             sage: print left_morphism
     233            sage: left_morphism_ref, right_morphism_ref = maps[ZZ, QQ]
     234            sage: print left_morphism_ref()
    233235            Natural morphism:
    234236              From: Integer Ring
    235237              To:   Rational Field
    236             sage: print right_morphism
     238            sage: print right_morphism_ref
    237239            None
    238240           
    239241        We can see that it coerces the left operand from an integer to a
     
    10631065            True
    10641066        """
    10651067        try:
    1066             return self._coercion_maps.get(R, S, None)
     1068            refs = self._coercion_maps.get(R, S, None)
     1069            if refs is None:
     1070                return None
     1071            R_map_ref, S_map_ref = refs
     1072            if R_map_ref is None:
     1073                S_map = <object>PyWeakref_GET_OBJECT(S_map_ref)
     1074                if S_map is not None:
     1075                    return None, S_map
     1076            elif S_map_ref is None:
     1077                R_map = <object>PyWeakref_GET_OBJECT(R_map_ref)
     1078                if R_map is not None:
     1079                    return R_map, None
     1080            else:
     1081                R_map = <object>PyWeakref_GET_OBJECT(R_map_ref)
     1082                S_map = <object>PyWeakref_GET_OBJECT(S_map_ref)
     1083                if R_map is not None and S_map is not None:
     1084                    return R_map, S_map
    10671085        except KeyError:
    1068             homs = self.discover_coercion(R, S)
    1069             if 0:
    1070                 # This breaks too many things that are going to change
    1071                 # in the new coercion model anyways.
    1072                 # COERCE TODO: Enable it then.
    1073                 homs = self.verify_coercion_maps(R, S, homs)
     1086            pass
     1087        homs = self.discover_coercion(R, S)
     1088        if 0:
     1089            # This breaks too many things that are going to change
     1090            # in the new coercion model anyways.
     1091            # COERCE TODO: Enable it then.
     1092            homs = self.verify_coercion_maps(R, S, homs)
     1093        else:
     1094            if homs is not None:
     1095                x_map, y_map = homs
     1096                if x_map is not None and not isinstance(x_map, Map):
     1097                    raise RuntimeError, "BUG in coercion model: coerce_map_from must return a Map"
     1098                if y_map is not None and not isinstance(y_map, Map):
     1099                    raise RuntimeError, "BUG in coercion model: coerce_map_from must return a Map"
     1100        if homs is None:
     1101            refs = None
     1102            swap = None
     1103        else:
     1104            R_map, S_map = homs
     1105            R_map_ref = None if R_map is None else PyWeakref_NewRef(R_map, None)
     1106            S_map_ref = None if S_map is None else PyWeakref_NewRef(S_map, None)
     1107            refs = R_map_ref, S_map_ref
     1108            if R_map is None and PY_TYPE_CHECK(S, Parent) and (<Parent>S).has_coerce_map_from(R):
     1109                swap = None, PyWeakref_NewRef((<Parent>S).coerce_map_from(R), None)
    10741110            else:
    1075                 if homs is not None:
    1076                     x_map, y_map = homs
    1077                     if x_map is not None and not isinstance(x_map, Map):
    1078                         raise RuntimeError, "BUG in coercion model: coerce_map_from must return a Map"
    1079                     if y_map is not None and not isinstance(y_map, Map):
    1080                         raise RuntimeError, "BUG in coercion model: coerce_map_from must return a Map"
    1081             if homs is None:
    1082                 swap = None
    1083             else:
    1084                 R_map, S_map = homs
    1085                 if R_map is None and PY_TYPE_CHECK(S, Parent) and (<Parent>S).has_coerce_map_from(R):
    1086                     swap = None, (<Parent>S).coerce_map_from(R)
    1087                 else:
    1088                     swap = S_map, R_map
    1089             self._coercion_maps.set(R, S, None, homs)
    1090             self._coercion_maps.set(S, R, None, swap)
     1111                swap = S_map_ref, R_map_ref
     1112        self._coercion_maps.set(R, S, None, refs)
     1113        self._coercion_maps.set(S, R, None, swap)
    10911114        return homs
    10921115       
    10931116    cpdef verify_coercion_maps(self, R, S, homs, bint fix=False):