Ticket #14159: trac_14159-document_callback_issue.patch

File trac_14159-document_callback_issue.patch, 2.7 KB (added by nbruin, 7 years ago)

Documentation to explain the problem (and possible future problems)

  • sage/categories/homset.py

    # HG changeset patch
    # User Nils Bruin <nbruin@sfu.ca>
    # Date 1361747496 28800
    # Node ID ebbbaa0cf36900a1c214527592489a4021547b0c
    # Parent  364089bc94692df23b65eda676e99929fdb4b93e
    #14159: Document that we're introducing a possible memory leak to save writing a very complicated callback. If this proves to be a problem, we'll know what to do
    
    diff --git a/sage/categories/homset.py b/sage/categories/homset.py
    a b def Hom(X, Y, category=None): 
    220220    except KeyError:
    221221        H = None
    222222    if H is not None:
    223         # Are domain or codomain breaking the unique parent condition?
    224         if H.domain() is X and H.codomain() is Y:
    225             return H
     223        # Note H has just been found using the identities of X and Y as
     224        # keys, so if the domain and codomain of H do not match by identity
     225        # something went wrong and we want to know about it.
     226        assert H.domain() is X and H.codomain() is Y
     227        return H
    226228
    227229    try:
    228230        # Apparently X._Hom_ is supposed to be cached
    def Hom(X, Y, category=None): 
    248250    except KeyError:
    249251        H = None
    250252    if H is not None:
    251         # Are domain or codomain breaking the unique parent condition?
    252         if H.domain() is X and H.codomain() is Y:
    253             return H
     253        # We double check domain and codomain are expected (see above)
     254        assert H.domain() is X and H.codomain() is Y
     255        return H
    254256
    255257    # coercing would be incredibly annoying, since the domain and codomain
    256258    # are totally different objects
    def Hom(X, Y, category=None): 
    261263    # For the moment, this is the category, for compatibility with the current implementations
    262264    # of Homset in rings, schemes, ...
    263265    H = category.hom_category().parent_class(X, Y, category = category)
    264            
     266   
     267    #Since H is holding strong references to X,Y,category in the form of
     268    #H.domain(), H.codomain(), H.homset_category(), the keyed reference below
     269    #should be OK: Even though X,Y,category are only weakly referenced by
     270    # _cache, they can't be garbage unless H is as well.
     271    #(the callback below isn't safe if _cache[key] would be able to get a
     272    #different value because H gets deallocated).
     273    #However, just to be safe, we prefer to risk leaving a dead reference
     274    #in _cache for now. Should this prove problematic in the future, we
     275    #can revisit this and equip the weak reference to H with a suitable callback
     276    #see trac #14159
     277    #_cache[key] = KeyedRef(H, _cache.eraser, (id(X),id(Y),id(category)))
    265278    _cache[key] = ref(H)
    266     ##_cache[key] = KeyedRef(H, _cache.eraser, (id(X),id(Y),id(category)))
    267279    return H
    268280
    269281def hom(X, Y, f):