Ticket #715: trac715_optional_weakref.patch

File trac715_optional_weakref.patch, 9.6 KB (added by jpflori, 8 years ago)

Make use of weakrefs optional: off by default, on for coercion

  • sage/categories/action.pxd

    # HG changeset patch
    # User Jean-Pierre Flori <jean-pierre.flori@ssi.gouv.fr>
    # Date 1328879416 -3600
    # Node ID 5bc48828f8b11afe38a78e97494f616330290466
    # Parent  cd70dd22ca28927add3ba28eca28379bb89f4fe8
    #715: Make use of weakrefs for action optional: off by default, on for coercion
    
    diff --git a/sage/categories/action.pxd b/sage/categories/action.pxd
    a b  
    88    cdef S
    99    cdef bint _is_left
    1010    cdef op
     11    cdef bint _use_weakrefs
    1112    cdef underlying_set(self)
    1213    cpdef _call_(self, a, b)
    1314   
  • sage/categories/action.pyx

    diff --git a/sage/categories/action.pyx b/sage/categories/action.pyx
    a b  
    4545
    4646cdef class Action(Functor):
    4747   
    48     def __init__(self, G, S, bint is_left = 1, op=None):
     48    def __init__(self, G, S, bint is_left = 1, op=None,
     49                 bint use_weakrefs = False):
    4950        from groupoid import Groupoid
    5051        Functor.__init__(self, Groupoid(G), category(S))
     52        self._use_weakrefs = use_weakrefs
    5153        self.G = G
    52         self.S = ref(S)
     54        if self._use_weakrefs:
     55            self.S = ref(S)
     56        else:
     57            self.S = S
    5358        self._is_left = is_left
    5459        self.op = op
    5560       
     
    150155            RuntimeError: This action acted on a set that became garbage collected
    151156
    152157        """
    153         S = self.S()
    154         if S is None:
    155             raise RuntimeError, "This action acted on a set that became garbage collected"
    156         return S
     158        if self._use_weakrefs:
     159            return self.S()
     160        return self.S
    157161
    158162    def codomain(self):
    159        return self.underlying_set()
     163        return self.underlying_set()
    160164       
    161165    def domain(self):
    162166        return self.underlying_set()
     
    201205            # We must be in the case that parent(~a) == parent(a)
    202206            # so we can invert in call_c code below.
    203207            if (PY_TYPE_CHECK(G, Group) and G.is_multiplicative()) or G.is_field():
    204                 Action.__init__(self, G, action.underlying_set(), action._is_left)
     208                Action.__init__(self, G, action.underlying_set(), action._is_left, use_weakrefs=action._use_weakrefs)
    205209                self._action = action
    206210                return
    207211            else:
    208212                K = G._pseudo_fraction_field()
    209                 Action.__init__(self, K, action.underlying_set(), action._is_left)
     213                Action.__init__(self, K, action.underlying_set(), action._is_left, use_weakrefs=action._use_weakrefs)
    210214                self._action = action
    211215                return
    212216        except (AttributeError, NotImplementedError):
     
    246250              right_precomposition = homset.Hom(right_precomposition._codomain, right).natural_map() * right_precomposition
    247251            right = right_precomposition._domain
    248252        if action._is_left:
    249             Action.__init__(self, left, action.underlying_set(), 1)
     253            Action.__init__(self, left, action.underlying_set(), 1, use_weakrefs=action._use_weakrefs)
    250254        else:
    251             Action.__init__(self, right, action.underlying_set(), 0)
     255            Action.__init__(self, right, action.underlying_set(), 0, use_weakrefs=action._use_weakrefs)
    252256        self._action = action
    253257        self.left_precomposition = left_precomposition
    254258        self.right_precomposition = right_precomposition
  • sage/structure/coerce.pyx

    diff --git a/sage/structure/coerce.pyx b/sage/structure/coerce.pyx
    a b  
    13621362                    if is_inverse: a = ~a
    13631363                    if a is not None and PY_TYPE_CHECK(a, RightModuleAction):
    13641364                        # We want a new instance so that we don't alter the (potentially cached) original
    1365                         a = RightModuleAction(S, R)
     1365                        a = RightModuleAction(S, R, use_weakrefs=True)
    13661366                        a.is_inplace = 1
    13671367                    if is_inverse: a = ~a
    13681368                return a
  • sage/structure/coerce_actions.pyx

    diff --git a/sage/structure/coerce_actions.pyx b/sage/structure/coerce_actions.pyx
    a b  
    3939
    4040cdef class LAction(Action):
    4141    """Action calls _l_action of the actor."""
    42     def __init__(self, G, S):
    43         Action.__init__(self, G, S, True, operator.mul)
     42    def __init__(self, G, S, bint use_weakrefs = False):
     43        Action.__init__(self, G, S, True, operator.mul, use_weakrefs)
    4444    cpdef _call_(self, g, a):
    4545        return g._l_action(a)  # a * g
    4646
    4747
    4848cdef class RAction(Action):
    4949    """Action calls _r_action of the actor."""
    50     def __init__(self, G, S):
    51         Action.__init__(self, G, S, False, operator.mul)
     50    def __init__(self, G, S, bint use_weakrefs = False):
     51        Action.__init__(self, G, S, False, operator.mul, use_weakrefs)
    5252    cpdef _call_(self, a, g):
    5353        return g._r_action(a)  # g * a
    5454
     
    5959
    6060    cdef _codomain
    6161   
    62     def __init__(self, Parent G, S, is_left, bint check=True):
     62    def __init__(self, Parent G, S, is_left, bint check=True,
     63                 bint use_weakrefs = False):
    6364        """
    6465        TESTS::
    6566
     
    7778            Left action by Rational Field on Ring of integers modulo 6
    7879       
    7980        """
    80         Action.__init__(self, G, S, is_left, operator.mul)
     81        Action.__init__(self, G, S, is_left, operator.mul, use_weakrefs)
    8182        if check:
    8283            res = self.act(G.an_element(), S.an_element())
    8384            if res is None:
     
    201202    try:
    202203        # Elements defining _act_on_
    203204        if x._act_on_(y, X_on_left) is not None:
    204             return ActOnAction(X, Y, X_on_left, False)
     205            return ActOnAction(X, Y, X_on_left, False, use_weakrefs=True)
    205206    except CoercionException:
    206207        _record_exception()
    207208    if isinstance(Y, Parent):
    208209        try:
    209210            # Elements defining _acted_upon_
    210211            if x._acted_upon_(y, X_on_left) is not None:
    211                 return ActedUponAction(Y, X, not X_on_left, False)
     212                return ActedUponAction(Y, X, not X_on_left, False, use_weakrefs=True)
    212213        except CoercionException:
    213214            _record_exception()
    214215
    215216
    216217cdef class ModuleAction(Action):
    217218
    218     def __init__(self, G, S):
     219    def __init__(self, G, S, use_weakrefs = False):
    219220        """
    220221        This creates an action of an element of a module by an element of its
    221222        base ring. The simplest example to keep in mind is R acting on the
     
    253254            1/x
    254255
    255256        """
    256         Action.__init__(self, G, S, not PY_TYPE_CHECK(self, RightModuleAction), operator.mul)
     257        Action.__init__(self, G, S, not PY_TYPE_CHECK(self, RightModuleAction), operator.mul, use_weakrefs)
    257258        if not isinstance(G, Parent):
    258259            # only let Parents act
    259260            raise TypeError, "Actor must be a parent."
     
    425426
    426427cdef class IntegerMulAction(Action):
    427428
    428     def __init__(self, ZZ, M, is_left=True):
     429    def __init__(self, ZZ, M, is_left=True, bint use_weakrefs = False):
    429430        r"""
    430431        This class implements the action `n \cdot a = a + a + \cdots + a` via
    431432        repeated doubling.
     
    448449            from sage.structure.parent import Set_PythonType
    449450            ZZ = Set_PythonType(ZZ)
    450451        test = M.an_element() + (-M.an_element()) # make sure addition and negation is allowed
    451         Action.__init__(self, ZZ, M, is_left, operator.mul)
     452        Action.__init__(self, ZZ, M, is_left, operator.mul, use_weakrefs)
    452453
    453454    cpdef _call_(self, nn, a):
    454455        """
  • sage/structure/parent.pyx

    diff --git a/sage/structure/parent.pyx b/sage/structure/parent.pyx
    a b  
    16301630
    16311631            sage: class SymmetricGroupAction(sage.categories.action.Action):
    16321632            ...       "Act on a multivariate polynomial ring by permuting the generators."
    1633             ...       def __init__(self, G, M, is_left=True):
    1634             ...           sage.categories.action.Action.__init__(self, G, M, is_left, operator.mul)
     1633            ...       def __init__(self, G, M, is_left=True, use_weak_references=True):
     1634            ...           sage.categories.action.Action.__init__(self, G, M, is_left, operator.mul, use_weak_references)
    16351635            ...   
    16361636            ...       def _call_(self, g, a):
    16371637            ...           if not self.is_left():
     
    22552255                    R = action
    22562256                    _register_pair(self, R, "action") # to kill circular recursion
    22572257                    if self_on_left:
    2258                         action = LeftModuleAction(R, self) # self is acted on from right
     2258                        action = LeftModuleAction(R, self, use_weakrefs=True) # self is acted on from right
    22592259                    else:
    2260                         action = RightModuleAction(R, self) # self is acted on from left
     2260                        action = RightModuleAction(R, self, use_weakrefs=True) # self is acted on from left
    22612261                    ## The following two lines are disabled to prevent the following from working:
    22622262                    ## sage: x, y = var('x,y')
    22632263                    ## sage: parent(ZZ[x][y](1)*vector(QQ[y],[1,2]))
     
    23042304                    from sage.rings.integer_ring import ZZ
    23052305                    if S is ZZ and not self.has_coerce_map_from(ZZ):
    23062306                        from sage.structure.coerce_actions import IntegerMulAction
    2307                         action = IntegerMulAction(S, self, not self_on_left)
     2307                        action = IntegerMulAction(S, self, not self_on_left, use_weakrefs=True)
    23082308                        return action
    23092309                except (CoercionException, TypeError):
    23102310                    _record_exception()