ruff/crates
Micha Reiser a467e7c8d3
[red-knot] Case sensitive module resolver (#16521)
## Summary

This PR implements the first part of
https://github.com/astral-sh/ruff/discussions/16440. It ensures that Red
Knot's module resolver is case sensitive on all systems.

This PR combines a few approaches:

1. It uses `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 windows `E:\` is mapped to `\\server\share` thingy).
This is the same as what Pyright does
2. If 1. fails, fall back to recursively list the parent directory and
test if the path's file name matches the casing exactly as listed in by
list dir. This is the same approach as CPython takes in its module
resolver. The main downside is that it requires more syscalls because,
unlike CPython, we Red Knot needs to invalidate its caches if a file
name gets renamed (CPython assumes that the folders are immutable).

It's worth noting that the file watching test that I added that renames
`lib.py` to `Lib.py` currently doesn't pass on case-insensitive systems.
Making it pass requires some more involved changes to `Files`. 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.
2025-03-14 19:16:44 +00:00
..
red_knot [red-knot] Case sensitive module resolver (#16521) 2025-03-14 19:16:44 +00:00
red_knot_project red_knot: plumb through DiagnosticFormat to the CLI 2025-03-14 14:46:17 -04:00
red_knot_python_semantic [red-knot] Case sensitive module resolver (#16521) 2025-03-14 19:16:44 +00:00
red_knot_server [red-knot] Case sensitive module resolver (#16521) 2025-03-14 19:16:44 +00:00
red_knot_test [red-knot] Case sensitive module resolver (#16521) 2025-03-14 19:16:44 +00:00
red_knot_vendored [red-knot] Add CallableTypeFromFunction special form (#16683) 2025-03-13 07:49:34 +05:30
red_knot_wasm [red-knot] Case sensitive module resolver (#16521) 2025-03-14 19:16:44 +00:00
ruff Ruff 0.11.0 (#16723) 2025-03-14 13:57:56 +01:00
ruff_annotate_snippets Update pre-commit dependencies (#16465) 2025-03-03 13:10:46 +05:30
ruff_benchmark [red-knot] Handle gradual intersection types in assignability (#16611) 2025-03-11 07:58:56 -07:00
ruff_cache Fix cache key collisions for paths with separators (#12159) 2024-07-03 07:36:46 -05:00
ruff_db [red-knot] Case sensitive module resolver (#16521) 2025-03-14 19:16:44 +00:00
ruff_dev Pass ParserOptions to the parser (#16220) 2025-02-19 10:50:50 -05:00
ruff_diagnostics Show errors for attempted fixes only when passed --verbose (#15237) 2025-01-03 08:50:13 -06:00
ruff_formatter bump MSRV to 1.83 (#16294) 2025-02-26 06:12:43 -08:00
ruff_graph Pass ParserOptions to the parser (#16220) 2025-02-19 10:50:50 -05:00
ruff_index [red-knot] Don't use separate ID types for each alist (#16415) 2025-02-28 14:55:55 -05:00
ruff_linter Ruff 0.11.0 (#16723) 2025-03-14 13:57:56 +01:00
ruff_macros Add knot.toml schema (#15735) 2025-02-07 10:59:40 +01:00
ruff_notebook bump MSRV to 1.83 (#16294) 2025-02-26 06:12:43 -08:00
ruff_python_ast [red-knot] Auto generate statement nodes (#16645) 2025-03-13 15:43:48 +01:00
ruff_python_ast_integration_tests Pass ParserOptions to the parser (#16220) 2025-02-19 10:50:50 -05:00
ruff_python_codegen Pass ParserOptions to the parser (#16220) 2025-02-19 10:50:50 -05:00
ruff_python_formatter [formatter] Stabilize fix for single-with-item formatting with trailing comment (#16603) 2025-03-13 15:37:37 +01:00
ruff_python_index Extract LineIndex independent methods from Locator (#13938) 2024-10-28 07:53:41 +00:00
ruff_python_literal Preserve triple quotes and prefixes for strings (#15818) 2025-02-04 08:41:06 -05:00
ruff_python_parser [syntax-errors] Unparenthesized assignment expressions in sets and indexes (#16404) 2025-03-14 15:06:42 -04:00
ruff_python_resolver bump MSRV to 1.83 (#16294) 2025-02-26 06:12:43 -08:00
ruff_python_semantic Consider all TYPE_CHECKING symbols for type-checking blocks (#16669) 2025-03-13 15:37:37 +01:00
ruff_python_stdlib Revert "Add all PEP-585 names to UP006 rule" (#15250) 2025-01-04 12:23:53 +01:00
ruff_python_trivia [red-knot] Ignore surrounding whitespace when looking for <!-- snapshot-diagnostics --> directives in mdtests (#16380) 2025-02-27 13:25:31 +00:00
ruff_python_trivia_integration_tests Pass ParserOptions to the parser (#16220) 2025-02-19 10:50:50 -05:00
ruff_server Fallback to requires-python in certain cases when target-version is not found (#16721) 2025-03-14 09:36:51 +01:00
ruff_source_file [pyupgrade] Do not report when a UTF-8 comment is followed by a non-UTF-8 one (UP009) (#14728) 2024-12-11 10:30:41 +00:00
ruff_text_size [ruff] itertools.starmap(..., zip(...)) (RUF058) (#15483) 2025-01-16 15:18:12 +01:00
ruff_wasm Ruff 0.11.0 (#16723) 2025-03-14 13:57:56 +01:00
ruff_workspace Fallback to requires-python in certain cases when target-version is not found (#16721) 2025-03-14 09:36:51 +01:00