mirror of
https://github.com/astral-sh/ruff.git
synced 2025-11-17 19:27:11 +00:00
Merge 924fd61627 into 665f68036c
This commit is contained in:
commit
875fca8779
10 changed files with 131 additions and 12 deletions
|
|
@ -146,14 +146,18 @@ linter.flake8_import_conventions.aliases = {
|
|||
pandas = pd,
|
||||
panel = pn,
|
||||
plotly.express = px,
|
||||
plotly.graph_objects = go,
|
||||
polars = pl,
|
||||
pyarrow = pa,
|
||||
seaborn = sns,
|
||||
statsmodels.api = sm,
|
||||
tensorflow = tf,
|
||||
tkinter = tk,
|
||||
xml.etree.ElementTree = ET,
|
||||
}
|
||||
linter.flake8_import_conventions.banned_aliases = {}
|
||||
linter.flake8_import_conventions.banned_aliases = {
|
||||
geopandas = [gpd],
|
||||
}
|
||||
linter.flake8_import_conventions.banned_from = []
|
||||
linter.flake8_pytest_style.fixture_parentheses = false
|
||||
linter.flake8_pytest_style.parametrize_names_type = tuple
|
||||
|
|
|
|||
|
|
@ -30,3 +30,17 @@ def conventional_aliases():
|
|||
import seaborn as sns
|
||||
import tkinter as tk
|
||||
import networkx as nx
|
||||
|
||||
|
||||
# ICN001: plotly.graph_objects should be imported as go
|
||||
import plotly.graph_objects # should require alias
|
||||
import plotly.graph_objects as go # ok
|
||||
|
||||
# ICN001: statsmodels.api should be imported as sm
|
||||
import statsmodels.api # should require alias
|
||||
import statsmodels.api as sm # ok
|
||||
|
||||
# ICN002: geopandas should not be imported as gpd
|
||||
import geopandas as gpd # banned
|
||||
import geopandas # ok
|
||||
import geopandas as gdf # ok
|
||||
|
|
|
|||
|
|
@ -254,6 +254,11 @@ pub(crate) const fn is_b006_check_guaranteed_mutable_expr_enabled(
|
|||
settings.preview.is_enabled()
|
||||
}
|
||||
|
||||
// https://github.com/astral-sh/ruff/pull/21373
|
||||
pub(crate) const fn is_import_conventions_preview_enabled(settings: &LinterSettings) -> bool {
|
||||
settings.preview.is_enabled()
|
||||
}
|
||||
|
||||
// github.com/astral-sh/ruff/issues/20004
|
||||
pub(crate) const fn is_b006_unsafe_fix_preserve_assignment_expr_enabled(
|
||||
settings: &LinterSettings,
|
||||
|
|
|
|||
|
|
@ -12,14 +12,20 @@ mod tests {
|
|||
use crate::assert_diagnostics;
|
||||
use crate::registry::Rule;
|
||||
use crate::rules::flake8_import_conventions::settings::{BannedAliases, default_aliases};
|
||||
use crate::settings::LinterSettings;
|
||||
use crate::settings::{LinterSettings, types::PreviewMode};
|
||||
use crate::test::test_path;
|
||||
|
||||
#[test]
|
||||
fn defaults() -> Result<()> {
|
||||
let mut settings = LinterSettings {
|
||||
flake8_import_conventions: super::settings::Settings::default(),
|
||||
..LinterSettings::for_rules([Rule::UnconventionalImportAlias, Rule::BannedImportAlias])
|
||||
};
|
||||
// Enable preview mode to test preview-only conventions
|
||||
settings.preview = PreviewMode::Enabled;
|
||||
let diagnostics = test_path(
|
||||
Path::new("flake8_import_conventions/defaults.py"),
|
||||
&LinterSettings::for_rule(Rule::UnconventionalImportAlias),
|
||||
&settings,
|
||||
)?;
|
||||
assert_diagnostics!(diagnostics);
|
||||
Ok(())
|
||||
|
|
|
|||
|
|
@ -6,7 +6,8 @@ use ruff_text_size::Ranged;
|
|||
|
||||
use crate::Violation;
|
||||
use crate::checkers::ast::Checker;
|
||||
use crate::rules::flake8_import_conventions::settings::BannedAliases;
|
||||
use crate::preview::is_import_conventions_preview_enabled;
|
||||
use crate::rules::flake8_import_conventions::settings::{BannedAliases, preview_banned_aliases};
|
||||
|
||||
/// ## What it does
|
||||
/// Checks for imports that use non-standard naming conventions, like
|
||||
|
|
@ -56,7 +57,17 @@ pub(crate) fn banned_import_alias(
|
|||
asname: &str,
|
||||
banned_conventions: &FxHashMap<String, BannedAliases>,
|
||||
) {
|
||||
if let Some(banned_aliases) = banned_conventions.get(name) {
|
||||
// Merge preview banned aliases if preview mode is enabled
|
||||
let banned_aliases = if is_import_conventions_preview_enabled(checker.settings()) {
|
||||
banned_conventions.get(name).cloned().or_else(|| {
|
||||
let preview_banned = preview_banned_aliases();
|
||||
preview_banned.get(name).cloned()
|
||||
})
|
||||
} else {
|
||||
banned_conventions.get(name).cloned()
|
||||
};
|
||||
|
||||
if let Some(banned_aliases) = banned_aliases.as_ref() {
|
||||
if banned_aliases
|
||||
.iter()
|
||||
.any(|banned_alias| banned_alias == asname)
|
||||
|
|
|
|||
|
|
@ -5,6 +5,8 @@ use ruff_python_semantic::{Binding, Imported};
|
|||
use ruff_text_size::Ranged;
|
||||
|
||||
use crate::checkers::ast::Checker;
|
||||
use crate::preview::is_import_conventions_preview_enabled;
|
||||
use crate::rules::flake8_import_conventions::settings::preview_aliases;
|
||||
use crate::{Fix, FixAvailability, Violation};
|
||||
|
||||
use crate::renamer::Renamer;
|
||||
|
|
@ -66,12 +68,26 @@ pub(crate) fn unconventional_import_alias(
|
|||
return;
|
||||
};
|
||||
let qualified_name = import.qualified_name().to_string();
|
||||
let Some(expected_alias) = conventions.get(qualified_name.as_str()) else {
|
||||
|
||||
// Merge preview conventions if preview mode is enabled
|
||||
let expected_alias = if is_import_conventions_preview_enabled(checker.settings()) {
|
||||
conventions
|
||||
.get(qualified_name.as_str())
|
||||
.cloned()
|
||||
.or_else(|| {
|
||||
let preview_aliases_map = preview_aliases();
|
||||
preview_aliases_map.get(qualified_name.as_str()).cloned()
|
||||
})
|
||||
} else {
|
||||
conventions.get(qualified_name.as_str()).cloned()
|
||||
};
|
||||
|
||||
let Some(expected_alias) = expected_alias else {
|
||||
return;
|
||||
};
|
||||
|
||||
let name = binding.name(checker.source());
|
||||
if name == expected_alias {
|
||||
if name == expected_alias.as_str() {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -83,12 +99,12 @@ pub(crate) fn unconventional_import_alias(
|
|||
binding.range(),
|
||||
);
|
||||
if !import.is_submodule_import() {
|
||||
if checker.semantic().is_available(expected_alias) {
|
||||
if checker.semantic().is_available(&expected_alias) {
|
||||
diagnostic.try_set_fix(|| {
|
||||
let scope = &checker.semantic().scopes[binding.scope];
|
||||
let (edit, rest) = Renamer::rename(
|
||||
name,
|
||||
expected_alias,
|
||||
&expected_alias,
|
||||
scope,
|
||||
checker.semantic(),
|
||||
checker.stylist(),
|
||||
|
|
|
|||
|
|
@ -17,17 +17,20 @@ const CONVENTIONAL_ALIASES: &[(&str, &str)] = &[
|
|||
("numpy", "np"),
|
||||
("numpy.typing", "npt"),
|
||||
("pandas", "pd"),
|
||||
("plotly.express", "px"),
|
||||
("seaborn", "sns"),
|
||||
("tensorflow", "tf"),
|
||||
("tkinter", "tk"),
|
||||
("holoviews", "hv"),
|
||||
("panel", "pn"),
|
||||
("plotly.express", "px"),
|
||||
("polars", "pl"),
|
||||
("pyarrow", "pa"),
|
||||
("xml.etree.ElementTree", "ET"),
|
||||
];
|
||||
|
||||
const PREVIEW_ALIASES: &[(&str, &str)] =
|
||||
&[("plotly.graph_objects", "go"), ("statsmodels.api", "sm")];
|
||||
|
||||
#[derive(Debug, Default, Clone, PartialEq, Eq, Serialize, Deserialize, CacheKey)]
|
||||
#[serde(deny_unknown_fields, rename_all = "kebab-case")]
|
||||
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
|
||||
|
|
@ -73,6 +76,32 @@ pub fn default_aliases() -> FxHashMap<String, String> {
|
|||
.collect::<FxHashMap<_, _>>()
|
||||
}
|
||||
|
||||
pub fn preview_aliases() -> FxHashMap<String, String> {
|
||||
PREVIEW_ALIASES
|
||||
.iter()
|
||||
.map(|(k, v)| ((*k).to_string(), (*v).to_string()))
|
||||
.collect::<FxHashMap<_, _>>()
|
||||
}
|
||||
|
||||
pub fn preview_banned_aliases() -> FxHashMap<String, BannedAliases> {
|
||||
FxHashMap::from_iter([(
|
||||
"geopandas".to_string(),
|
||||
BannedAliases::from_iter(["gpd".to_string()]),
|
||||
)])
|
||||
}
|
||||
|
||||
impl Settings {
|
||||
/// Merge preview aliases and banned aliases into the settings if preview mode is enabled.
|
||||
#[must_use]
|
||||
pub fn with_preview(mut self, preview_enabled: bool) -> Self {
|
||||
if preview_enabled {
|
||||
self.aliases.extend(preview_aliases());
|
||||
self.banned_aliases.extend(preview_banned_aliases());
|
||||
}
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for Settings {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
|
|
|
|||
|
|
@ -277,3 +277,33 @@ help: Alias `networkx` to `nx`
|
|||
24 |
|
||||
25 | def conventional_aliases():
|
||||
note: This is an unsafe fix and may change runtime behavior
|
||||
|
||||
ICN001 `plotly.graph_objects` should be imported as `go`
|
||||
--> defaults.py:36:8
|
||||
|
|
||||
35 | # ICN001: plotly.graph_objects should be imported as go
|
||||
36 | import plotly.graph_objects # should require alias
|
||||
| ^^^^^^^^^^^^^^^^^^^^
|
||||
37 | import plotly.graph_objects as go # ok
|
||||
|
|
||||
help: Alias `plotly.graph_objects` to `go`
|
||||
|
||||
ICN001 `statsmodels.api` should be imported as `sm`
|
||||
--> defaults.py:40:8
|
||||
|
|
||||
39 | # ICN001: statsmodels.api should be imported as sm
|
||||
40 | import statsmodels.api # should require alias
|
||||
| ^^^^^^^^^^^^^^^
|
||||
41 | import statsmodels.api as sm # ok
|
||||
|
|
||||
help: Alias `statsmodels.api` to `sm`
|
||||
|
||||
ICN002 `geopandas` should not be imported as `gpd`
|
||||
--> defaults.py:44:1
|
||||
|
|
||||
43 | # ICN002: geopandas should not be imported as gpd
|
||||
44 | import geopandas as gpd # banned
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^
|
||||
45 | import geopandas # ok
|
||||
46 | import geopandas as gdf # ok
|
||||
|
|
||||
|
|
|
|||
|
|
@ -250,12 +250,16 @@ impl Configuration {
|
|||
.map(IsortOptions::try_into_settings)
|
||||
.transpose()?
|
||||
.unwrap_or_default();
|
||||
let flake8_import_conventions = lint
|
||||
let mut flake8_import_conventions = lint
|
||||
.flake8_import_conventions
|
||||
.map(Flake8ImportConventionsOptions::try_into_settings)
|
||||
.transpose()?
|
||||
.unwrap_or_default();
|
||||
|
||||
// Merge preview aliases and banned aliases when preview mode is enabled
|
||||
flake8_import_conventions =
|
||||
flake8_import_conventions.with_preview(matches!(lint_preview, PreviewMode::Enabled));
|
||||
|
||||
conflicting_import_settings(&isort, &flake8_import_conventions)?;
|
||||
|
||||
let future_annotations = lint.future_annotations.unwrap_or_default();
|
||||
|
|
|
|||
|
|
@ -1534,7 +1534,7 @@ pub struct Flake8ImportConventionsOptions {
|
|||
/// The conventional aliases for imports. These aliases can be extended by
|
||||
/// the [`extend-aliases`](#lint_flake8-import-conventions_extend-aliases) option.
|
||||
#[option(
|
||||
default = r#"{"altair": "alt", "matplotlib": "mpl", "matplotlib.pyplot": "plt", "numpy": "np", "numpy.typing": "npt", "pandas": "pd", "seaborn": "sns", "tensorflow": "tf", "tkinter": "tk", "holoviews": "hv", "panel": "pn", "plotly.express": "px", "polars": "pl", "pyarrow": "pa", "xml.etree.ElementTree": "ET"}"#,
|
||||
default = r#"{"altair": "alt", "matplotlib": "mpl", "matplotlib.pyplot": "plt", "numpy": "np", "numpy.typing": "npt", "pandas": "pd", "plotly.express": "px", "seaborn": "sns", "tensorflow": "tf", "tkinter": "tk", "holoviews": "hv", "panel": "pn", "polars": "pl", "pyarrow": "pa", "xml.etree.ElementTree": "ET"}"#,
|
||||
value_type = "dict[str, str]",
|
||||
scope = "aliases",
|
||||
example = r#"
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue