Skip to content
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

Add stubs for wrapped methods to trio.Path, add tests for mypy seeing exported symbols, and test for seeing class members #2631

Conversation

jakkdl
Copy link
Member

@jakkdl jakkdl commented Apr 12, 2023

For #2630

@jakkdl jakkdl force-pushed the static_check_mypy_and_class_members_and_fix_path branch 2 times, most recently from adf17df to c5b52e4 Compare April 12, 2023 12:58
@codecov
Copy link

codecov bot commented Apr 12, 2023

Codecov Report

Merging #2631 (c6ac460) into master (1a7a9c5) will decrease coverage by 1.59%.
The diff coverage is 62.50%.

Additional details and impacted files
@@            Coverage Diff             @@
##           master    #2631      +/-   ##
==========================================
- Coverage   92.43%   90.84%   -1.59%     
==========================================
  Files         118      118              
  Lines       16352    16387      +35     
  Branches     2945     1309    -1636     
==========================================
- Hits        15115    14887     -228     
- Misses       1124     1358     +234     
- Partials      113      142      +29     
Impacted Files Coverage Δ
trio/tests/test_exports.py 75.51% <57.64%> (-21.68%) ⬇️
trio/_path.py 100.00% <100.00%> (ø)

... and 47 files with indirect coverage changes

trio/_path.py Show resolved Hide resolved
@jakkdl jakkdl force-pushed the static_check_mypy_and_class_members_and_fix_path branch from c5b52e4 to 8b6c935 Compare April 13, 2023 13:21
trio/_path.py Outdated Show resolved Hide resolved
@jakkdl jakkdl force-pushed the static_check_mypy_and_class_members_and_fix_path branch 2 times, most recently from ab12518 to be5d3c2 Compare April 14, 2023 18:49
@jakkdl jakkdl marked this pull request as ready for review April 14, 2023 18:53
@jakkdl jakkdl force-pushed the static_check_mypy_and_class_members_and_fix_path branch from be5d3c2 to f3f43d5 Compare April 14, 2023 19:09
@TeamSpen210
Copy link
Contributor

Actually, does trio want a dependency on typing_extensions? #2507 suggests not, so it'd be better to move the import into the if TYPE_CHECKING guard, then just unconditionally import from typing.

@jakkdl
Copy link
Member Author

jakkdl commented Apr 14, 2023

Actually, does trio want a dependency on typing_extensions? #2507 suggests not, so it'd be better to move the import into the if TYPE_CHECKING guard, then just unconditionally import from typing.

ah yes, good catch

@jakkdl jakkdl force-pushed the static_check_mypy_and_class_members_and_fix_path branch 2 times, most recently from 9f19367 to 1e0da49 Compare April 14, 2023 20:49
@jakkdl
Copy link
Member Author

jakkdl commented Apr 14, 2023

I should maybe spin up a virtual machine at some point so I can test windows stuff better lol

@jakkdl
Copy link
Member Author

jakkdl commented Apr 14, 2023

Huh, looks like pypy has different dunders? I'm guessing they can just be ignored.

  'trio.EndOfChannel': {'extra': {'__basicsize__',
                                 '__dictoffset__',
                                 '__itemsize__',
                                 '__sizeof__',
                                 '__weakrefoffset__'},
                       'missing': {'__unicode__'}},

Windows ones are failing due to path having a colon in C: which is easily worked around.

@TeamSpen210
Copy link
Contributor

Yeah those aren't relevant. __unicode__ would be Py2 remnants, PyPy mustn't have removed that yet. The rest are how the memory layout of the object is defined/exposed for introspection, which isn't something Python code should care about unless it's using ctypes or something.

@jakkdl jakkdl force-pushed the static_check_mypy_and_class_members_and_fix_path branch 2 times, most recently from 6f3fd88 to b1e32a8 Compare April 14, 2023 21:25
@Fuyukai
Copy link
Member

Fuyukai commented Apr 15, 2023

Truly incredible. Now we have the worst of both worlds: you have to type out all the wrapper declarations manually and you're testing that you even wrote out the wrapper declarations - and if we ever want to have real asynchronous file I/O all of this has to go anyway.

@A5rocks
Copy link
Contributor

A5rocks commented Apr 15, 2023

I think it's worth the effort to provide better autocomplete! (Sorry if I'm misinterpreting your tone!)

The test is just a continuation of what we already test -- just that we are checking that class members match and not just module members.

@jakkdl
Copy link
Member Author

jakkdl commented Apr 15, 2023

Truly incredible. Now we have the worst of both worlds: you have to type out all the wrapper declarations manually and you're testing that you even wrote out the wrapper declarations - and if we ever want to have real asynchronous file I/O all of this has to go anyway.

I could've implemented the class member check as making the export test more thorough, but was easier to just write a new one than modifying the old one to also do class members. So yes the tests are very much what's currently done already, except with one more tool and testing the public class methods that weren't.

_path.py is messy and ugly, I don't disagree with that, but it's the only class that requires this much of a mess, and it's not like the interface of pathlib.Path is gonna change anytime soon, so this shouldn't introduce any maintenance overhead or anything.

And it's not like I came up with this for nothing - I ran mypy on the current tests (cause typechecking the tests is a good way to get free tests for whether the types on trio is correct) and it failed whenever it did anything with trio.Path because the methods were invisible to it. So I fixed that, and wrote a test to see if any other classes were broken. /shrug

