-
-
Notifications
You must be signed in to change notification settings - Fork 343
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
Path
refactor
#2959
Path
refactor
#2959
Conversation
d540052
to
80229df
Compare
Codecov ReportAll modified and coverable lines are covered by tests ✅
Additional details and impacted files@@ Coverage Diff @@
## master #2959 +/- ##
==========================================
- Coverage 99.64% 99.64% -0.01%
==========================================
Files 117 117
Lines 17643 17594 -49
Branches 3176 3171 -5
==========================================
- Hits 17581 17532 -49
Misses 43 43
Partials 19 19
|
80229df
to
0a78304
Compare
|
||
assert not hasattr(MockWrapper, "_private") | ||
|
||
|
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.
All of this can be removed, now we're not using metaclasses.
@@ -39,7 +39,7 @@ def sync_attrs(path: trio.Path) -> None: | |||
assert_type(path.drive, str) | |||
assert_type(path.root, str) | |||
assert_type(path.anchor, str) | |||
assert_type(path.parents[3], pathlib.Path) |
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 count this as a bugfix!
5776eaa
to
0dbda03
Compare
cb177d5
to
c12689a
Compare
c12689a
to
91bcaa6
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.
Questions about a few minor things
The error message is specifically about it being ambigious and could be inferred differently by other type checkers, so whether it's being inferred to the same thing by pyright is not really relevant. In most other cases we've resorted to doing the disgusting/bloated boilerplate to get around these errors, but I'll have a closer look later on whether I think it's worth it. We are after all running type checks on both mypy & pyright, so we can probably ignore it.
Maybe I should resuscitate #2910 and get the output-filtering script finished/merged. |
I think I'm disagreeing here with This is related to my point about the static visibility linter, really. This check seems to have a very uncompromising idea of what's ambiguous. The use of I'm a huge fan of static analysis tools in general, and favor very strict typing and linting. But to me, these checks feel overboard. I realize that this exactly the argument people make to me about strict I'm left in a bit of a quandry for this PR though. Hopefully you have a solution in mind with #2910. |
Also, apologies if the tone of my messages comes over as overly critical! I'm a big fan of how welcoming this project is to new contributors, so this stems from a concern about placing too-high barriers in front of new contributions. It's hard to express frustration without sounding... frustrated. 🥵 |
disagreeing with pyright seems very fair in this case, and given how complex the Path wrapping is already I'm open to just ignoring what |
One slightly interesting point https://trio--2959.org.readthedocs.build/en/2959/reference-io.html#trio.Path.link_to |
I'm assuming these docs were built not on Python 3.12? The method is indeed gone in 3.12. |
I've just had another look at this. Unfortunately,
The only solution I can see is the solution in #2910. Do we keep this open and wait for that to merge, or do we temporarily disable the check? |
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 forgot: could you add a newsfragment?
Also a couple comments, ranging from nitpicks to asking for a test or two
os.PathLike.register(Path) | ||
) -> AsyncIOWrapper[IO[Any]]: ... | ||
|
||
@_wraps_async(pathlib.Path.open) # type: ignore[misc] # Overload return mismatch. |
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.
If this is what I think it is (mismatch because we don't have overloads for "r"
vs "w"
vs whatever), then IMO this should have a TODO. I realize you didn't write this type ignore and just copied it over, but yeah.
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.
This is probably actually because we return an AsyncIOWrapper
, not the sync file.
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.
It's neither! It's Type of decorated function contains type "Any" ("Callable[[Path, str, int, Optional[str], Optional[str], Optional[str]], Coroutine[Any, Any, AsyncIOWrapper[IO[Any]]]]")
For some reason, using any in a decorated function is naughty. It's not naughty if the function isn't decorated though. 🤷
I'm sure specifically filtering pyright errors should be a pretty simple thing to do; let's wait a few days and see if that happens. If it doesn't, then temporarily disabling the check sounds good. (I'm hoping we can get a release out in ~a week, so that this and a bunch of changes can go out) |
Perhaps we should open an issue for Pyright. Thinking about it, it seems like a bug that |
d73c26a
to
8b47648
Compare
8b47648
to
819ea33
Compare
Hopefully that's all points addressed! Some directly, others laterally. |
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.
Looks good, I like that this decreases the total amount of code!
(hopefully someone else can also give this a lookover because my passes might have missed something)
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.
Looks pretty good other than one thing I noticed
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.
Very nice!
pyright changes are merged, you should be able to |
I added some logic to ignore everything instead of listing all the errors in the json. I feel like |
It's in! Thanks all! |
Thank you! And sorry for the delay with finishing up #2910 :) |
fyi this went out in 0.25.0! |
This PR implements the proposed refactor in #2944. As well as fixing the Python 3.13 problems, it adds some cool new things! 😎
The big change 💥
trio.Path
now subclassespathlib.PurePath
!This means all the sync method forwarding can be completely removed!
Since it now fits into the
pathlib
class hierarchy, it can be used interchangeably with other pure paths and methods that take pure paths. This also has the nice effect of making the wrapped async methods just work with regard to input types.It's also now a non-virtual subclass of
os.PathLike[str]
, which might help some static analysis tools...?Two concrete subclasses
PosixPath
andWindowsPath
also now exist, matching howpathlib
does things. Instantiating aPath
actually gets you the appropriate one for the platform, just likepathlib
.The medium change
Async method wrapping is now explicit, fixing Python 3.13. There are three high-level wrapper helpers that work for most cases (
_wrap_method
,_wrap_method_path
and_wrap_method_path_iterable
). For methods that don't fit into these, a low-level (_wraps_async
) is used.Other changes
Path
is now slotted, to matchpathlib
. A minor speed boost, with luck!Fixing Python 3.13
Unlike #2955, this fix actually works! Check it out:
My battle with
pyright --verifytypes
😭The
pyright --verifytypes
check does not like this syntax:It claims this is an ambiguous type, asking me to annotate it with something that can't be expressed with the Python type system except for a per-method unweildy protocol!
The workaround would be to put in a dummy method and use a decorator syntax, which
pyright
thinks is absolutely okay despite inferring to exactly the same thing! It's also pretty disgusting to look at, and bloats the implementation with boilerplate.I can't see any way to disable this check for just this file, or just these lines. Any suggestions?! 😭