Пример #1
0
 def test_exception(self):
     seen = []
     g1 = Fiber(target=fmain, args=(seen, ))
     g2 = Fiber(target=fmain, args=(seen, ))
     g1.switch()
     g2.switch()
     g2.parent = g1
     self.assertEqual(seen, [])
     self.assertRaises(SomeError, g2.switch)
     self.assertEqual(seen, [SomeError])
Пример #2
0
def send_exception(g, exc):
    # note: send_exception(g, exc)  can be now done with  g.throw(exc).
    # the purpose of this test is to explicitely check the propagation rules.
    def crasher(exc):
        raise exc
    g1 = Fiber(target=crasher, args=(exc, ), parent=g)
    g1.switch()
Пример #3
0
 def test_finished_parent(self):
     def f():
         return 42
     g = Fiber(f)
     g.switch()
     self.assertFalse(g.is_alive())
     self.assertRaises(ValueError, Fiber, parent=g)
Пример #4
0
    def __init__(self):
        if getattr(_tls, 'loop', None) is not None:
            raise RuntimeError(
                'cannot instantiate more than one event loop per thread')
        _tls.loop = self
        self._loop = pyuv.Loop()
        self._loop.excepthook = self._handle_error
        self._loop.event_loop = self
        self._threadpool = ThreadPool(self)
        self.task = Fiber(self._run_loop)

        self._destroyed = False
        self._started = False
        self._running = False

        self._fd_map = dict()
        self._signals = dict()
        self._timers = set()
        self._ready = deque()

        self._ready_processor = pyuv.Idle(self._loop)
        self._waker = pyuv.Async(self._loop, self._async_cb)
        self._waker.unref()

        self._install_signal_checker()
Пример #5
0
    def async (cls, func, *args, **kwargs):
        self = cls.get()

        def _f():
            func(*args, **kwargs)
            self._loop_fiber.switch()

        fb = Fiber(target=_f)
        self._fibers.append(fb)
Пример #6
0
 def f():
     try:
         raise ValueError('fun')
     except:
         exc_info = sys.exc_info()
         t = Fiber(h)
         t.switch()
         self.assertEqual(exc_info, sys.exc_info())
         del t
Пример #7
0
    def test_two_children(self):
        lst = []

        def f():
            lst.append(1)
            current().parent.switch()
            lst.extend([1, 1])
        g = Fiber(f)
        h = Fiber(f)
        g.switch()
        self.assertEqual(len(lst), 1)
        h.switch()
        self.assertEqual(len(lst), 2)
        h.switch()
        self.assertEqual(len(lst), 4)
        self.assertEqual(h.is_alive(), False)
        g.switch()
        self.assertEqual(len(lst), 6)
        self.assertEqual(g.is_alive(), False)
Пример #8
0
        def worker():
            # main and additional *finished* greenlets
            ll = current().ll = []

            def additional():
                ll.append(current())

            for i in range(2):
                Fiber(additional).switch()
            gg.append(weakref.ref(current()))
Пример #9
0
 def test_arg_refs(self):
     if not has_refcount:
         return
     args = ('a', 'b', 'c')
     refcount_before = sys.getrefcount(args)
     g = Fiber(target=lambda *x: None, args=args)
     self.assertEqual(sys.getrefcount(args), refcount_before + 1)
     g.switch()
     self.assertEqual(sys.getrefcount(args), refcount_before)
     del g
     self.assertEqual(sys.getrefcount(args), refcount_before)
Пример #10
0
 def test_kwarg_refs(self):
     if not has_refcount:
         return
     kwargs = {'a': 1234}
     refcount_before = sys.getrefcount(kwargs)
     g = Fiber(lambda **x: None, kwargs=kwargs)
     self.assertEqual(sys.getrefcount(kwargs), refcount_before + 1)
     g.switch()
     self.assertEqual(sys.getrefcount(kwargs), refcount_before)
     del g
     self.assertEqual(sys.getrefcount(kwargs), refcount_before)
Пример #11
0
    def test_throw_goes_to_original_parent(self):
        main = fibers.current()

        def f1():
            try:
                main.switch("f1 ready to catch")
            except IndexError:
                return "caught"
            else:
                return "normal exit"

        def f2():
            main.switch("from f2")

        g1 = Fiber(f1)
        g2 = Fiber(target=f2, parent=g1)
        self.assertRaises(IndexError, g2.throw, IndexError)
        self.assertFalse(g2.is_alive())
        self.assertTrue(
            g1.is_alive())  # g1 is skipped because it was not started
Пример #12
0
    def test_val(self):
        def f():
            try:
                switch("ok")
            except RuntimeError:
                val = sys.exc_info()[1]
                if str(val) == "ciao":
                    switch("ok")
                    return
            switch("fail")

        g = Fiber(f)
        res = g.switch()
        self.assertEqual(res, "ok")
        res = g.throw(RuntimeError("ciao"))
        self.assertEqual(res, "ok")

        g = Fiber(f)
        res = g.switch()
        self.assertEqual(res, "ok")
        res = g.throw(RuntimeError, "ciao")
        self.assertEqual(res, "ok")
Пример #13
0
    def test_throw_goes_to_original_parent2(self):
        main = fibers.current()

        def f1():
            try:
                main.switch("f1 ready to catch")
            except IndexError:
                return "caught"
            else:
                return "normal exit"

        def f2():
            main.switch("from f2")

        g1 = Fiber(f1)
        g2 = Fiber(target=f2, parent=g1)
        res = g1.switch()
        self.assertEqual(res, "f1 ready to catch")
        res = g2.throw(IndexError)
        self.assertEqual(res, "caught")
        self.assertFalse(g2.is_alive())
        self.assertFalse(g1.is_alive())
Пример #14
0
    def test_threaded_updatecurrent(self):
        # FIXME (hangs?)
        return
        # released when main thread should execute
        lock1 = threading.Lock()
        lock1.acquire()
        # released when another thread should execute
        lock2 = threading.Lock()
        lock2.acquire()

        class finalized(object):
            def __del__(self):
                # happens while in green_updatecurrent() in main greenlet
                # should be very careful not to accidentally call it again
                # at the same time we must make sure another thread executes
                lock2.release()
                lock1.acquire()
                # now ts_current belongs to another thread
        def deallocator():
            current().parent.switch()

        def fthread():
            lock2.acquire()
            current()
            del g[0]
            lock1.release()
            lock2.acquire()
            current()
            lock1.release()

        main = current()
        g = [Fiber(deallocator)]
        g[0].bomb = finalized()
        g[0].switch()
        t = threading.Thread(target=fthread)
        t.start()
        # let another thread grab ts_current and deallocate g[0]
        lock2.release()
        lock1.acquire()
        # this is the corner stone
        # getcurrent() will notice that ts_current belongs to another thread
        # and start the update process, which would notice that g[0] should
        # be deallocated, and that will execute an object's finalizer. Now,
        # that object will let another thread run so it can grab ts_current
        # again, which would likely crash the interpreter if there's no
        # check for this case at the end of green_updatecurrent(). This test
        # passes if getcurrent() returns correct result, but it's likely
        # to randomly crash if it's not anyway.
        self.assertEqual(current(), main)
        # wait for another thread to complete, just in case
        t.join()
Пример #15
0
    def test_simple2(self):
        lst = []

        def f():
            lst.append(1)
            current().parent.switch()
            lst.append(3)
        g = Fiber(f)
        lst.append(0)
        g.switch()
        lst.append(2)
        g.switch()
        lst.append(4)
        self.assertEqual(lst, list(range(5)))
Пример #16
0
    def test_class(self):
        def f():
            try:
                switch("ok")
            except RuntimeError:
                switch("ok")
                return
            switch("fail")

        g = Fiber(f)
        res = g.switch()
        self.assertEqual(res, "ok")
        res = g.throw(RuntimeError)
        self.assertEqual(res, "ok")
Пример #17
0
    def test_kill(self):
        def f():
            try:
                switch("ok")
                switch("fail")
            except Exception as e:
                return e

        g = Fiber(f)
        res = g.switch()
        self.assertEqual(res, "ok")
        res = g.throw(ValueError)
        self.assertTrue(isinstance(res, ValueError))
        self.assertFalse(g.is_alive())
Пример #18
0
    def test_two_recursive_children(self):
        lst = []

        def f():
            lst.append(1)
            current().parent.switch()

        def h():
            lst.append(1)
            i = Fiber(f)
            i.switch()
            lst.append(1)
        g = Fiber(h)
        g.switch()
        self.assertEqual(len(lst), 3)
Пример #19
0
    def test_exc_state(self):
        def f():
            try:
                raise ValueError('fun')
            except:
                exc_info = sys.exc_info()
                t = Fiber(h)
                t.switch()
                self.assertEqual(exc_info, sys.exc_info())
                del t

        def h():
            self.assertEqual(sys.exc_info(), (None, None, None))

        g = Fiber(f)
        g.switch()
Пример #20
0
 def test_instance_dict(self):
     if is_pypy:
         return
     def f():
         current().test = 42
     def deldict(g):
         del g.__dict__
     def setdict(g, value):
         g.__dict__ = value
     g = Fiber(f)
     self.assertEqual(g.__dict__, {})
     g.switch()
     self.assertEqual(g.test, 42)
     self.assertEqual(g.__dict__, {'test': 42})
     g.__dict__ = g.__dict__
     self.assertEqual(g.__dict__, {'test': 42})
     self.assertRaises(AttributeError, deldict, g)
     self.assertRaises(TypeError, setdict, g, 42)
Пример #21
0
    def do_async(cls, func, *args, **kwargs):
        """
        do coroutine asynchronously.

        Examples
        ---
        Server.do_async( lambda : Task.create(...) )

        Parameters
        ---
        tasks : list of Task
        callback : callable
        """
        self = cls._get()

        def _f():
            func(*args, **kwargs)
            self._loop_fiber.switch()

        fb = Fiber(target=_f)
        self._fibers.append(fb)
Пример #22
0
    def test_finalizer_crash(self):
        # This test is designed to crash when active greenlets
        # are made garbage collectable, until the underlying
        # problem is resolved. How does it work:
        # - order of object creation is important
        # - array is created first, so it is moved to unreachable first
        # - we create a cycle between a greenlet and this array
        # - we create an object that participates in gc, is only
        #   referenced by a greenlet, and would corrupt gc lists
        #   on destruction, the easiest is to use an object with
        #   a finalizer
        # - because array is the first object in unreachable it is
        #   cleared first, which causes all references to greenlet
        #   to disappear and causes greenlet to be destroyed, but since
        #   it is still live it causes a switch during gc, which causes
        #   an object with finalizer to be destroyed, which causes stack
        #   corruption and then a crash
        class object_with_finalizer(object):
            def __del__(self):
                pass

        array = []
        parent = current()

        def greenlet_body():
            current().object = object_with_finalizer()
            try:
                parent.switch()
            finally:
                del current().object

        g = Fiber(greenlet_body)
        g.array = array
        array.append(g)
        g.switch()
        del array
        del g
        current()
        gc.collect()
Пример #23
0
    def test_threaded_reparent(self):
        data = {}
        created_event = threading.Event()
        done_event = threading.Event()

        def foo():
            data['g'] = Fiber(lambda: None)
            created_event.set()
            done_event.wait()

        def blank():
            current().parent.switch()

        def setparent(g, value):
            g.parent = value

        thread = threading.Thread(target=foo)
        thread.start()
        created_event.wait()
        g = Fiber(blank)
        g.switch()
        self.assertRaises(ValueError, setparent, g, data['g'])
        done_event.set()
        thread.join()
Пример #24
0
 def test_deepcopy(self):
     self.assertRaises(TypeError, copy.copy, Fiber())
     self.assertRaises(TypeError, copy.deepcopy, Fiber())
Пример #25
0
 def test_inactive_ref(self):
     o = Fiber(lambda: None)
     o = weakref.ref(o)
     gc.collect()
     self.assertTrue(o() is None)
     self.assertFalse(gc.garbage, gc.garbage)
Пример #26
0
 def test_dead_circular_ref(self):
     o = weakref.ref(Fiber(current).switch())
     gc.collect()
     self.assertTrue(o() is None)
     self.assertFalse(gc.garbage, gc.garbage)
Пример #27
0
 def runner(x):
     g = Fiber(lambda: time.sleep(x))
     g.switch()
Пример #28
0
 def foo():
     data['g'] = Fiber(lambda: None)
     created_event.set()
     done_event.wait()
Пример #29
0
 def __enter__(self):
     self._loop_fiber = Fiber(target=self._loop)
Пример #30
0
 def creator():
     g = Fiber(worker)
     g.switch()
     result.append(g)