And I have absolutely no problem with all of this getting tossed out when systems are improved!

@jakkdl
Copy link
Member Author

jakkdl commented Apr 15, 2023

These last errors are confusing me (and then there's other problems currently untested that'll need adressing), but I think it boils down to dir(pathlib.Path) includes 'group', 'owner' and 'is_mount' on both win32 and not - but if you'd try calling them on win32 you'd get an error. And mypy solves that by saying they're not attributes of pathlib.Path if run with --platform=win32.
I thought that maybe dir(trio.Path) was bugged on win32 in listing them, but if pathlib.Path also does it then I guess it isn't really a bug - it's just mypy special-casing it and so the correct thing is to expect the current status quo with dir() and mypy not being the same, and special-case them in the tests.

@jakkdl jakkdl marked this pull request as draft April 16, 2023 09:03
@jakkdl jakkdl force-pushed the static_check_mypy_and_class_members_and_fix_path branch from b1e32a8 to bcb0b96 Compare April 17, 2023 12:34
@jakkdl
Copy link
Member Author

jakkdl commented Apr 17, 2023

Okay since getting the stubs correct for the path methods wasn't trivial, I'll postpone that to a different PR so this one can get merged.

@jakkdl jakkdl marked this pull request as ready for review April 17, 2023 12:35
@jakkdl jakkdl force-pushed the static_check_mypy_and_class_members_and_fix_path branch from bcb0b96 to 58c5649 Compare April 17, 2023 12:53
@jakkdl
Copy link
Member Author

jakkdl commented Apr 27, 2023

would somebody mind reviewing this? It's ready for merge unless there's any more comments.

@A5rocks
Copy link
Contributor

A5rocks commented Apr 27, 2023

I can check this out in a bit, also the new 3.12 dev errors are concerning (they're not cause you) and we gotta fix those!

@A5rocks
Copy link
Contributor

A5rocks commented May 1, 2023

Sorry, haven't gotten to this! Eventually I will, don't worry.

@A5rocks
Copy link
Contributor

A5rocks commented May 4, 2023

(just updating this branch based on master as that (should) fix the macos pypy-3.8-nightly cancellation and the formatting check)

Copy link
Contributor

@A5rocks A5rocks left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was telling myself not to nitpick too much but... Oops. If something feels like a nitpick, feel free to ignore it! (or if it's missing something too obvious, I guess)

trio/_path.py Outdated Show resolved Hide resolved
write_bytes: Any
write_text: Any

if sys.platform != "win32":
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be nice to be able to auto-generate this (read from relevant file in https://github.com/python/typeshed and change the types... like just stick an async in the right places and call it a day). I suppose that's all part of "how will we do this" that is the followup, so ignore this :^)

readlink: Any
if sys.version_info >= (3, 10):
hardlink_to: Any

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This line isn't the one I wanted to comment on, but I can't comment on it cause it's out of the diff github shows :(

Namely, the line that is os.PathLike.register(Path). Presumably we could subclass os.PathLike and that would help some typing stuff? I don't know though.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Definitely, register isn't going to be fully supported everywhere. It'd also be better to inherit to indicate that we provide string paths, not bytes. A little tricky though since it's only as of 3.9 that you could subscript PathLike:

if TYPE_CHECKING:
    _StrPathLike = os.PathLike[str]
else:
    _StrPathLike = os.PathLike
...
class Path(_StrPathLike):

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

let's leave that to a different PR that fully types trio.Path, can either continue with that in #2630 or open a different issue

trio/tests/test_exports.py Show resolved Hide resolved
trio/tests/test_exports.py Outdated Show resolved Hide resolved
trio/tests/test_exports.py Outdated Show resolved Hide resolved
trio/tests/test_exports.py Outdated Show resolved Hide resolved
trio/tests/test_exports.py Outdated Show resolved Hide resolved
trio/tests/test_exports.py Outdated Show resolved Hide resolved
trio/tests/test_exports.py Show resolved Hide resolved
@A5rocks A5rocks requested a review from TeamSpen210 May 5, 2023 00:32
@jakkdl
Copy link
Member Author

jakkdl commented May 5, 2023

Fixed all changes requested, except where noted. Good nitpicks @A5rocks! ❤️

@jakkdl jakkdl force-pushed the static_check_mypy_and_class_members_and_fix_path branch 2 times, most recently from 648cdfc to 10e7549 Compare May 6, 2023 12:21
Copy link
Contributor

@A5rocks A5rocks left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems great from a cursory glance, we can always make a bunch of followups!

@A5rocks A5rocks linked an issue May 15, 2023 that may be closed by this pull request
@jakkdl jakkdl force-pushed the static_check_mypy_and_class_members_and_fix_path branch from 10e7549 to d01f42e Compare May 16, 2023 10:23
@jakkdl jakkdl force-pushed the static_check_mypy_and_class_members_and_fix_path branch from f8646bb to c6ac460 Compare May 16, 2023 11:47
@jakkdl
Copy link
Member Author

jakkdl commented May 16, 2023

Okay I'm done fighting with codecov, merging!

@jakkdl jakkdl merged commit 855f5fd into python-trio:master May 16, 2023
@jakkdl jakkdl deleted the static_check_mypy_and_class_members_and_fix_path branch May 16, 2023 12:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Static tools doesn't see class members (at least for trio.Path)
4 participants