Skip to content

Commit

Permalink
Revert "feat: remove deprecated ASyncIterable.wrap method (#314)" (#…
Browse files Browse the repository at this point in the history
…318)

This reverts commit ccdd23b.
  • Loading branch information
BobTheBuidler authored Sep 6, 2024
1 parent 9255a64 commit dd3b0d4
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 9 deletions.
13 changes: 6 additions & 7 deletions a_sync/iter.py
Original file line number Diff line number Diff line change
Expand Up @@ -101,17 +101,17 @@ class ASyncIterable(_AwaitableAsyncIterableMixin[T], Iterable[T]):
The class achieves this by implementing both `__iter__` and `__aiter__` methods, enabling it to return appropriate iterator objects that can handle synchronous and asynchronous iteration, respectively. This dual functionality is particularly useful in codebases that are transitioning between synchronous and asynchronous code, or in libraries that aim to support both synchronous and asynchronous usage patterns without requiring the user to manage different types of iterable objects.
"""

@classmethod
def wrap(cls, wrapped: AsyncIterable[T]) -> "ASyncIterable[T]":
"Class method to wrap an AsyncIterable for backward compatibility."
logger.warning("ASyncIterable.wrap will be removed soon. Please replace uses with simple instantiation ie `ASyncIterable(wrapped)`")
return cls(wrapped)
def __init__(self, async_iterable: AsyncIterable[T]):
"""
Initializes the ASyncIterable with an async iterable.
"""
"Initializes the ASyncIterable with an async iterable."
if not isinstance(async_iterable, AsyncIterable):
raise TypeError(f"`async_iterable` must be an AsyncIterable. You passed {async_iterable}")

self.__wrapped__ = async_iterable
"The wrapped async iterable object."

def __repr__(self) -> str:
return f"<{type(self).__name__} for {self.__wrapped__} at {hex(id(self))}>"

Expand All @@ -122,7 +122,6 @@ def __aiter__(self) -> AsyncIterator[T]:
def __iter__(self) -> Iterator[T]:
"Returns an iterator for the wrapped async iterable."
yield from ASyncIterator(self.__aiter__())

__slots__ = "__wrapped__",

AsyncGenFunc = Callable[P, Union[AsyncGenerator[T, None], AsyncIterator[T]]]
Expand Down
43 changes: 41 additions & 2 deletions tests/test_iter.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,12 +38,13 @@ async def async_err_gen():


@test_both
def test_init(cls_to_test, async_generator):
def test_wrap_types(cls_to_test, async_generator):
assert isinstance(cls_to_test(async_generator()), cls_to_test)
assert isinstance(cls_to_test.wrap(async_generator()), cls_to_test)

@test_both
def test_sync(cls_to_test, async_generator):
# sourcery skip: for-append-to-extend, identity-comprehension, list-comprehension, simplify-generator
# sourcery skip: identity-comprehension, list-comprehension
# comprehension
assert [i for i in cls_to_test(async_generator())] == [0, 1, 2]

Expand All @@ -53,11 +54,15 @@ def test_sync(cls_to_test, async_generator):
result.append(item)
assert result == [0, 1, 2]

# wrap
assert list(cls_to_test.wrap(async_generator())) == [0, 1, 2]

# list
assert list(cls_to_test(async_generator())) == [0, 1, 2]

# helper method
assert cls_to_test(async_generator()).materialized == [0, 1, 2]
assert cls_to_test.wrap(async_generator()).materialized == [0, 1, 2]

@test_both
@pytest.mark.asyncio_cooperative
Expand All @@ -81,6 +86,10 @@ async def test_async(cls_to_test, async_generator):
# await
assert await cls_to_test(async_generator()) == [0, 1, 2]

# wrap
assert [i async for i in cls_to_test.wrap(async_generator())] == [0, 1, 2]
assert await cls_to_test.wrap(async_generator()) == [0, 1, 2]


@test_both
def test_sync_empty(cls_to_test, async_generator_empty):
Expand Down Expand Up @@ -153,6 +162,20 @@ async def test_stop_iteration_async(cls_to_test, async_generator):

# Test decorator

def test_aiterable_decorated_func_sync():
with pytest.raises(TypeError, match="`async_iterable` must be an AsyncIterable. You passed "):
@ASyncIterable.wrap
async def decorated():
yield 0

@pytest.mark.asyncio_cooperative
async def test_aiterable_decorated_func_async(async_generator):
with pytest.raises(TypeError, match="`async_iterable` must be an AsyncIterable. You passed "):
@ASyncIterable.wrap
async def decorated():
yield 0


def test_aiterator_decorated_func_sync(async_generator):
@ASyncIterator.wrap
async def decorated():
Expand All @@ -173,6 +196,22 @@ async def decorated():
assert await retval == [0, 1, 2]


def test_aiterable_decorated_method_sync():
with pytest.raises(TypeError, match=""):
class Test:
@ASyncIterable.wrap
async def decorated(self):
yield 0

@pytest.mark.asyncio_cooperative
async def test_aiterable_decorated_method_async():
with pytest.raises(TypeError, match=""):
class Test:
@ASyncIterable.wrap
async def decorated(self):
yield 0


def test_aiterator_decorated_method_sync(async_generator):
class Test:
@ASyncIterator.wrap
Expand Down

0 comments on commit dd3b0d4

Please sign in to comment.