Beispiel #1
0
    async def iter(self):
        async with self.running():
            # Common kwargs to all middleware handlers.
            kwargs = {"events": self}

            async with AsyncExitStack() as stack:
                enter = stack.enter_async_context
                agen = await enter(aitercontext(self.root()))

                # Construct the middleware pipeline.
                if self.batch_args:
                    agen = await enter(
                        aitercontext(
                            Take(*self.batch_args).handler(agen, **kwargs)))

                # User-provided middleware, which must handle and yield either single
                # events or a batch.
                for m in self.executor.processor.middleware:
                    agen = await enter(aitercontext(m.handler(agen, **kwargs)))

                # Acknowledgement handling.
                agen = await enter(aitercontext(Ack().handler(agen, **kwargs)))

                # Automatic deserialisation.
                if self.want == "records":
                    agen = await enter(
                        aitercontext(Deserialize().handler(agen, **kwargs)))

                # It begins.
                async for x in agen:
                    try:
                        yield x
                    except GeneratorExit:
                        logger.warning("events-iter-exit")
                        return
Beispiel #2
0
async def test_aitercontext(event_loop):
    async def agen():
        for x in range(5):
            await asyncio.sleep(1)
            yield x

    with event_loop.assert_cleanup():
        async with aitercontext(agen()) as safe_gen:
            it = iter(range(5))
            async for item in safe_gen:
                assert item == next(it)
        assert event_loop.steps == [1] * 5

        with pytest.raises(RuntimeError):
            await anext(safe_gen)

        with pytest.raises(RuntimeError):
            async with safe_gen:
                pass

    safe_gen = aitercontext(agen())
    with pytest.warns(UserWarning):
        await anext(safe_gen)

    with pytest.raises(TypeError):
        AsyncIteratorContext(None)

    with pytest.raises(TypeError):
        AsyncIteratorContext(safe_gen)
Beispiel #3
0
async def test_not_an_agen_in_aitercontext(event_loop):
    async with aitercontext(not_an_agen([1])) as safe_gen:
        async for item in safe_gen:
            assert item == 1

    with pytest.raises(ZeroDivisionError):
        async with aitercontext(not_an_agen([1])) as safe_gen:
            async for item in safe_gen:
                1/0
Beispiel #4
0
async def test_not_an_agen_in_aitercontext(event_loop):
    async with aitercontext(not_an_agen([1])) as safe_gen:
        async for item in safe_gen:
            assert item == 1

    with pytest.raises(ZeroDivisionError):
        async with aitercontext(not_an_agen([1])) as safe_gen:
            async for item in safe_gen:
                1 / 0
Beispiel #5
0
async def test_silence_exception_in_aitercontext(event_loop):
    async with aitercontext(silence_agen()) as safe_gen:
        async for item in safe_gen:
            assert item == 1
            1/0

    # Silencing a generator exit is forbidden
    with pytest.raises(GeneratorExit):
        async with aitercontext(silence_agen()) as safe_gen:
            async for _ in safe_gen:
                raise GeneratorExit
Beispiel #6
0
async def test_silence_exception_in_aitercontext(event_loop):
    async with aitercontext(silence_agen()) as safe_gen:
        async for item in safe_gen:
            assert item == 1
            1 / 0

    # Silencing a generator exit is forbidden
    with pytest.raises(GeneratorExit):
        async with aitercontext(silence_agen()) as safe_gen:
            async for _ in safe_gen:
                raise GeneratorExit
Beispiel #7
0
async def test_reraise_exception_in_aitercontext(event_loop):
    with pytest.raises(RuntimeError) as info:
        async with aitercontext(reraise_agen()) as safe_gen:
            async for item in safe_gen:
                assert item == 1
                1/0
    assert type(info.value.__cause__) is ZeroDivisionError

    with pytest.raises(RuntimeError) as info:
        async with aitercontext(reraise_agen()) as safe_gen:
            async for item in safe_gen:
                assert item == 1
                raise GeneratorExit
    assert type(info.value.__cause__) is GeneratorExit
Beispiel #8
0
async def test_reraise_exception_in_aitercontext(event_loop):
    with pytest.raises(RuntimeError) as info:
        async with aitercontext(reraise_agen()) as safe_gen:
            async for item in safe_gen:
                assert item == 1
                1 / 0
    assert type(info.value.__cause__) is ZeroDivisionError

    with pytest.raises(RuntimeError) as info:
        async with aitercontext(reraise_agen()) as safe_gen:
            async for item in safe_gen:
                assert item == 1
                raise GeneratorExit
    assert type(info.value.__cause__) is GeneratorExit
Beispiel #9
0
async def test_athrow_in_aitercontext(event_loop):
    async with aitercontext(agen()) as safe_gen:
        assert await safe_gen.__anext__() == 0
        with pytest.raises(ZeroDivisionError):
            await safe_gen.athrow(ZeroDivisionError())
        async for _ in safe_gen:
            assert False  # No more items
Beispiel #10
0
async def test_stuck_in_aitercontext(event_loop):
    with pytest.raises(RuntimeError) as info:
        async with aitercontext(stuck_agen()) as safe_gen:
            async for item in safe_gen:
                assert item == 1
                1 / 0
    assert "didn't stop after athrow" in str(info.value)

    with pytest.raises(RuntimeError) as info:
        async with aitercontext(stuck_agen()) as safe_gen:
            async for item in safe_gen:
                assert item == 1
                raise GeneratorExit
    # GeneratorExit relies on aclose, not athrow
    # The message is a bit different
    assert "async generator ignored GeneratorExit" in str(info.value)
