[ty] Infer the Python version from the environment if feasible (#18057)

Co-authored-by: Alex Waygood <alex.waygood@gmail.com>
This commit is contained in:
Zanie Blue 2025-05-30 16:22:51 -05:00 committed by GitHub
parent 9bbf4987e8
commit 88866f0048
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
19 changed files with 582 additions and 165 deletions

View file

@ -1,8 +1,5 @@
use crate::{Db, Program, PythonVersionWithSource};
use ruff_db::{
diagnostic::{Annotation, Diagnostic, Severity, Span, SubDiagnostic},
files::system_path_to_file,
};
use ruff_db::diagnostic::{Annotation, Diagnostic, Severity, SubDiagnostic};
/// Add a subdiagnostic to `diagnostic` that explains why a certain Python version was inferred.
///
@ -22,17 +19,15 @@ pub fn add_inferred_python_version_hint_to_diagnostic(
"Python {version} was assumed when {action} because it was specified on the command line",
));
}
crate::PythonVersionSource::File(path, range) => {
if let Ok(file) = system_path_to_file(db.upcast(), &**path) {
crate::PythonVersionSource::ConfigFile(source) => {
if let Some(span) = source.span(db) {
let mut sub_diagnostic = SubDiagnostic::new(
Severity::Info,
format_args!("Python {version} was assumed when {action}"),
);
sub_diagnostic.annotate(
Annotation::primary(Span::from(file).with_optional_range(*range)).message(
format_args!("Python {version} assumed due to this configuration setting"),
),
);
sub_diagnostic.annotate(Annotation::primary(span).message(format_args!(
"Python {version} assumed due to this configuration setting"
)));
diagnostic.sub(sub_diagnostic);
} else {
diagnostic.info(format_args!(
@ -40,6 +35,32 @@ pub fn add_inferred_python_version_hint_to_diagnostic(
));
}
}
crate::PythonVersionSource::PyvenvCfgFile(source) => {
if let Some(span) = source.span(db) {
let mut sub_diagnostic = SubDiagnostic::new(
Severity::Info,
format_args!(
"Python {version} was assumed when {action} because of your virtual environment"
),
);
sub_diagnostic.annotate(
Annotation::primary(span)
.message("Python version inferred from virtual environment metadata file"),
);
// TODO: it would also be nice to tell them how we resolved their virtual environment...
diagnostic.sub(sub_diagnostic);
} else {
diagnostic.info(format_args!(
"Python {version} was assumed when {action} because \
your virtual environment's pyvenv.cfg file indicated \
it was the Python version being used",
));
}
diagnostic.info(
"No Python version was specified on the command line \
or in a configuration file",
);
}
crate::PythonVersionSource::Default => {
diagnostic.info(format_args!(
"Python {version} was assumed when {action} \