-
Notifications
You must be signed in to change notification settings - Fork 141
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
Provide conversion to and from pathlib.Path
in anyio.Path
#844
Comments
|
Type checkers like Mypy disagree though. |
What API gives such errors then? |
Are you getting errors at run time? |
On your point of API compatibility, unexpectedly passing Coercing the objects in the way you suggest results in type checking faults (under Mypy 1.13.0). |
You haven't answered either one of my questions yet. |
Any API could, for example: from anyio import Path as PathAnyio
from pathlib import Path
from tarfile import open as tarfile_open
def test_std(*, path_std: Path) -> None:
assert not path_std.exists()
with tarfile_open(name=path_std):
pass
def test_anyio(*, path_anyio: PathAnyio) -> None:
# Passes type check, but is incorrect since this path isn't awaited. https://github.com/python/mypy/issues/16069.
# One reason to avoid accepting either `Path` and `PathAnyio` as a single argument.
assert not path_anyio.exists()
# Works.
with tarfile_open(name=path_anyio):
pass
def main() -> None:
path_std = Path("test.tar")
path_anyio = PathAnyio("test.tar")
test_anyio(path_anyio=path_anyio)
test_anyio(path_anyio=path_std)
test_std(path_std=path_std)
test_std(path_std=path_anyio)
test_std(path_std=Path(path_anyio))
if __name__ == "__main__":
main()
Can you explain what you find badly designed about an API that doesn't conflate
I wrote this:
I don't see the relation with run-time you refer to. Mypy is a type checker, that analyses statically, i.e., not at run-time. |
Not duck typing sense. Stdlib APIs, for example, are defined in typeshed to accept path-like objects (
I'm trying to understand the extent of the problem you have with this (to see if it's a mypy-only issue). |
This is what I'm talking about passes mypy in strict mode): import asyncio.tasks
from pathlib import Path
import anyio
async def test_func(p: Path) -> None:
pass
if __name__ == "__main__":
path = anyio.Path("/foo")
asyncio.run(test_func(Path(path))) |
First, about the actual solution you proposed. It's nice that Then about the argument signature. We don't want to accept |
If you annotate a parameter as |
That |
That's a nice tidbit of documentation I would say. For the function signatures I find in our present product, I still don't want to use this since there's the risk of not checking for and handling the particulars of each class. |
Yeah, and that's why I opened this issue. To discuss this use case. A |
I'm not inclined to add any extra code without good reason. And not wanting to import something is definitely not a good reason. It doesn't increase memory footprint given that AnyIO already imports it. What's stopping you from doing |
I least write all my path-accepting APIs elsewhere to allow any |
We do import, of course, otherwise conversion wouldn't work. We favor |
How about aliasing the import then, like how you did it in your original post? |
Yes, that's what we do now. The need to import the clas(ses) across many files to convert is less ergonomical than a |
There is little "cost" per se - I just don't want to encourage the wrong kinds (IMHO) of design patterns. |
Speaking of which: is making |
What's the alternative then? Being
That sentence made no sense to me. What awaitable operation is performed on what, by what code? |
Things to check first
Feature description
There's a private attribute
_path
already.Use case
Can you please expose it, so that APIs expecting
pathlib.Path
objects can use them. Currently, I convertanyio.Path
objects to strings since it's most succinct, but that detracts from type safety and code base conventions.The text was updated successfully, but these errors were encountered: