-
Notifications
You must be signed in to change notification settings - Fork 1.5k
[red-knot] Case sensitive module resolver #16521
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
Conversation
|
edcb9e6
to
38e8267
Compare
dbde770
to
35d4ec7
Compare
499881a
to
2ef2590
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.
What a headache! Thank you for taking this on.
|
||
db.use_system(OsSystem::new(&root)); | ||
|
||
db.write_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.
This seems to rely on creating a parent directory, so why isn't it write_file_all
?
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.
See #16518 (comment)
Happy to change the naming if you prefer the consistency of having the _all
prefix everywhere.
|
||
let upper_case = SystemPathBuf::from(path.as_str().to_uppercase()); | ||
if &*upper_case == path { | ||
return CaseSensitivity::Unknown; |
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.
Does this mean that if someone on a case-sensitive file system happens to run red-knot from an all-caps CWD, they may observe a significant slowdown?
That's not likely to ever happen... but it's pretty weird/unpleasant behavior if it does happen.
Would an alternative be to try lower-casing in that scenario? Either all-lower or all-upper should be different from the the original 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.
What a headache!
I hope you referred to file systems and not my PR ;)
Yes. Another example is if you run Red Knot from a directory named /1234
where the upper and lower-case names are identical. The reason why I think this is extremely unlikely is because the code lower-cases the entire path and not just the last component. So /Users/micha/1234
would be converted to /USERS/MICHA/1234
and the test would still succeed.
We could extend the logic to also try current_exe
for which the casing should differ unless someone renames the red_knot
binary to 1234
... 🤷 The only downside this has is that Red Knot might be installed in your home directory (let's say that's case sensitive) and your project runs on a case-insensitive network drive. However, I'm not sure how much we should worry about this case because the best we can do here ultimately is an approximation (or make everything slower than it has to be in most projects).
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 hope you referred to file systems and not my PR ;)
Yes, file systems!
We could extend the logic to also try
current_exe
for which the casing should differ unless someone renames thered_knot
binary to1234
... 🤷 The only downside this has is that Red Knot might be installed in your home directory (let's say that's case sensitive) and your project runs on a case-insensitive network drive.
The same issue could occur if you run knot from a cwd on one filesystem and use --project
to check files on another one. In theory you could even have your project on one filesystem and your venv/site-packages on a different one.
Ultimately I am fine with however you want to handle this.
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'll leave it as is for now and plan to revisit it as part of the file watching on case insensitive systems work because, depending on which approach we take, falling back to Unknown
might no longer be an option (in which case a more precise inference is important).
2ef2590
to
a708fa1
Compare
|
* main: [red-knot] Use `try_call_dunder` for augmented assignment (#16717) [red-knot] Document current state of attribute assignment diagnostics (#16746) [red-knot] Case sensitive module resolver (#16521) [red-knot] Very minor simplification of the render tests (#16759) [syntax-errors] Unparenthesized assignment expressions in sets and indexes (#16404) ruff_db: add a new diagnostic renderer ruff_db: add `context` configuration red_knot: plumb through `DiagnosticFormat` to the CLI ruff_db: add concise diagnostic mode [syntax-errors] Star annotations before Python 3.11 (#16545) [syntax-errors] Star expression in index before Python 3.11 (#16544) Ruff 0.11.0 (#16723) [red-knot] Preliminary tests for typing.Final (#15917) [red-knot] fix: improve type inference for binary ops on tuples (#16725) [red-knot] Assignments to attributes (#16705) [`pygrep-hooks`]: Detect file-level suppressions comments without rul… (#16720) Fallback to requires-python in certain cases when target-version is not found (#16721)
Summary
This PR implements the first part of #16440. It ensures that Red Knot's module resolver is case sensitive on all systems.
This PR combines a few approaches:
canonicalize
on non-case-sensitive systems to get the real casing of a path. This works for as long as no symlinks or mapped network drives (the windowsE:\
is mapped to\\server\share
thingy). This is the same as what Pyright doesIt's worth noting that the file watching test that I added that renames
lib.py
toLib.py
currently doesn't pass on case-insensitive systems. Making it pass requires some more involved changes toFiles
. I plan to work on this next. There's the argument that landing this PR on its own isn't worth it without this issue being addressed. I think it's still a good step in the right direction even when some of the details on how and where the path case sensitive comparison is implemented.Test plan
I added multiple integration tests (including a failing one). I tested that the
case-sensitivity
detection works as expected on Windows, MacOS and Linux and that the fast-paths are taken accordingly.