-
Notifications
You must be signed in to change notification settings - Fork 1.1k
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
[flake8-import-conventions
] Syntax check aliases supplied in configuration for unconventional-import-alias (ICN001)
#14477
Conversation
Two notes:
|
|
crates/ruff_workspace/Cargo.toml
Outdated
@@ -42,6 +43,7 @@ serde = { workspace = true } | |||
shellexpand = { workspace = true } | |||
strum = { workspace = true } | |||
toml = { workspace = true } | |||
serde_json.workspace = true |
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 should be a dev-dependency if it is only used in tests
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.
No longer used (test moved to integration test)
crates/ruff_workspace/src/options.rs
Outdated
#[test] | ||
fn flake8_import_conventions_validate_aliases() { | ||
let json_options = r#"{"aliases": {"a.b":"a.b"}}"#; | ||
let result: Result<Flake8ImportConventionsOptions, _> = serde_json::from_str(json_options); | ||
assert!(result.unwrap_err().to_string().contains("Module must be valid identifier separated by single periods and alias must be valid identifier")); | ||
} | ||
|
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'm leaning towards making this a ruff cli integration test. It then also demonstrates how the error message is displayed to the users.
See
ruff/crates/ruff/tests/lint.rs
Line 23 in c847cad
fn top_level_options() -> Result<()> { |
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.
Done!
crates/ruff_workspace/src/options.rs
Outdated
if module.is_empty() | ||
|| module.split('.').any(|part| !is_identifier(part)) | ||
|| !is_identifier(alias) | ||
{ | ||
return Err(de::Error::custom( | ||
"Module must be valid identifier separated by single periods and alias must be valid identifier", | ||
)); | ||
} |
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 suggest that we use two dedicated errors: One for alias
and one for module
.
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.
Done!
Let's try to get this into ruff 0.8 if we can — while it is a bugfix, it might still be breaking for some users who are currently "using the rule incorrectly" |
Sorry — I optimistically tried to change the target branch, but it messed up the diff, so I swiftly reverted that back 😅 It's probably fine if this goes straight into |
I also don't consider this breaking. It doesn't change the intent of the rule. |
I agree that it doesn't change the intent of the rule, but clearly some users are not using the rule as it was intended: #14439 (comment). We will break those users; this is a case of Hyrum's law. I strongly agree with the change, I'd just prefer to have it go into Ruff 0.8 and to list it in |
|
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.
Thanks for adding the integration tests. They show that the error messages aren't great. We should either:
- minimal: Include the alias and module name in the error message
- better: Use newtype wrappers for
Module
andAlias
(FxHashMap<ModuleName, Alias>
) and implementDeserialize
on the newtype wrappers. That should allow serde to highlight the relevant line and column in the error message.
crates/ruff/tests/lint.rs
Outdated
Cause: Failed to parse [TMP]/ruff.toml | ||
Cause: TOML parse error at line 2, column 2 | ||
| | ||
2 | [lint.flake8-import-conventions.aliases] |
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.
Hmm. The errors aren't great. Let's at least include the alias in the error message to help users figure out what's going on. The same for the module name.
crates/ruff_workspace/src/options.rs
Outdated
@@ -1327,6 +1329,7 @@ pub struct Flake8ImportConventionsOptions { | |||
scipy = "sp" | |||
"# | |||
)] | |||
#[serde(deserialize_with = "deserialize_and_validate_aliases")] | |||
pub aliases: Option<FxHashMap<String, String>>, |
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.
We would probably get better error messages if you create a newtype for ModuleName
and Alias
and implement Deserialize
for them. I would expect that serde can then narrow the error message to the specific line rather than the entire table
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 PR does actually already seem to be a small improvement on the status quo when it comes to line numbers. Currently if I make this change to typeshed's pyproject.toml file:
diff --git a/pyproject.toml b/pyproject.toml
index 46014bcd2..927da6162 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -111,6 +111,9 @@ ignore = [
"E501", # Line too long
]
+[tool.ruff.lint.flake8-import-conventions.aliases]
+"pandas" = 42
+
Then Ruff v0.7.1 gives me this error message:
ruff failed
Cause: Failed to parse /Users/alexw/dev/typeshed/pyproject.toml
Cause: TOML parse error at line 27, column 1
|
27 | [tool.ruff.lint]
| ^^^^^^^^^^^^^^^^
invalid type: integer `42`, expected a string
I pushed a change that implements |
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.
@AlexWaygood should we merge?
14ad456
to
4e0cf71
Compare
4e0cf71
to
e1805e9
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.
Thanks @dylwil3!
@MichaReiser you beat me to it! Much improved error message, thanks! |
This PR introduces a validation step to the deserialization of the configuration for unconventional-import-alias (ICN001). We verify that the import module and alias supplied have valid syntax in order to avoid a panic if these aliases are added in during a fix.
Closes #14439