Esempio n. 1
0
    def testIsGeneratorOrComposed(self):
        def f():
            yield

        self.assertTrue(is_generator(f()))
        self.assertTrue(is_generator(compose(f())))
        self.assertFalse(is_generator(lambda: None))
        self.assertFalse(is_generator(None))
    def testIsGeneratorOrComposed(self):
        def f():
            yield

        self.assertTrue(is_generator(f()))
        self.assertTrue(is_generator(compose(f())))
        self.assertFalse(is_generator(lambda: None))
        self.assertFalse(is_generator(None))
Esempio n. 3
0
 def _callonce(self, observers, args, kwargs, seen):
     for observer in (o for o in observers if o not in seen):
         seen.add(observer)
         try:
             method = getattr(observer, self._message)
         except AttributeError:
             pass
         else:
             try:
                 try:
                     self.called.add(observer)
                     _ = methodResult = method(*args, **kwargs)
                 except (StopIteration, GeneratorExit):
                     c, v, t = exc_info()
                     handleNonGeneratorGeneratorExceptions(method, c, v, t.tb_next)
                 if is_generator(methodResult):
                     _ = yield methodResult
             except:
                 c, v, t = exc_info(); raise c, v, t.tb_next
             assert _ is None, "%s returned '%s'" % (methodOrMethodPartialStr(method), _)
         if isinstance(observer, Observable):
             try:
                 _ = yield self._callonce(observer._observers, args, kwargs, seen)
             except:
                 c, v, t = exc_info(); raise c, v, t.tb_next
             assert _ is None, "OnceMessage of %s returned '%s', but must always be None" % (self._observable, _)
Esempio n. 4
0
 def _callonce(self, observers, args, kwargs, done):
     for observer in (o for o in observers if o not in done):
         done.add(observer)
         try:
             method = getattr(observer, self._message)
         except AttributeError:
             pass
         else:
             try:
                 try:
                     _ = methodResult = method(*args, **kwargs)
                 except (StopIteration, GeneratorExit):
                     c, v, t = exc_info()
                     handleNonGeneratorGeneratorExceptions(
                         method, c, v, t.tb_next)
                 if is_generator(methodResult):
                     _ = yield methodResult
             except:
                 c, v, t = exc_info()
                 raise c, v, t.tb_next
             assert _ is None, "%s returned '%s'" % (
                 methodOrMethodPartialStr(method), _)
         if isinstance(observer, Observable):
             try:
                 _ = yield self._callonce(observer._observers, args, kwargs,
                                          done)
             except:
                 c, v, t = exc_info()
                 raise c, v, t.tb_next
             assert _ is None, "OnceMessage of %s returned '%s', but must always be None" % (
                 self._observable, _)
Esempio n. 5
0
    def _asProcess(g):
        if not is_generator(g):
            raise TypeError("asProcess() expects a generator, got %s" % repr(g))

        reactor = Reactor()  # Between creating and reactor.loop() there should be no statements that can raise exceptions (otherwise (epoll) fd-leaking occurs).
        wrapper(g, reactor)
        try:
            reactor.loop()
        except StopIteration, e:
            if e.args:
                return e.args[0]
Esempio n. 6
0
 def verifyMethodResult(self, method, result):
     assert is_generator(result), "%s should have resulted in a generator." % methodOrMethodPartialStr(method)
Esempio n. 7
0
 def verifyMethodResult(self, method, result):
     assert is_generator(
         result
     ), "%s should have resulted in a generator." % methodOrMethodPartialStr(
         method)