Beispiel #11
0
async def test_simple_aitercontext(event_loop):

    async with aitercontext(agen()) as safe_gen:

        # Cannot enter twice
        with pytest.raises(RuntimeError):
            async with safe_gen:
                pass

        it = iter(range(5))
        async for item in safe_gen:
            assert item == next(it)
    assert event_loop.steps == [1] * 5

    # Exiting is idempotent
    await safe_gen.__aexit__(None, None, None)
    await safe_gen.aclose()

    with pytest.raises(RuntimeError):
        await anext(safe_gen)

    with pytest.raises(RuntimeError):
        async with safe_gen:
            pass

    with pytest.raises(RuntimeError):
        await safe_gen.athrow(ValueError())
Beispiel #12
0
async def test_stuck_in_aitercontext(event_loop):
    with pytest.raises(RuntimeError) as info:
        async with aitercontext(stuck_agen()) as safe_gen:
            async for item in safe_gen:
                assert item == 1
                1/0
    assert "didn't stop after athrow" in str(info.value)

    with pytest.raises(RuntimeError) as info:
        async with aitercontext(stuck_agen()) as safe_gen:
            async for item in safe_gen:
                assert item == 1
                raise GeneratorExit
    # GeneratorExit relies on aclose, not athrow
    # The message is a bit different
    assert "async generator ignored GeneratorExit" in str(info.value)
Beispiel #13
0
async def test_athrow_in_aitercontext(event_loop):
    async with aitercontext(agen()) as safe_gen:
        assert await safe_gen.__anext__() == 0
        with pytest.raises(ZeroDivisionError):
            await safe_gen.athrow(ZeroDivisionError())
        async for _ in safe_gen:
            assert False  # No more items
Beispiel #14
0
async def test_aitercontext_wrong_usage(event_loop):
    safe_gen = aitercontext(agen())
    with pytest.warns(UserWarning):
        await anext(safe_gen)

    with pytest.raises(TypeError):
        AsyncIteratorContext(None)

    with pytest.raises(TypeError):
        AsyncIteratorContext(safe_gen)
Beispiel #15
0
async def test_aitercontext_wrong_usage(event_loop):
    safe_gen = aitercontext(agen())
    with pytest.warns(UserWarning):
        await anext(safe_gen)

    with pytest.raises(TypeError):
        AsyncIteratorContext(None)

    with pytest.raises(TypeError):
        AsyncIteratorContext(safe_gen)
Beispiel #16
0
async def test_aitercontext(event_loop):
    async def agen():
        for x in range(5):
            await asyncio.sleep(1)
            yield x

    with event_loop.assert_cleanup():
        async with aitercontext(agen()) as safe_gen:
            it = iter(range(5))
            async for item in safe_gen:
                assert item == next(it)
        assert event_loop.steps == [1] * 5

        with pytest.raises(RuntimeError):
            await anext(safe_gen)

        with pytest.raises(RuntimeError):
            async with safe_gen:
                pass

        with pytest.raises(RuntimeError):
            await safe_gen.athrow(ValueError())

    with event_loop.assert_cleanup():
        async with aitercontext(agen()) as safe_gen:
            assert await safe_gen.__anext__() == 0
            with pytest.raises(ZeroDivisionError):
                await safe_gen.athrow(ZeroDivisionError())
            async for item in safe_gen:
                assert False  # No more items

    safe_gen = aitercontext(agen())
    with pytest.warns(UserWarning):
        await anext(safe_gen)

    with pytest.raises(TypeError):
        AsyncIteratorContext(None)

    with pytest.raises(TypeError):
        AsyncIteratorContext(safe_gen)
Beispiel #17
0
async def test_raise_in_aitercontext(event_loop):
    with pytest.raises(ZeroDivisionError):
        async with aitercontext(agen()) as safe_gen:
            async for _ in safe_gen:
                1 / 0

    with pytest.raises(ZeroDivisionError):
        async with aitercontext(agen()) as safe_gen:
            async for _ in safe_gen:
                pass
            1 / 0

    with pytest.raises(GeneratorExit):
        async with aitercontext(agen()) as safe_gen:
            async for _ in safe_gen:
                raise GeneratorExit

    with pytest.raises(GeneratorExit):
        async with aitercontext(agen()) as safe_gen:
            async for _ in safe_gen:
                pass
            raise GeneratorExit
Beispiel #18
0
async def test_raise_in_aitercontext(event_loop):
    with pytest.raises(ZeroDivisionError):
        async with aitercontext(agen()) as safe_gen:
            async for _ in safe_gen:
                1/0

    with pytest.raises(ZeroDivisionError):
        async with aitercontext(agen()) as safe_gen:
            async for _ in safe_gen:
                pass
            1/0

    with pytest.raises(GeneratorExit):
        async with aitercontext(agen()) as safe_gen:
            async for _ in safe_gen:
                raise GeneratorExit

    with pytest.raises(GeneratorExit):
        async with aitercontext(agen()) as safe_gen:
            async for _ in safe_gen:
                pass
            raise GeneratorExit
Beispiel #19
0
async def test_simple_aitercontext(event_loop):

    async with aitercontext(agen()) as safe_gen:
        it = iter(range(5))
        async for item in safe_gen:
            assert item == next(it)
    assert event_loop.steps == [1]*5

    # Exiting is idempotent
    await safe_gen.__aexit__(None, None, None)
    await safe_gen.aclose()

    with pytest.raises(RuntimeError):
        await anext(safe_gen)

    with pytest.raises(RuntimeError):
        async with safe_gen:
            pass

    with pytest.raises(RuntimeError):
        await safe_gen.athrow(ValueError())