Sfoglia il codice sorgente

pythonlib/pydispatch: more doc test for signal

git-svn-id: https://svn.osgeo.org/grass/grass/trunk@55342 15284696-431f-4ddb-bdfa-cd5b030d7da7
Vaclav Petras 12 anni fa
parent
commit
da11ac0cea
1 ha cambiato i file con 76 aggiunte e 5 eliminazioni
  1. 76 5
      lib/python/pydispatch/signal.py

+ 76 - 5
lib/python/pydispatch/signal.py

@@ -14,6 +14,12 @@ def _islambda(function):
 
 
     Should work on the most of Python implementations where name of lambda
     Should work on the most of Python implementations where name of lambda
     function is not unique.
     function is not unique.
+    
+    >>> mylambda = lambda x: x*x
+    >>> _islambda(mylambda)
+    True
+    >>> _islambda(_islambda)
+    False
     """
     """
     return isinstance(function, type(lambda: None)) and function.__name__== (lambda: None).__name__
     return isinstance(function, type(lambda: None)) and function.__name__== (lambda: None).__name__
 
 
@@ -37,7 +43,8 @@ class Signal(object):
     handler2: Hello
     handler2: Hello
 
 
     >>> import sys
     >>> import sys
-    >>> signal2.connect(lambda text: sys.stdout.write('lambda handler: %s\\n' % text))
+    >>> signal2.connect(lambda text:
+    ...                 sys.stdout.write('lambda handler: %s\\n' % text))
     >>> signal2.emit(text="Hi")
     >>> signal2.emit(text="Hi")
     handler2: Hi
     handler2: Hi
     lambda handler: Hi
     lambda handler: Hi
@@ -87,15 +94,79 @@ class Signal(object):
         dispatcher.connect(receiver=handler, signal=self, weak=weak)
         dispatcher.connect(receiver=handler, signal=self, weak=weak)
 
 
     def disconnect(self, handler, weak=True):
     def disconnect(self, handler, weak=True):
+        """
+        
+        >>> signal1 = Signal('signal1')
+        >>> import sys
+        >>> signal1.connect(sys.stdout.write)
+        >>> signal1.disconnect(sys.stdout.write)
+        >>> signal1.disconnect(sys.stdout.flush)  #doctest: +ELLIPSIS
+        Traceback (most recent call last):
+        DispatcherKeyError: 'No receivers found for signal <__main__.Signal object at 0x...> from sender _Any'
+        >>> signal1.disconnect(some_function)
+        Traceback (most recent call last):
+        NameError: name 'some_function' is not defined
+        >>> signal1.emit()
+        """
         dispatcher.disconnect(receiver=handler, signal=self, weak=weak)
         dispatcher.disconnect(receiver=handler, signal=self, weak=weak)
 
 
+    # TODO: remove args?, make it work for args?
     def emit(self, *args, **kwargs):
     def emit(self, *args, **kwargs):
+        """
+        >>> signal1 = Signal('signal1')
+        >>> def mywrite(text):
+        ...     print text
+        >>> signal1.connect(mywrite)
+        >>> signal1.emit(text='Hello')
+        Hello
+        >>> signal1.emit()
+        Traceback (most recent call last):
+        TypeError: mywrite() takes exactly 1 argument (0 given)
+        >>> signal1.emit('Hello')
+        Traceback (most recent call last):
+        TypeError: send() got multiple values for keyword argument 'signal'
+        """
         dispatcher.send(signal=self, *args, **kwargs)
         dispatcher.send(signal=self, *args, **kwargs)
 
 
-    def __call__(self, *arguments, **named):
-        if 'signal' in named:
-            del named['signal']
-        self.emit(*arguments, **named)
+    def __call__(self, *args, **kwargs):
+        """Allows to emit signal with function call syntax.
+
+        It allows to handle signal as a function or other callable object.
+        So, the signal can be in the list of fuctions or can be connected as
+        a handler for another signal.
+        However, it is strongly recommended to use emit method for direct
+        signal emitting.
+        The use of emit method is more explicit than the function call
+        and thus it it clear that we are using signal.
+
+        >>> signal1 = Signal('signal1')
+        >>> def mywrite(text):
+        ...     print text
+        >>> signal1.connect(mywrite)
+        >>> functions = [signal1, lambda text: mywrite(text + '!')]
+        >>> for function in functions:
+        ...     function(text='text')
+        text
+        text!
+
+        The other reason why the function call should not by used when it is
+        possible to use emit method is that this function does ugly hack to
+        enable calling as a signal handler. The signal parameter is deleted
+        when it is in named keyword arguments. As a consequence, when the
+        signal is emitted with the signal parameter (which is a very bad
+        name for parameter when using signals), the error is much more readable
+        when using emit than function call. Concluding remark is that
+        emit behaves more predictable.
+        >>> signal1.emit(signal='Hello')
+        Traceback (most recent call last):
+        TypeError: send() got multiple values for keyword argument 'signal'
+        >>> signal1(signal='Hello')
+        Traceback (most recent call last):
+        TypeError: mywrite() takes exactly 1 argument (0 given)
+        """
+        if 'signal' in kwargs:
+            del kwargs['signal']
+        self.emit(*args, **kwargs)
 
 
 
 
 if __name__ == '__main__':
 if __name__ == '__main__':