mirror of
https://github.com/astral-sh/ruff.git
synced 2025-11-18 19:41:34 +00:00
feat: add option to toggle type checking imports detection
Commit adds functionality to enabled or disable type checking imports, either as a cli arg or a config file
This commit is contained in:
parent
698231a47a
commit
b5c24fe923
6 changed files with 52 additions and 1 deletions
|
|
@ -167,6 +167,7 @@ pub enum AnalyzeCommand {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, clap::Parser)]
|
#[derive(Clone, Debug, clap::Parser)]
|
||||||
|
#[expect(clippy::struct_excessive_bools)]
|
||||||
pub struct AnalyzeGraphCommand {
|
pub struct AnalyzeGraphCommand {
|
||||||
/// List of files or directories to include.
|
/// List of files or directories to include.
|
||||||
#[clap(help = "List of files or directories to include [default: .]")]
|
#[clap(help = "List of files or directories to include [default: .]")]
|
||||||
|
|
@ -193,6 +194,11 @@ pub struct AnalyzeGraphCommand {
|
||||||
/// Path to a virtual environment to use for resolving additional dependencies
|
/// Path to a virtual environment to use for resolving additional dependencies
|
||||||
#[arg(long)]
|
#[arg(long)]
|
||||||
python: Option<PathBuf>,
|
python: Option<PathBuf>,
|
||||||
|
/// Include imports that are only used for type checking (i.e., imports within `if TYPE_CHECKING:` blocks). Use `--no-type-checking-imports` to disable.
|
||||||
|
#[arg(long, overrides_with("no_type_checking_imports"))]
|
||||||
|
type_checking_imports: bool,
|
||||||
|
#[arg(long, overrides_with("type_checking_imports"), hide = true)]
|
||||||
|
no_type_checking_imports: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
// The `Parser` derive is for ruff_dev, for ruff `Args` would be sufficient
|
// The `Parser` derive is for ruff_dev, for ruff `Args` would be sufficient
|
||||||
|
|
@ -839,6 +845,10 @@ impl AnalyzeGraphCommand {
|
||||||
string_imports_min_dots: self.min_dots,
|
string_imports_min_dots: self.min_dots,
|
||||||
preview: resolve_bool_arg(self.preview, self.no_preview).map(PreviewMode::from),
|
preview: resolve_bool_arg(self.preview, self.no_preview).map(PreviewMode::from),
|
||||||
target_version: self.target_version.map(ast::PythonVersion::from),
|
target_version: self.target_version.map(ast::PythonVersion::from),
|
||||||
|
type_checking_imports: resolve_bool_arg(
|
||||||
|
self.type_checking_imports,
|
||||||
|
self.no_type_checking_imports,
|
||||||
|
),
|
||||||
..ExplicitConfigOverrides::default()
|
..ExplicitConfigOverrides::default()
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -1335,6 +1345,7 @@ struct ExplicitConfigOverrides {
|
||||||
extension: Option<Vec<ExtensionPair>>,
|
extension: Option<Vec<ExtensionPair>>,
|
||||||
detect_string_imports: Option<bool>,
|
detect_string_imports: Option<bool>,
|
||||||
string_imports_min_dots: Option<usize>,
|
string_imports_min_dots: Option<usize>,
|
||||||
|
type_checking_imports: Option<bool>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ConfigurationTransformer for ExplicitConfigOverrides {
|
impl ConfigurationTransformer for ExplicitConfigOverrides {
|
||||||
|
|
@ -1425,6 +1436,9 @@ impl ConfigurationTransformer for ExplicitConfigOverrides {
|
||||||
if let Some(string_imports_min_dots) = &self.string_imports_min_dots {
|
if let Some(string_imports_min_dots) = &self.string_imports_min_dots {
|
||||||
config.analyze.string_imports_min_dots = Some(*string_imports_min_dots);
|
config.analyze.string_imports_min_dots = Some(*string_imports_min_dots);
|
||||||
}
|
}
|
||||||
|
if let Some(type_checking_imports) = &self.type_checking_imports {
|
||||||
|
config.analyze.type_checking_imports = Some(*type_checking_imports);
|
||||||
|
}
|
||||||
|
|
||||||
config
|
config
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -105,6 +105,7 @@ pub(crate) fn analyze_graph(
|
||||||
let settings = resolver.resolve(path);
|
let settings = resolver.resolve(path);
|
||||||
let string_imports = settings.analyze.string_imports;
|
let string_imports = settings.analyze.string_imports;
|
||||||
let include_dependencies = settings.analyze.include_dependencies.get(path).cloned();
|
let include_dependencies = settings.analyze.include_dependencies.get(path).cloned();
|
||||||
|
let type_checking_imports = settings.analyze.type_checking_imports;
|
||||||
|
|
||||||
// Skip excluded files.
|
// Skip excluded files.
|
||||||
if (settings.file_resolver.force_exclude || !resolved_file.is_root())
|
if (settings.file_resolver.force_exclude || !resolved_file.is_root())
|
||||||
|
|
@ -167,6 +168,7 @@ pub(crate) fn analyze_graph(
|
||||||
&path,
|
&path,
|
||||||
package.as_deref(),
|
package.as_deref(),
|
||||||
string_imports,
|
string_imports,
|
||||||
|
type_checking_imports,
|
||||||
)
|
)
|
||||||
.unwrap_or_else(|err| {
|
.unwrap_or_else(|err| {
|
||||||
warn!("Failed to generate import map for {path}: {err}");
|
warn!("Failed to generate import map for {path}: {err}");
|
||||||
|
|
|
||||||
|
|
@ -30,6 +30,7 @@ impl ModuleImports {
|
||||||
path: &SystemPath,
|
path: &SystemPath,
|
||||||
package: Option<&SystemPath>,
|
package: Option<&SystemPath>,
|
||||||
string_imports: StringImports,
|
string_imports: StringImports,
|
||||||
|
type_checking_imports: bool,
|
||||||
) -> Result<Self> {
|
) -> Result<Self> {
|
||||||
// Parse the source code.
|
// Parse the source code.
|
||||||
let parsed = parse(source, ParseOptions::from(source_type))?;
|
let parsed = parse(source, ParseOptions::from(source_type))?;
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@ use std::collections::BTreeMap;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
|
|
||||||
#[derive(Debug, Default, Clone, CacheKey)]
|
#[derive(Debug, Clone, CacheKey)]
|
||||||
pub struct AnalyzeSettings {
|
pub struct AnalyzeSettings {
|
||||||
pub exclude: FilePatternSet,
|
pub exclude: FilePatternSet,
|
||||||
pub preview: PreviewMode,
|
pub preview: PreviewMode,
|
||||||
|
|
@ -14,6 +14,21 @@ pub struct AnalyzeSettings {
|
||||||
pub string_imports: StringImports,
|
pub string_imports: StringImports,
|
||||||
pub include_dependencies: BTreeMap<PathBuf, (PathBuf, Vec<String>)>,
|
pub include_dependencies: BTreeMap<PathBuf, (PathBuf, Vec<String>)>,
|
||||||
pub extension: ExtensionMapping,
|
pub extension: ExtensionMapping,
|
||||||
|
pub type_checking_imports: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for AnalyzeSettings {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self {
|
||||||
|
exclude: FilePatternSet::default(),
|
||||||
|
preview: PreviewMode::default(),
|
||||||
|
target_version: PythonVersion::default(),
|
||||||
|
string_imports: StringImports::default(),
|
||||||
|
include_dependencies: BTreeMap::default(),
|
||||||
|
extension: ExtensionMapping::default(),
|
||||||
|
type_checking_imports: true,
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl fmt::Display for AnalyzeSettings {
|
impl fmt::Display for AnalyzeSettings {
|
||||||
|
|
@ -29,6 +44,7 @@ impl fmt::Display for AnalyzeSettings {
|
||||||
self.string_imports,
|
self.string_imports,
|
||||||
self.extension | debug,
|
self.extension | debug,
|
||||||
self.include_dependencies | debug,
|
self.include_dependencies | debug,
|
||||||
|
self.type_checking_imports,
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
|
||||||
|
|
@ -232,6 +232,9 @@ impl Configuration {
|
||||||
include_dependencies: analyze
|
include_dependencies: analyze
|
||||||
.include_dependencies
|
.include_dependencies
|
||||||
.unwrap_or(analyze_defaults.include_dependencies),
|
.unwrap_or(analyze_defaults.include_dependencies),
|
||||||
|
type_checking_imports: analyze
|
||||||
|
.type_checking_imports
|
||||||
|
.unwrap_or(analyze_defaults.type_checking_imports),
|
||||||
};
|
};
|
||||||
|
|
||||||
let lint = self.lint;
|
let lint = self.lint;
|
||||||
|
|
@ -1277,6 +1280,7 @@ pub struct AnalyzeConfiguration {
|
||||||
pub detect_string_imports: Option<bool>,
|
pub detect_string_imports: Option<bool>,
|
||||||
pub string_imports_min_dots: Option<usize>,
|
pub string_imports_min_dots: Option<usize>,
|
||||||
pub include_dependencies: Option<BTreeMap<PathBuf, (PathBuf, Vec<String>)>>,
|
pub include_dependencies: Option<BTreeMap<PathBuf, (PathBuf, Vec<String>)>>,
|
||||||
|
pub type_checking_imports: Option<bool>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AnalyzeConfiguration {
|
impl AnalyzeConfiguration {
|
||||||
|
|
@ -1303,6 +1307,7 @@ impl AnalyzeConfiguration {
|
||||||
})
|
})
|
||||||
.collect::<BTreeMap<_, _>>()
|
.collect::<BTreeMap<_, _>>()
|
||||||
}),
|
}),
|
||||||
|
type_checking_imports: options.type_checking_imports,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1317,6 +1322,7 @@ impl AnalyzeConfiguration {
|
||||||
.string_imports_min_dots
|
.string_imports_min_dots
|
||||||
.or(config.string_imports_min_dots),
|
.or(config.string_imports_min_dots),
|
||||||
include_dependencies: self.include_dependencies.or(config.include_dependencies),
|
include_dependencies: self.include_dependencies.or(config.include_dependencies),
|
||||||
|
type_checking_imports: self.type_checking_imports.or(config.type_checking_imports),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3892,6 +3892,18 @@ pub struct AnalyzeOptions {
|
||||||
"#
|
"#
|
||||||
)]
|
)]
|
||||||
pub include_dependencies: Option<BTreeMap<PathBuf, Vec<String>>>,
|
pub include_dependencies: Option<BTreeMap<PathBuf, Vec<String>>>,
|
||||||
|
/// Whether to include imports that are only used for type checking (i.e., imports within `if TYPE_CHECKING:` blocks).
|
||||||
|
/// When enabled (default), type-checking-only imports are included in the import graph.
|
||||||
|
/// When disabled, they are excluded.
|
||||||
|
#[option(
|
||||||
|
default = "true",
|
||||||
|
value_type = "bool",
|
||||||
|
example = r#"
|
||||||
|
# Exclude type-checking-only imports from the graph
|
||||||
|
type-checking-imports = false
|
||||||
|
"#
|
||||||
|
)]
|
||||||
|
pub type_checking_imports: Option<bool>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Like [`LintCommonOptions`], but with any `#[serde(flatten)]` fields inlined. This leads to far,
|
/// Like [`LintCommonOptions`], but with any `#[serde(flatten)]` fields inlined. This leads to far,
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue