# Path: aiostream/aiter_utils.py
# def aiter(obj):
# def anext(obj):
# async def await_(obj):
# def async_(fn):
#     async def wrapper(*args, **kwargs):
# def is_async_iterable(obj):
# def assert_async_iterable(obj):
# def is_async_iterator(obj):
# def assert_async_iterator(obj):
#     def __init__(self, aiterator):
#     def __aiter__(self):
#     def __anext__(self):
#     async def __aenter__(self):
#     async def __aexit__(self, typ, value, traceback):
#     async def aclose(self):
#     async def athrow(self, exc):
# def aitercontext(aiterable, *, cls=AsyncIteratorContext):
# class AsyncIteratorContext(AsyncIterator):
#     _STANDBY = "STANDBY"
#     _RUNNING = "RUNNING"
#     _FINISHED = "FINISHED"
# 
# Path: aiostream/aiter_utils.py
# def anext(obj):
#     """Access anext magic method."""
#     assert_async_iterator(obj)
#     return obj.__anext__()
# 
# Path: aiostream/core.py
# def streamcontext(aiterable):
#     """Return a stream context manager from an asynchronous iterable.
# 
#     The context management makes sure the aclose asynchronous method
#     of the corresponding iterator has run before it exits. It also issues
#     warnings and RuntimeError if it is used incorrectly.
# 
#     It is safe to use with any asynchronous iterable and prevent
#     asynchronous iterator context to be wrapped twice.
# 
#     Correct usage::
# 
#         ait = some_asynchronous_iterable()
#         async with streamcontext(ait) as streamer:
#             async for item in streamer:
#                 <block>
# 
#     For streams objects, it is possible to use the stream method instead::
# 
#         xs = stream.count()
#         async with xs.stream() as streamer:
#             async for item in streamer:
#                 <block>
#     """
#     return aitercontext(aiterable, cls=Streamer)


import asyncio
from .aiter_utils import AsyncExitStack
from .aiter_utils import anext
from .core import streamcontext
                # to raise a `StopAsyncIteration`.
                except Exception:
                    pass
        finally:
            self._pending.discard(task)


class StreamerManager:
    def __init__(self):
        self.tasks = {}
        self.streamers = []
        self.group = TaskGroup()
        self.stack = AsyncExitStack()

    async def __aenter__(self):
        await self.stack.__aenter__()
        await self.stack.enter_async_context(self.group)
        return self

    async def __aexit__(self, *args):
        for streamer in self.streamers:
            task = self.tasks.pop(streamer, None)
            if task is not None:
                self.stack.push_async_callback(self.group.cancel_task, task)
            self.stack.push_async_exit(streamer)
        self.tasks.clear()
        self.streamers.clear()
        return await self.stack.__aexit__(*args)

    async def enter_and_create_task(self, aiter):

# Path: aiostream/aiter_utils.py
# def aiter(obj):
# def anext(obj):
# async def await_(obj):
# def async_(fn):
#     async def wrapper(*args, **kwargs):
# def is_async_iterable(obj):
# def assert_async_iterable(obj):
# def is_async_iterator(obj):
# def assert_async_iterator(obj):
#     def __init__(self, aiterator):
#     def __aiter__(self):
#     def __anext__(self):
#     async def __aenter__(self):
#     async def __aexit__(self, typ, value, traceback):
#     async def aclose(self):
#     async def athrow(self, exc):
# def aitercontext(aiterable, *, cls=AsyncIteratorContext):
# class AsyncIteratorContext(AsyncIterator):
#     _STANDBY = "STANDBY"
#     _RUNNING = "RUNNING"
#     _FINISHED = "FINISHED"
# 
# Path: aiostream/aiter_utils.py
# def anext(obj):
#     """Access anext magic method."""
#     assert_async_iterator(obj)
#     return obj.__anext__()
# 
# Path: aiostream/core.py
# def streamcontext(aiterable):
#     """Return a stream context manager from an asynchronous iterable.
# 
#     The context management makes sure the aclose asynchronous method
#     of the corresponding iterator has run before it exits. It also issues
#     warnings and RuntimeError if it is used incorrectly.
# 
#     It is safe to use with any asynchronous iterable and prevent
#     asynchronous iterator context to be wrapped twice.
# 
#     Correct usage::
# 
#         ait = some_asynchronous_iterable()
#         async with streamcontext(ait) as streamer:
#             async for item in streamer:
#                 <block>
# 
#     For streams objects, it is possible to use the stream method instead::
# 
#         xs = stream.count()
#         async with xs.stream() as streamer:
#             async for item in streamer:
#                 <block>
#     """
#     return aitercontext(aiterable, cls=Streamer)


# Path: aiostream/manager.py
import asyncio
from .aiter_utils import AsyncExitStack
from .aiter_utils import anext
from .core import streamcontext

                # to raise a `StopAsyncIteration`.
                except Exception:
                    pass
        finally:
            self._pending.discard(task)


class StreamerManager:
    def __init__(self):
        self.tasks = {}
        self.streamers = []
        self.group = TaskGroup()
        self.stack = AsyncExitStack()

    async def __aenter__(self):
        await self.stack.__aenter__()
        await self.stack.enter_async_context(self.group)
        return self

    async def __aexit__(self, *args):
        for streamer in self.streamers:
            task = self.tasks.pop(streamer, None)
            if task is not None:
                self.stack.push_async_callback(self.group.cancel_task, task)
            self.stack.push_async_exit(streamer)
        self.tasks.clear()
        self.streamers.clear()
        return await self.stack.__aexit__(*args)

    async def enter_and_create_task(self, aiter):

        streamer = streamcontext(aiter)