Add per-file-target-version option (#16257)

## Summary

This PR is another step in preparing to detect syntax errors in the
parser. It introduces the new `per-file-target-version` top-level
configuration option, which holds a mapping of compiled glob patterns to
Python versions. I intend to use the
`LinterSettings::resolve_target_version` method here to pass to the
parser:


f50849aeef/crates/ruff_linter/src/linter.rs (L491-L493)

## Test Plan

I added two new CLI tests to show that the `per-file-target-version` is
respected in both the formatter and the linter.
This commit is contained in:
Brent Westbrook 2025-02-24 08:47:13 -05:00 committed by GitHub
parent 42a5f5ef6a
commit e7a6c19e3a
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
78 changed files with 820 additions and 274 deletions

View file

@ -333,6 +333,29 @@ pub struct Options {
)]
pub target_version: Option<PythonVersion>,
/// A list of mappings from glob-style file pattern to Python version to use when checking the
/// corresponding file(s).
///
/// This may be useful for overriding the global Python version settings in `target-version` or
/// `requires-python` for a subset of files. For example, if you have a project with a minimum
/// supported Python version of 3.9 but a subdirectory of developer scripts that want to use a
/// newer feature like the `match` statement from Python 3.10, you can use
/// `per-file-target-version` to specify `"developer_scripts/*.py" = "py310"`.
///
/// This setting is used by the linter to enforce any enabled version-specific lint rules, as
/// well as by the formatter for any version-specific formatting options, such as parenthesizing
/// context managers on Python 3.10+.
#[option(
default = "{}",
value_type = "dict[str, PythonVersion]",
scope = "per-file-target-version",
example = r#"
# Override the project-wide Python version for a developer scripts directory:
"scripts/**.py" = "py312"
"#
)]
pub per_file_target_version: Option<FxHashMap<String, PythonVersion>>,
/// The directories to consider when resolving first- vs. third-party
/// imports.
///