Esempio n. 8
0
def _compose(initial, stepping):
    """
    The method compose() allows program (de)composition with generators.  It enables calls like:
        retvat = yield otherGenerator(args)
    The otherGenerator may return values by:
        raise StopIteration(retvat, remaining data)
    Remaining data might be present if the otherGenerator consumes less than it get gets.  It must
    make this remaining data available to the calling generator by yielding it as shown.
    Most notably, compose enables catching exceptions:
        try:
            retvat = yield otherGenerator(args)
        except Exception:
            pass
    This will work as expected: it catches an exception thrown by otherGenerator.
    """
    generators = [initial]
    __callstack__ = generators  # make these visible to 'local()'
    messages = [None]
    exception = None
    while generators:
        generator = generators[-1]
        try:
            if exception:
                if exception[0] == GeneratorExit:
                    generator.close()
                    raise exception
                response = generator.throw(*exception)
                exception = None
            else:
                message = messages.pop(0)
                response = generator.send(message)
            if is_generator(response):
                generators.append(response)
                frame = response.gi_frame
                if cpython: assert frame, 'Generator is exhausted.'
                if cpython:
                    assert frame.f_lineno == frame.f_code.co_firstlineno, 'Generator already used.'
                try:
                    if stepping:
                        _ = yield Yield
                except BaseException:
                    exType, exValue, exTraceback = exc_info()
                    exception = (exType, exValue, exTraceback.tb_next)
                    continue
                if stepping:
                    assert _ is None, 'Cannot accept data when stepping. First send None.'
                messages.insert(0, None)
            elif (response is not None) or not messages:
                try:
                    message = yield response
                    assert message is None or response is None, 'Cannot accept data. First send None.'
                    messages.insert(0, message)
                except BaseException:
                    exType, exValue, exTraceback = exc_info()
                    exception = (exType, exValue, exTraceback.tb_next)
        except StopIteration, returnValue:
            exception = None
            generators.pop()
            retvals = returnValue.args
            if retvals:
                if retvals == ('', ):  #jython
                    retvals = (None, )
                messages[0:0] = retvals
            else:
                generators and messages.insert(0, None)
        except BaseException:
            generators.pop()
            exType, exValue, exTraceback = exc_info()
            exception = (exType, exValue, exTraceback.tb_next)
Esempio n. 9
0
def compose(initial, stepping=False):
    if not is_generator(initial):
        raise TypeError("compose() expects generator")
    return _compose(initial, stepping)
Esempio n. 10
0
def _compose(initial, stepping):
    """
    The method compose() allows program (de)composition with generators.  It enables calls like:
        retvat = yield otherGenerator(args)
    The otherGenerator may return values by:
        raise StopIteration(retvat, remaining data)
    Remaining data might be present if the otherGenerator consumes less than it get gets.  It must
    make this remaining data available to the calling generator by yielding it as shown.
    Most notably, compose enables catching exceptions:
        try:
            retvat = yield otherGenerator(args)
        except Exception:
            pass
    This will work as expected: it catches an exception thrown by otherGenerator.
    """
    generators = [initial]
    __callstack__ = generators # make these visible to 'local()'
    messages = [None]
    exception = None
    while generators:
        generator = generators[-1]
        try:
            if exception:
                if exception[0] == GeneratorExit:
                    generator.close()
                    raise exception
                response = generator.throw(*exception)
                exception = None
            else:
                message = messages.pop(0)
                response = generator.send(message)
            if is_generator(response):
                generators.append(response)
                frame = response.gi_frame
                if cpython: assert frame, 'Generator is exhausted.' 
                if cpython: assert frame.f_lineno == frame.f_code.co_firstlineno, 'Generator already used.' 
                try:
                    if stepping:
                        _ = yield Yield
                except BaseException:
                    exType, exValue, exTraceback = exc_info()
                    exception = (exType, exValue, exTraceback.tb_next)
                    continue
                if stepping: assert _ is None, 'Cannot accept data when stepping. First send None.'
                messages.insert(0, None)
            elif (response is not None) or not messages:
                try:
                    message = yield response
                    assert message is None or response is None, 'Cannot accept data. First send None.'
                    messages.insert(0, message)
                except BaseException:
                    exType, exValue, exTraceback = exc_info()
                    exception = (exType, exValue, exTraceback.tb_next)
        except StopIteration, returnValue:
            exception = None
            generators.pop()
            retvals = returnValue.args
            if retvals:
                if retvals == ('',): #jython
                    retvals = (None,)
                messages[0:0] = retvals
            else:
                generators and messages.insert(0, None)
        except BaseException:
            generators.pop()
            exType, exValue, exTraceback = exc_info()
            exception = (exType, exValue, exTraceback.tb_next)
Esempio n. 11
0
def compose(initial, stepping=False):
    if not is_generator(initial):
        raise TypeError("compose() expects generator")
    return _compose(initial, stepping)