Ticket #12357: trac12357_reviewer.patch

File trac12357_reviewer.patch, 3.7 KB (added by jpflori, 8 years ago)

Reviewer patch

  • sage/categories/groupoid.pyx

    # HG changeset patch
    # User Jean-Pierre Flori <jean-pierre.flori@ssi.gouv.fr>
    # Date 1328873427 -3600
    # Node ID 25f1f8fd58bad620faf9f4351f8d6e48eb4fbef8
    # Parent  e602d29f510d92e2cf84ffa859930ad8929143dc
    #12357: Reviewer patch
    
    diff --git a/sage/categories/groupoid.pyx b/sage/categories/groupoid.pyx
    a b  
    3535    def __classcall__(cls, S):
    3636        """
    3737        In contrast to usual instances of
    38         :class:`~sage.structure.unique_representation.UniqueRepresentation`,
    39         the cache is implemented in the given argument.
    40        
     38        :class:`~sage.structure.unique_representation.UniqueRepresentation`
     39        for which :meth:`__classcall__` is a
     40        :class:`~sage.misc.cachefunc.cached_function`,
     41        here the cache is implemented in the given argument.
     42
    4143        In that way, no "external" strong references to the groupoid are created
    4244        by caching -- there only is a reference from ``Groupoid(G)`` to ``G``
    43         and from ``G`` to ``Groupoid(G)``, but Python's garbage collection can
     45        and from ``G`` to ``Groupoid(G)``, and Python's garbage collection can
    4446        easily deal with those circular references.
    4547
    4648        EXAMPLES::
     
    7375            sage: Groupoid(1)
    7476            Traceback (most recent call last):
    7577            ...
    76             TypeError: 1 must either allow attribute assignment or be instances of <type 'sage.structure.parent.Parent'>
     78            TypeError: 1 must either allow attribute assignment or be an instance of <type 'sage.structure.parent.Parent'>
    7779            sage: class A: pass
    7880            sage: a = A()
    7981            sage: Groupoid(a)
     
    8284            True
    8385
    8486        """
     87        # First try the cache
    8588        try:
    8689            return getattr(S, '_cached_'+cls.__name__)
    8790        except AttributeError:
    8891            pass
    89         cdef Parent G
    90         cdef dict D
     92
    9193        if S is None:
    9294            raise TypeError, "Groupoid of None is not defined"
    9395
     96        # Make sure pickling works
     97        # Copied from UniqueRepresentation.__classcall__
    9498        instance = type.__call__(cls, S)
    9599        assert(isinstance(instance,cls))
    96100        if instance.__class__.__reduce__ == UniqueRepresentation.__reduce__:
    97101            instance._reduction = (cls, (S,), {})
     102
     103        # Now try to store the Groupoid as an attribute
    98104        try:
    99105            setattr(S, '_cached_'+cls.__name__, instance)
    100106            return instance
    101107        except AttributeError:
    102108            pass
    103         if S is not None:
    104             try:
    105                 # Parents have a cpdef dict __cached_methods attribute, by #11115
    106                 G = S
    107                 if G is None:
    108                     raise ValueError
    109                 D = G.__cached_methods
    110                 if D is None:
    111                     D = G.__cached_methods = {}
    112                 D['_cached_'+cls.__name__] = instance
    113                 return instance
    114             except TypeError:
    115                 pass
    116         raise TypeError, "%s must either allow attribute assignment or be instances of %s"%(S, Parent)
     109
     110        # Last try: S should be a Parent
     111        cdef Parent G
     112        cdef dict D
     113        try:
     114            # Parents have a cpdef dict __cached_methods attribute, by #11115
     115            G = S
     116            if G is None:
     117                raise ValueError
     118            D = G.__cached_methods
     119            if D is None:
     120                D = G.__cached_methods = {}
     121            D['_cached_'+cls.__name__] = instance
     122            return instance
     123        except TypeError:
     124            pass
     125        raise TypeError, "%s must either allow attribute assignment or be an instance of %s"%(S, Parent)
    117126
    118127    def __init__(self, G = None):
    119128        """