Skip to content

Commit

Permalink
Merge branch 'cleanup-auto-aiter' into aclose-fixed-omnibus
Browse files Browse the repository at this point in the history
  • Loading branch information
graingert committed Apr 8, 2024
2 parents 8ed364c + 22cffd0 commit c9d61b7
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 7 deletions.
1 change: 1 addition & 0 deletions CHANGES.rst
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ Unreleased
- Use modern packaging metadata with ``pyproject.toml`` instead of ``setup.cfg``.
:pr:`1793`
- Use ``flit_core`` instead of ``setuptools`` as build backend.
- Avoid unclosed ``auto_aiter`` warnings. :pr:`1954`


Version 3.1.3
Expand Down
25 changes: 20 additions & 5 deletions src/jinja2/async_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@
from .utils import _PassArg
from .utils import pass_eval_context

if t.TYPE_CHECKING:
import typing_extensions as te

V = t.TypeVar("V")


Expand Down Expand Up @@ -67,15 +70,27 @@ async def auto_await(value: t.Union[t.Awaitable["V"], "V"]) -> "V":
return t.cast("V", value)


async def auto_aiter(
class _IteratorToAsyncIterator(t.Generic[V]):
def __init__(self, iterator: "t.Iterator[V]"):
self._iterator = iterator

def __aiter__(self) -> "te.Self":
return self

async def __anext__(self) -> V:
try:
return next(self._iterator)
except StopIteration as e:
raise StopAsyncIteration(e.value) from e


def auto_aiter(
iterable: "t.Union[t.AsyncIterable[V], t.Iterable[V]]",
) -> "t.AsyncIterator[V]":
if hasattr(iterable, "__aiter__"):
async for item in t.cast("t.AsyncIterable[V]", iterable):
yield item
return iterable.__aiter__()
else:
for item in iterable:
yield item
return _IteratorToAsyncIterator(iter(iterable))


async def auto_to_list(
Expand Down
8 changes: 6 additions & 2 deletions src/jinja2/compiler.py
Original file line number Diff line number Diff line change
Expand Up @@ -973,14 +973,18 @@ def visit_Block(self, node: nodes.Block, frame: Frame) -> None:
f"yield from context.blocks[{node.name!r}][0]({context})", node
)
else:
self.writeline("gen = context.blocks[{node.name!r}][0]({context})")
self.writeline("try:")
self.indent()
self.writeline(
f"{self.choose_async()}for event in"
f" context.blocks[{node.name!r}][0]({context}):",
f"{self.choose_async()}for event in gen:"
node,
)
self.indent()
self.simple_write("event", frame)
self.outdent()
self.outdent()
self.write_line(f"finally: {self.choose_async('await gen.aclose()', 'gen.close()')}")

self.outdent(level)

Expand Down

0 comments on commit c9d61b7

Please sign in to comment.