Ejemplo n.º 1
0
def test_weakfuncref_method():
    class Thing(object):
        def method(self):
            return 'existent!'

        def __priv_method(self):
            return 'existent!'

        @classmethod
        def clsmethod(clsself):
            return 'existent!'

    t = Thing()

    gcd_methref = make_weakfuncref_that_will_get_gcd()
    methref = weakfuncref.WeakFunctionRef(t.method)
    privmethref = weakfuncref.WeakFunctionRef(t._Thing__priv_method)
    clsmethref = weakfuncref.WeakFunctionRef(t.clsmethod)

    assert gcd_methref.function() is None
    assert privmethref.function()() == 'existent!'
    assert methref.function()() == 'existent!'
    assert clsmethref.function()() == 'existent!'

    print(gcd_methref)
    print(methref)

    t = None

    assert methref.function() is None
    assert privmethref.function() is None
    assert clsmethref.function()() == 'existent!'
Ejemplo n.º 2
0
    def __init__(self, target, propNames, keyFunc, triggers):
        """Create a ``PropCache``.

        :arg target:    Target :class:`.HasProperties` instance whose
                        property values are to be cached.

        :arg propNames: Names of properties on the ``target`` to be cached

        :arg keyFunc:   Function which will be called whenever a trigger
                        property changes, to generate a suitable key to
                        use for cached property values.

        :arg triggers:  Sequence of ``(hasProps, propName)`` pairs, specifying
                        which property changes should trigger caching of
                        the ``target`` property values.
        """

        self.__name = '{}_{}'.format(type(self).__name__, id(self))
        self.__cache = {}
        self.__target = weakref.ref(target)
        self.__propNames = propNames
        self.__keyFunc = weakfuncref.WeakFunctionRef(keyFunc)
        self.__triggers = [(weakref.ref(tobj), tprop)
                           for (tobj, tprop) in triggers]

        for tobj, tprop in triggers:
            tobj.addListener(tprop,
                             self.__name,
                             self.__doCache,
                             immediate=True)
Ejemplo n.º 3
0
    def addAttributeListener(self, name, listener, weak=True, immediate=False):
        """Adds an attribute listener for this ``PropertyValue``. The
        listener callback function must accept the following arguments:

          - ``context``:   The context associated with this ``PropertyValue``.

          - ``attribute``: The name of the attribute that changed.

          - ``value``:     The new attribute value.

          - ``name``:      The name of this ``PropertyValue`` instance.

        :param name:      A unique name for the listener. If a listener with
                          the specified name already exists, it will be
                          overwritten.

        :param listener:  The callback function.

        :param weak:      If ``True`` (the default), a weak reference to the
                          callback function is used.

        :param immediate: If ``False`` (the default), the listener is called
                          immediately; otherwise, it is called via the
                          :attr:`queue`.
        """
        log.debug('Adding attribute listener on {}.{} ({}): {}'.format(
            self._context().__class__.__name__, self._name, id(self), name))

        if weak:
            listener = weakfuncref.WeakFunctionRef(listener)

        name = self.__saltListenerName(name)
        self._attributeListeners[name] = Listener(self, name, listener, True,
                                                  immediate)
Ejemplo n.º 4
0
def test_weakfuncref_function():
    def func():
        pass

    non_gcd_func = weakfuncref.WeakFunctionRef(func)
    gcd_func = make_weakfuncref_that_will_get_gcd()

    assert gcd_func.function() is None
    assert non_gcd_func.function() is func
Ejemplo n.º 5
0
    def __init__(self, name, callback, topic, runOnIdle):

        self.name = name

        # We use a WeakFunctionRef so we can refer to
        # both functions and class/instance methods
        self.__callback = weakfuncref.WeakFunctionRef(callback)
        self.topic      = topic
        self.runOnIdle  = runOnIdle
        self.enabled    = True
Ejemplo n.º 6
0
def make_weakfuncref_method_that_will_get_gcd():
    class Thing(object):
        def method(self):
            pass

    return weakfuncref.WeakFunctionRef(Thing.method)
Ejemplo n.º 7
0
def make_weakfuncref_that_will_get_gcd():
    def thefunc():
        pass

    return weakfuncref.WeakFunctionRef(thefunc)
Ejemplo n.º 8
0
    def addListener(self,
                    name,
                    callback,
                    overwrite=False,
                    weak=True,
                    immediate=False):
        """Adds a listener for this value.

        When the value changes, the listener callback function is called. The
        callback function must accept the following arguments:

          - ``value``:   The property value
          - ``valid``:   Whether the value is valid or invalid
          - ``context``: The context object passed to :meth:`__init__`.
          - ``name``:    The name of this ``PropertyValue`` instance.

        Listener names ``prenotify`` and ``postnotify`` are reserved - if
        either of these are passed in for the listener name, a :exc`ValueError`
        is raised.

        :param str name:  A unique name for this listener. If a listener with
                          the name already exists, a :exc`RuntimeError` will be
                          raised, or it will be overwritten, depending upon
                          the value of the ``overwrite`` argument.

        :param callback:  The callback function.

        :param overwrite: If ``True`` any previous listener with the same name
                          will be overwritten.

        :param weak:      If ``True`` (the default), a weak reference to the
                          callback function is retained, meaning that it
                          can be garbage-collected. If passing in a lambda or
                          inner function, you will probably want to set
                          ``weak`` to ``False``, in which case a strong
                          reference will be used.

        :param immediate: If ``False`` (the default), this listener will be
                          notified through the :class:`.CallQueue` - listeners
                          for all ``PropertyValue`` instances are queued, and
                          notified in turn. If ``True``, If ``True``, the
                          ``CallQueue`` will not be used, and this listener
                          will be notified as soon as this ``PropertyValue``
                          changes.
        """

        if name in ('prenotify', 'postnotify'):
            raise ValueError('Reserved listener name used: {}. '
                             'Use a different name.'.format(name))

        log.debug('Adding listener on {}.{}: {}'.format(
            self._context().__class__.__name__, self._name, name))

        fullName = self.__saltListenerName(name)
        prior = self._changeListeners.get(fullName, None)

        if weak:
            callback = weakfuncref.WeakFunctionRef(callback)

        if (prior is not None) and (not overwrite):
            raise RuntimeError('Listener {} already exists'.format(name))

        elif prior is not None:
            prior.function = callback
            prior.immediate = immediate

        else:
            self._changeListeners[fullName] = Listener(self, fullName,
                                                       callback, True,
                                                       immediate)