-
-
Notifications
You must be signed in to change notification settings - Fork 286
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
AsyncGenerator → AsyncIterator #2381
Conversation
e86ee25
to
694af4b
Compare
I think a better type for these functions would be: async def list(self) -> AsyncIterator[str]: Most implementations probably won't need these functions to be async, but it's a more general type for some implementation that may need it. |
46dc84b
to
52e66c9
Compare
The roadmap defines the Store API as follows and should be updated: async def list(self) -> List[str]:
... # required for listable stores
async def list_prefix(self, prefix: str) -> List[str]:
... # required for listable stores
async def list_dir(self, prefix: str) -> List[str]:
... # required for listable stores
As for the return value, not sure why it changed from |
Sorry, I just missed the argument in the example, definitely we shouldn't drop it. My point was about returning |
Meanwhile, I tried to revert the return type from As for the |
It's definitely not a big deal, |
OK, let me try then. It's just that's I'll have to modify all child classes. |
844ccad
to
8d3ead3
Compare
src/zarr/storage/local.py
Outdated
if p.is_file(): | ||
yield str(p).replace(to_strip, "") | ||
allfiles = [str(p).replace(to_strip, "") for p in self.root.rglob("*") if p.is_file()] | ||
return (onefile for onefile in allfiles) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we don't want to materialize the full allfiles
list in memory. Can you use async for
instead? Here is an example of how you could do this:
from collections.abc import AsyncIterator
from abc import ABC, abstractmethod
class Foo(ABC):
@abstractmethod
async def foo(self) -> AsyncIterator[str]:
...
class Bar(Foo):
async def helper(self) -> AsyncIterator[str]:
raise ValueError("")
async def foo(self) -> AsyncIterator[str]:
return (x async for x in await self.helper())
This code should work and mypy successfully, and doesn't materialize the results of calling helper
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm a little bit lost here.
- What we have here are functions that yield. That's a generator. Why create an iterator?
- I'm afraid I don't have enough experience with
async
and no time to learn it in the short term. For example, I'm not even sure how to identify iterables and awaitables.
I suggest We keep AsyncGenerator
for now. What would be the benefit of an AsyncIterator
in this context?
8d3ead3
to
f2d2683
Compare
97d384a
to
2efe135
Compare
2efe135
to
a0b8bf0
Compare
1ae24a6
to
93ff6f2
Compare
5209fac
to
c90c23a
Compare
@DimitriPapadopoulos - are you planning to return to this? |
80c5fff
to
655a149
Compare
I tried briefly, but I cannot get typing to work after rebasing. I need to take a thorough look. |
655a149
to
56764da
Compare
56764da
to
8c48380
Compare
113e9cd
to
6c8dd5c
Compare
1a824a5
to
3fa0e1d
Compare
3fa0e1d
to
667ec8d
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm happy here (except for the requested docstring changes).
src/zarr/abc/store.py
Outdated
Notes | ||
----- | ||
This method should be async, | ||
`How to correctly specify type hints with AsyncGenerator and AsyncContextManager <https://stackoverflow.com/questions/68905848/how-to-correctly-specify-type-hints-with-asyncgenerator-and-asynccontextmanager>`_ | ||
explains why it is not. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd like to move this to a comment rather than the public docstring. Most implementations will inherit this and end users don't need to know about this implementation detail.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, I wasn't sure about it. I put it in the documentation because it documents an inconsistency in function signatures.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ideally, I would document this using something similar to disabling Pylint warning W0236:
# pylint: disable=invalid-overridden-method
Unfortunately there's no equivalent rule in ruff, as far as I can see.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks.
667ec8d
to
63b0438
Compare
63b0438
to
782bfa4
Compare
Fixes #2377.
See microsoft/pyright#4741.
TODO: