-
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] Add --ignore
, --warn
, and --error
CLI arguments
#15689
Conversation
@@ -30,7 +30,7 @@ tracing-flamechart.svg | |||
tracing-flamegraph.svg | |||
|
|||
# insta | |||
.rs.pending-snap | |||
*.rs.pending-snap |
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.
doh!
#[derive(Debug, Parser)] | ||
#[command( | ||
author, | ||
name = "red-knot", | ||
about = "An extremely fast Python type checker." | ||
)] | ||
#[command(version)] | ||
pub(crate) struct Args { | ||
#[command(subcommand)] | ||
pub(crate) command: Option<Command>, | ||
|
||
/// Run the command within the given project directory. | ||
/// | ||
/// All `pyproject.toml` files will be discovered by walking up the directory tree from the given project directory, | ||
/// as will the project's virtual environment (`.venv`) unless the `venv-path` option is set. | ||
/// | ||
/// Other command-line arguments (such as relative paths) will be resolved relative to the current working directory. | ||
#[arg(long, value_name = "PROJECT")] | ||
pub(crate) project: Option<SystemPathBuf>, | ||
|
||
/// Path to the virtual environment the project uses. | ||
/// | ||
/// If provided, red-knot will use the `site-packages` directory of this virtual environment | ||
/// to resolve type information for the project's third-party dependencies. | ||
#[arg(long, value_name = "PATH")] | ||
pub(crate) venv_path: Option<SystemPathBuf>, | ||
|
||
/// Custom directory to use for stdlib typeshed stubs. | ||
#[arg(long, value_name = "PATH", alias = "custom-typeshed-dir")] | ||
pub(crate) typeshed: Option<SystemPathBuf>, | ||
|
||
/// Additional path to use as a module-resolution source (can be passed multiple times). | ||
#[arg(long, value_name = "PATH")] | ||
pub(crate) extra_search_path: Option<Vec<SystemPathBuf>>, | ||
|
||
/// Python version to assume when resolving types. | ||
#[arg(long, value_name = "VERSION", alias = "target-version")] | ||
pub(crate) python_version: Option<PythonVersion>, | ||
|
||
#[clap(flatten)] | ||
pub(crate) verbosity: Verbosity, | ||
|
||
#[clap(flatten)] | ||
pub(crate) rules: RulesArg, | ||
|
||
/// Run in watch mode by re-running whenever files change. | ||
#[arg(long, short = 'W')] | ||
pub(crate) watch: bool, | ||
} | ||
|
||
impl Args { | ||
pub(crate) fn to_options(&self) -> Options { | ||
let rules = if self.rules.is_empty() { | ||
None | ||
} else { | ||
Some( | ||
self.rules | ||
.iter() | ||
.map(|(rule, level)| { | ||
(RangedValue::cli(rule.to_string()), RangedValue::cli(level)) | ||
}) | ||
.collect(), | ||
) | ||
}; | ||
|
||
Options { | ||
environment: Some(EnvironmentOptions { | ||
python_version: self | ||
.python_version | ||
.map(|version| RangedValue::cli(version.into())), | ||
venv_path: self.venv_path.as_ref().map(RelativePathBuf::cli), | ||
typeshed: self.typeshed.as_ref().map(RelativePathBuf::cli), | ||
extra_paths: self.extra_search_path.as_ref().map(|extra_search_paths| { | ||
extra_search_paths | ||
.iter() | ||
.map(RelativePathBuf::cli) | ||
.collect() | ||
}), | ||
..EnvironmentOptions::default() | ||
}), | ||
rules, | ||
..Default::default() | ||
} | ||
} | ||
} |
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 moved this code from main.rs
. The only difference is the added rules
field and the let rules = ...
in to_options
5dd905d
to
acc647e
Compare
acc647e
to
32c8630
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.
Nice, exciting to see this start coming together!
a09882f
to
e7a74fb
Compare
|
e7a74fb
to
61f473d
Compare
* main: Add `check` command (#15692) [red-knot] Use itertools to clean up `SymbolState::merge` (#15702) [red-knot] Add `--ignore`, `--warn`, and `--error` CLI arguments (#15689) Use `uv init --lib` in tutorial (#15718) [red-knot] Use `Unknown | T_inferred` for undeclared public symbols (#15674) [`ruff`] Parenthesize fix when argument spans multiple lines for `unnecessary-round` (`RUF057`) (#15703) [red-knot] Rename `TestDbBuilder::typeshed` to `.custom_typeshed` (#15712) Honor banned top level imports by TID253 in PLC0415. (#15628) Apply `AIR302`-context check only in `@task` function (#15711) [`airflow`] Update `AIR302` to check for deprecated context keys (#15144) Remove test rules from JSON schema (#15627) Add two missing commits to changelog (#15701) Fix grep for version number in docker build (#15699) Bump version to 0.9.3 (#15698) Preserve raw string prefix and escapes (#15694) [`flake8-pytest-style`] Rewrite references to `.exception` (`PT027`) (#15680)
Summary
Add support for enabling rules from the CLI and changing the rule's severity by adding
the
--warn
,--error
and--ignore
CLI arguments.The "tricky" part of this PR was that we need to preserve the order in which
the arguments were specified so that e.g.
--ignore division-by-zero --error division-by-zero
resolvesto enabling the rule with an
error
severity because the--error
argument comes last.The way this is solved is by manually implementing
Args
as described hereTest Plan
Added CLI tests, I did some manual testing as well.