-
Notifications
You must be signed in to change notification settings - Fork 1.2k
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
[red-knot] Anchor relative paths in configurations #15634
Conversation
545afe8
to
deba6f5
Compare
|
deba6f5
to
1dfa805
Compare
I did a coarse-grained review, but would like to understand the problem better before going into more detail. Let me try to rephrase what you wrote just to see if I understand this correctly: The core problem is with options like The approach you chose here is to attach that anchor to each and every path in the options struct, which leads to this slightly awkward solution with the thread-local because we create the options struct directly using serde. Another approach might be to store a global anchor next to the options struct that we get from a particular source. For the scenario above, we would then have something like (Sorry if this is basically what you meant with the alternative solution in the PR description) (Edit: the problem is even present for a config option with just a single path, not just with lists of paths) |
Your summary is accurate and yes, the problem is that options get combined from multiple sources so that arrays end up with values relative to different roots. What you describe is definetely possible and is roughly what Ruff does, except that it requires one extra representatios:
This separation has proven to be somewhat painful in Ruff because there's a lot of redundancy: Each structure roughly defines the same fields, only sometimes with slightly different types. There's a second problem that I only touched on in the summary: We want to validate the user configuration. Some of those validations are local to a single value and could be done when going from |
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.
Thank you — looks great!
I don't love the thread-local solution, but your reasoning makes sense — thank you for writing it down!
Neither do I :( It's a shame that there's no other solution for passing down state to serde. We'll face a similar problem when implementing the JSON schema for rules because the schema also doesn't allow passing down any additional data but we'll need access to the rule registry |
Is there a way to do it using |
Possibly. I didn't look too much into it, but it seems that you'd have to write your own |
If it's a pain, and the thread-local version is working, I'd say it's not worth it. |
* main: [red-knot] MDTests: Do not depend on precise public-symbol type inference (#15691) [red-knot] Make `infer.rs` unit tests independent of public symbol inference (#15690) Tidy knot CLI tests (#15685) [red-knot] Port comprehension tests to Markdown (#15688) Create Unknown rule diagnostics with a source range (#15648) [red-knot] Port 'deferred annotations' unit tests to Markdown (#15686) [red-knot] Support custom typeshed Markdown tests (#15683) Don't run the linter ecosystem check on PRs that only touch red-knot crates (#15687) Add `rules` table to configuration (#15645) [red-knot] Make `Diagnostic::file` optional (#15640) [red-knot] Add test for nested attribute access (#15684) [red-knot] Anchor relative paths in configurations (#15634) [`pyupgrade`] Handle multiple base classes for PEP 695 generics (`UP046`) (#15659) [`pyflakes`] Treat arguments passed to the `default=` parameter of `TypeVar` as type expressions (`F821`) (#15679) Upgrade zizmor to the latest version in CI (#15649) [`pyupgrade`] Add rules to use PEP 695 generics in classes and functions (`UP046`, `UP047`) (#15565) [red-knot] Ensure a gradual type can always be assigned to itself (#15675)
Summary
This PR adds support for relative paths in configurations and the CLI.
The challenge with relative paths is that they are relative to a different root based on where the configuration value comes from:
While Red Knot already supported relative paths from the CLI, it incorrecty
resolved relative paths in configuration files as relative to the current working directory.
This PR fixes this by implementing path anchoring. It introduces a new
RelativePath
type that weresolve to an absolute path when going from "raw"
Options
to a*Settings
struct.A
RelativePath
is a combination of the path and a source indicating the origin of the path. Thistuple allows resolving the absolute path when given the
project_root
andsystem
.I plan to generalize the value with a source in a follow up PR where we also start
tracking the source span for every value to enable rich diagnostics for configuration errors.
Part of #15491
Alternatives
An alternative to using the
thread_local
for passing theValueSource
would beto instead have a
Options::apply_source
or similar method that changes the sourcefor all values recursively. I decided against it because it would require a fair
bit of boilerplate (or a macro).
Test Plan
Added integration tests.