Dmitry Vakhrushev avatar Dmitry Vakhrushev committed eabb616 Draft

Added fake coroutine null

Comments (0)

Files changed (4)

 
 build
 dist
+manage
 *.egg-info
 *.pyc
 *.sublime-*

copipes/__init__.py

 from sys import version_info
 
 
-__all__ = ['coroutine', 'pipeline']
+__all__ = ['coroutine', 'pipeline', 'null']
 __version__ = '0.1'
 __author__ = 'Dmitry Vakhrushev <self@kr41.net>'
 __license__ = 'BSD'
 is2 = version_info[0] == 2
 
 
+class _null(object):
+    """
+    A fake coroutine, which does nothing
+
+    Is useful as pipeline end point or default value of next worker in
+    coroutine definition:
+
+    ..  code-block:: pycon
+
+        >>> @coroutine
+        ... def increment(next=null):
+        ...     while True:
+        ...         item = yield
+        ...         next.send(item + 1)
+
+    Is converted to boolean as ``False``:
+
+    ..  code-block:: pycon
+
+        >>> bool(null)
+        False
+        >>> next = null or increment
+        >>> next
+        increment
+
+    """
+
+    def __call__(self, *args, **kw):
+        """ Mimics to coroutine initialization """
+        return self
+
+    def __nonzero__(self):
+        """ Python 2.x boolean representation """
+        return False
+
+    def __bool__(self):
+        """ Python 3.x boolean representation """
+        return False
+
+    def __repr__(self):
+        """ String representation """
+        return 'null'
+
+    def send(self, *args, **kw):
+        """ Mimics to coroutine processing """
+        pass
+
+    def close(self):
+        """ Mimics to coroutine termination """
+        pass
+
+
+null = _null()
+
+
 class coroutine(object):
 
     def __init__(self, func):
         self.pipe = []
         self.connect(*workers)
 
-    def __call__(self, next=None):
-        next = next or null()
+    def __call__(self, next=null):
         for worker in reversed(self.pipe):
             next = worker(next)
         return next
             result.append('    -->')
             result.extend(' ' * 8 + wr for wr in repr(pipe).split(linesep))
         return linesep.join(result)
-
-
-@coroutine
-def null(*args):
-    while True:
-        yield
 
 from nose import tools
 
-from copipes import coroutine, pipeline
+from copipes import coroutine, pipeline, null
 
 
 @coroutine
         next.send(item)
 
 
+def null_test():
+    tools.ok_(not null)
+
+
 def coroutine_preserves_name_and_docstring_test():
     tools.eq_(add.__name__, 'add')
     tools.eq_(add.__doc__, ' Adds specified ``value`` to each'
 [nosetests]
-verbosity=3
+verbosity=2
 with-doctest=1
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.