diff --git a/crates/ruff_python_formatter/src/lib.rs b/crates/ruff_python_formatter/src/lib.rs index 05f122606bd796..5b7f4ff29d80fa 100644 --- a/crates/ruff_python_formatter/src/lib.rs +++ b/crates/ruff_python_formatter/src/lib.rs @@ -17,7 +17,7 @@ use crate::comments::{ pub use crate::context::PyFormatContext; pub use crate::options::{ DocstringCode, DocstringCodeLineWidth, MagicTrailingComma, PreviewMode, PyFormatOptions, - QuoteStyle, + PythonVersion, QuoteStyle, }; pub use crate::shared_traits::{AsFormat, FormattedIter, FormattedIterExt, IntoFormat}; use crate::verbatim::suppressed_node; diff --git a/crates/ruff_python_formatter/src/options.rs b/crates/ruff_python_formatter/src/options.rs index 4f637dca9ee107..5408e1f8e19e3c 100644 --- a/crates/ruff_python_formatter/src/options.rs +++ b/crates/ruff_python_formatter/src/options.rs @@ -17,6 +17,10 @@ pub struct PyFormatOptions { /// Whether we're in a `.py` file or `.pyi` file, which have different rules. source_type: PySourceType, + /// The (minimum) Python version used to run the formatted code. This is used + /// to determine the supported Python syntax. + target_version: PythonVersion, + /// Specifies the indent style: /// * Either a tab /// * or a specific amount of spaces @@ -74,6 +78,7 @@ impl Default for PyFormatOptions { fn default() -> Self { Self { source_type: PySourceType::default(), + target_version: PythonVersion::default(), indent_style: default_indent_style(), line_width: default_line_width(), indent_width: default_indent_width(), @@ -101,31 +106,35 @@ impl PyFormatOptions { } } - pub fn magic_trailing_comma(&self) -> MagicTrailingComma { + pub const fn target_version(&self) -> PythonVersion { + self.target_version + } + + pub const fn magic_trailing_comma(&self) -> MagicTrailingComma { self.magic_trailing_comma } - pub fn quote_style(&self) -> QuoteStyle { + pub const fn quote_style(&self) -> QuoteStyle { self.quote_style } - pub fn source_type(&self) -> PySourceType { + pub const fn source_type(&self) -> PySourceType { self.source_type } - pub fn source_map_generation(&self) -> SourceMapGeneration { + pub const fn source_map_generation(&self) -> SourceMapGeneration { self.source_map_generation } - pub fn line_ending(&self) -> LineEnding { + pub const fn line_ending(&self) -> LineEnding { self.line_ending } - pub fn docstring_code(&self) -> DocstringCode { + pub const fn docstring_code(&self) -> DocstringCode { self.docstring_code } - pub fn docstring_code_line_width(&self) -> DocstringCodeLineWidth { + pub const fn docstring_code_line_width(&self) -> DocstringCodeLineWidth { self.docstring_code_line_width } @@ -133,6 +142,12 @@ impl PyFormatOptions { self.preview } + #[must_use] + pub fn with_target_version(mut self, target_version: PythonVersion) -> Self { + self.target_version = target_version; + self + } + #[must_use] pub fn with_indent_width(mut self, indent_width: IndentWidth) -> Self { self.indent_width = indent_width; @@ -349,3 +364,20 @@ where )), } } + +#[derive(CacheKey, Clone, Copy, Debug, PartialOrd, Ord, PartialEq, Eq, Default)] +#[cfg_attr( + feature = "serde", + derive(serde::Serialize, serde::Deserialize), + serde(rename_all = "lowercase") +)] +#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] +pub enum PythonVersion { + Py37, + #[default] + Py38, + Py39, + Py310, + Py311, + Py312, +} diff --git a/crates/ruff_python_formatter/tests/fixtures.rs b/crates/ruff_python_formatter/tests/fixtures.rs index 3845385d7335f5..ebe0569ffe5f05 100644 --- a/crates/ruff_python_formatter/tests/fixtures.rs +++ b/crates/ruff_python_formatter/tests/fixtures.rs @@ -355,7 +355,8 @@ line-ending = {line_ending:?} magic-trailing-comma = {magic_trailing_comma:?} docstring-code = {docstring_code:?} docstring-code-line-width = {docstring_code_line_width:?} -preview = {preview:?}"#, +preview = {preview:?} +target_version = {target_version:?}"#, indent_style = self.0.indent_style(), indent_width = self.0.indent_width().value(), line_width = self.0.line_width().value(), @@ -364,7 +365,8 @@ preview = {preview:?}"#, magic_trailing_comma = self.0.magic_trailing_comma(), docstring_code = self.0.docstring_code(), docstring_code_line_width = self.0.docstring_code_line_width(), - preview = self.0.preview() + preview = self.0.preview(), + target_version = self.0.target_version() ) } } diff --git a/crates/ruff_python_formatter/tests/snapshots/format@blank_line_before_class_docstring.py.snap b/crates/ruff_python_formatter/tests/snapshots/format@blank_line_before_class_docstring.py.snap index b3986d0395ff1a..0f29adfc9f5ff0 100644 --- a/crates/ruff_python_formatter/tests/snapshots/format@blank_line_before_class_docstring.py.snap +++ b/crates/ruff_python_formatter/tests/snapshots/format@blank_line_before_class_docstring.py.snap @@ -56,6 +56,7 @@ magic-trailing-comma = Respect docstring-code = Disabled docstring-code-line-width = "dynamic" preview = Enabled +target_version = Py38 ``` ```python diff --git a/crates/ruff_python_formatter/tests/snapshots/format@docstring.py.snap b/crates/ruff_python_formatter/tests/snapshots/format@docstring.py.snap index bf8fa7f40df949..b447c93b8cec6b 100644 --- a/crates/ruff_python_formatter/tests/snapshots/format@docstring.py.snap +++ b/crates/ruff_python_formatter/tests/snapshots/format@docstring.py.snap @@ -175,6 +175,7 @@ magic-trailing-comma = Respect docstring-code = Disabled docstring-code-line-width = "dynamic" preview = Disabled +target_version = Py38 ``` ```python @@ -349,6 +350,7 @@ magic-trailing-comma = Respect docstring-code = Disabled docstring-code-line-width = "dynamic" preview = Disabled +target_version = Py38 ``` ```python @@ -523,6 +525,7 @@ magic-trailing-comma = Respect docstring-code = Disabled docstring-code-line-width = "dynamic" preview = Disabled +target_version = Py38 ``` ```python @@ -697,6 +700,7 @@ magic-trailing-comma = Respect docstring-code = Disabled docstring-code-line-width = "dynamic" preview = Disabled +target_version = Py38 ``` ```python @@ -871,6 +875,7 @@ magic-trailing-comma = Respect docstring-code = Disabled docstring-code-line-width = "dynamic" preview = Disabled +target_version = Py38 ``` ```python diff --git a/crates/ruff_python_formatter/tests/snapshots/format@docstring_code_examples.py.snap b/crates/ruff_python_formatter/tests/snapshots/format@docstring_code_examples.py.snap index 672b7a715d623d..08a112b1d869a2 100644 --- a/crates/ruff_python_formatter/tests/snapshots/format@docstring_code_examples.py.snap +++ b/crates/ruff_python_formatter/tests/snapshots/format@docstring_code_examples.py.snap @@ -1368,6 +1368,7 @@ magic-trailing-comma = Respect docstring-code = Disabled docstring-code-line-width = "dynamic" preview = Disabled +target_version = Py38 ``` ```python @@ -2738,6 +2739,7 @@ magic-trailing-comma = Respect docstring-code = Disabled docstring-code-line-width = "dynamic" preview = Disabled +target_version = Py38 ``` ```python @@ -4108,6 +4110,7 @@ magic-trailing-comma = Respect docstring-code = Disabled docstring-code-line-width = "dynamic" preview = Disabled +target_version = Py38 ``` ```python @@ -5478,6 +5481,7 @@ magic-trailing-comma = Respect docstring-code = Disabled docstring-code-line-width = "dynamic" preview = Disabled +target_version = Py38 ``` ```python @@ -6848,6 +6852,7 @@ magic-trailing-comma = Respect docstring-code = Enabled docstring-code-line-width = "dynamic" preview = Disabled +target_version = Py38 ``` ```python @@ -8215,6 +8220,7 @@ magic-trailing-comma = Respect docstring-code = Enabled docstring-code-line-width = "dynamic" preview = Disabled +target_version = Py38 ``` ```python @@ -9582,6 +9588,7 @@ magic-trailing-comma = Respect docstring-code = Enabled docstring-code-line-width = "dynamic" preview = Disabled +target_version = Py38 ``` ```python @@ -10958,6 +10965,7 @@ magic-trailing-comma = Respect docstring-code = Enabled docstring-code-line-width = "dynamic" preview = Disabled +target_version = Py38 ``` ```python @@ -12325,6 +12333,7 @@ magic-trailing-comma = Respect docstring-code = Enabled docstring-code-line-width = 60 preview = Disabled +target_version = Py38 ``` ```python @@ -13701,6 +13710,7 @@ magic-trailing-comma = Respect docstring-code = Enabled docstring-code-line-width = "dynamic" preview = Disabled +target_version = Py38 ``` ```python diff --git a/crates/ruff_python_formatter/tests/snapshots/format@docstring_code_examples_crlf.py.snap b/crates/ruff_python_formatter/tests/snapshots/format@docstring_code_examples_crlf.py.snap index 9f7fd5b9ac5b7d..c36e4046fae208 100644 --- a/crates/ruff_python_formatter/tests/snapshots/format@docstring_code_examples_crlf.py.snap +++ b/crates/ruff_python_formatter/tests/snapshots/format@docstring_code_examples_crlf.py.snap @@ -27,6 +27,7 @@ magic-trailing-comma = Respect docstring-code = Enabled docstring-code-line-width = "dynamic" preview = Disabled +target_version = Py38 ``` ```python diff --git a/crates/ruff_python_formatter/tests/snapshots/format@docstring_code_examples_dynamic_line_width.py.snap b/crates/ruff_python_formatter/tests/snapshots/format@docstring_code_examples_dynamic_line_width.py.snap index 1bab5f433b52a7..2d2a1afd30e7fc 100644 --- a/crates/ruff_python_formatter/tests/snapshots/format@docstring_code_examples_dynamic_line_width.py.snap +++ b/crates/ruff_python_formatter/tests/snapshots/format@docstring_code_examples_dynamic_line_width.py.snap @@ -239,6 +239,7 @@ magic-trailing-comma = Respect docstring-code = Enabled docstring-code-line-width = "dynamic" preview = Disabled +target_version = Py38 ``` ```python @@ -545,6 +546,7 @@ magic-trailing-comma = Respect docstring-code = Enabled docstring-code-line-width = "dynamic" preview = Disabled +target_version = Py38 ``` ```python @@ -841,6 +843,7 @@ magic-trailing-comma = Respect docstring-code = Enabled docstring-code-line-width = "dynamic" preview = Disabled +target_version = Py38 ``` ```python @@ -1147,6 +1150,7 @@ magic-trailing-comma = Respect docstring-code = Enabled docstring-code-line-width = "dynamic" preview = Disabled +target_version = Py38 ``` ```python diff --git a/crates/ruff_python_formatter/tests/snapshots/format@expression__bytes.py.snap b/crates/ruff_python_formatter/tests/snapshots/format@expression__bytes.py.snap index b741654c94c4a5..b6c249c6095573 100644 --- a/crates/ruff_python_formatter/tests/snapshots/format@expression__bytes.py.snap +++ b/crates/ruff_python_formatter/tests/snapshots/format@expression__bytes.py.snap @@ -138,6 +138,7 @@ magic-trailing-comma = Respect docstring-code = Disabled docstring-code-line-width = "dynamic" preview = Disabled +target_version = Py38 ``` ```python @@ -290,6 +291,7 @@ magic-trailing-comma = Respect docstring-code = Disabled docstring-code-line-width = "dynamic" preview = Disabled +target_version = Py38 ``` ```python diff --git a/crates/ruff_python_formatter/tests/snapshots/format@expression__string.py.snap b/crates/ruff_python_formatter/tests/snapshots/format@expression__string.py.snap index 306a10a49f9fe2..7fa4f1e24eb5aa 100644 --- a/crates/ruff_python_formatter/tests/snapshots/format@expression__string.py.snap +++ b/crates/ruff_python_formatter/tests/snapshots/format@expression__string.py.snap @@ -153,6 +153,7 @@ magic-trailing-comma = Respect docstring-code = Disabled docstring-code-line-width = "dynamic" preview = Disabled +target_version = Py38 ``` ```python @@ -329,6 +330,7 @@ magic-trailing-comma = Respect docstring-code = Disabled docstring-code-line-width = "dynamic" preview = Disabled +target_version = Py38 ``` ```python diff --git a/crates/ruff_python_formatter/tests/snapshots/format@fmt_on_off__fmt_off_docstring.py.snap b/crates/ruff_python_formatter/tests/snapshots/format@fmt_on_off__fmt_off_docstring.py.snap index 2c5ce6935feec0..a9da9389700244 100644 --- a/crates/ruff_python_formatter/tests/snapshots/format@fmt_on_off__fmt_off_docstring.py.snap +++ b/crates/ruff_python_formatter/tests/snapshots/format@fmt_on_off__fmt_off_docstring.py.snap @@ -37,6 +37,7 @@ magic-trailing-comma = Respect docstring-code = Disabled docstring-code-line-width = "dynamic" preview = Disabled +target_version = Py38 ``` ```python @@ -73,6 +74,7 @@ magic-trailing-comma = Respect docstring-code = Disabled docstring-code-line-width = "dynamic" preview = Disabled +target_version = Py38 ``` ```python diff --git a/crates/ruff_python_formatter/tests/snapshots/format@fmt_on_off__indent.py.snap b/crates/ruff_python_formatter/tests/snapshots/format@fmt_on_off__indent.py.snap index f1db6d7a8bfdc2..9f2c51fc6f5cf1 100644 --- a/crates/ruff_python_formatter/tests/snapshots/format@fmt_on_off__indent.py.snap +++ b/crates/ruff_python_formatter/tests/snapshots/format@fmt_on_off__indent.py.snap @@ -18,6 +18,7 @@ magic-trailing-comma = Respect docstring-code = Disabled docstring-code-line-width = "dynamic" preview = Disabled +target_version = Py38 ``` ```python @@ -35,6 +36,7 @@ magic-trailing-comma = Respect docstring-code = Disabled docstring-code-line-width = "dynamic" preview = Disabled +target_version = Py38 ``` ```python @@ -52,6 +54,7 @@ magic-trailing-comma = Respect docstring-code = Disabled docstring-code-line-width = "dynamic" preview = Disabled +target_version = Py38 ``` ```python diff --git a/crates/ruff_python_formatter/tests/snapshots/format@fmt_on_off__mixed_space_and_tab.py.snap b/crates/ruff_python_formatter/tests/snapshots/format@fmt_on_off__mixed_space_and_tab.py.snap index 7ff04c9571b702..945439c7d8acc3 100644 --- a/crates/ruff_python_formatter/tests/snapshots/format@fmt_on_off__mixed_space_and_tab.py.snap +++ b/crates/ruff_python_formatter/tests/snapshots/format@fmt_on_off__mixed_space_and_tab.py.snap @@ -33,6 +33,7 @@ magic-trailing-comma = Respect docstring-code = Disabled docstring-code-line-width = "dynamic" preview = Disabled +target_version = Py38 ``` ```python @@ -66,6 +67,7 @@ magic-trailing-comma = Respect docstring-code = Disabled docstring-code-line-width = "dynamic" preview = Disabled +target_version = Py38 ``` ```python @@ -99,6 +101,7 @@ magic-trailing-comma = Respect docstring-code = Disabled docstring-code-line-width = "dynamic" preview = Disabled +target_version = Py38 ``` ```python diff --git a/crates/ruff_python_formatter/tests/snapshots/format@preview.py.snap b/crates/ruff_python_formatter/tests/snapshots/format@preview.py.snap index 888c6f938a304b..6922442d678433 100644 --- a/crates/ruff_python_formatter/tests/snapshots/format@preview.py.snap +++ b/crates/ruff_python_formatter/tests/snapshots/format@preview.py.snap @@ -84,6 +84,7 @@ magic-trailing-comma = Respect docstring-code = Disabled docstring-code-line-width = "dynamic" preview = Disabled +target_version = Py38 ``` ```python @@ -166,6 +167,7 @@ magic-trailing-comma = Respect docstring-code = Disabled docstring-code-line-width = "dynamic" preview = Enabled +target_version = Py38 ``` ```python diff --git a/crates/ruff_python_formatter/tests/snapshots/format@quote_style.py.snap b/crates/ruff_python_formatter/tests/snapshots/format@quote_style.py.snap index ed5c09022e14e4..4cd816c24eb133 100644 --- a/crates/ruff_python_formatter/tests/snapshots/format@quote_style.py.snap +++ b/crates/ruff_python_formatter/tests/snapshots/format@quote_style.py.snap @@ -68,6 +68,7 @@ magic-trailing-comma = Respect docstring-code = Disabled docstring-code-line-width = "dynamic" preview = Disabled +target_version = Py38 ``` ```python @@ -139,6 +140,7 @@ magic-trailing-comma = Respect docstring-code = Disabled docstring-code-line-width = "dynamic" preview = Disabled +target_version = Py38 ``` ```python @@ -210,6 +212,7 @@ magic-trailing-comma = Respect docstring-code = Disabled docstring-code-line-width = "dynamic" preview = Disabled +target_version = Py38 ``` ```python diff --git a/crates/ruff_python_formatter/tests/snapshots/format@skip_magic_trailing_comma.py.snap b/crates/ruff_python_formatter/tests/snapshots/format@skip_magic_trailing_comma.py.snap index 83b67689f467fb..70efcca93a7942 100644 --- a/crates/ruff_python_formatter/tests/snapshots/format@skip_magic_trailing_comma.py.snap +++ b/crates/ruff_python_formatter/tests/snapshots/format@skip_magic_trailing_comma.py.snap @@ -51,6 +51,7 @@ magic-trailing-comma = Respect docstring-code = Disabled docstring-code-line-width = "dynamic" preview = Disabled +target_version = Py38 ``` ```python @@ -107,6 +108,7 @@ magic-trailing-comma = Ignore docstring-code = Disabled docstring-code-line-width = "dynamic" preview = Disabled +target_version = Py38 ``` ```python diff --git a/crates/ruff_python_formatter/tests/snapshots/format@statement__assignment_split_value_first.py.snap b/crates/ruff_python_formatter/tests/snapshots/format@statement__assignment_split_value_first.py.snap index f26ce4b5fba0bd..e112d4b651d3ff 100644 --- a/crates/ruff_python_formatter/tests/snapshots/format@statement__assignment_split_value_first.py.snap +++ b/crates/ruff_python_formatter/tests/snapshots/format@statement__assignment_split_value_first.py.snap @@ -253,6 +253,7 @@ magic-trailing-comma = Respect docstring-code = Disabled docstring-code-line-width = "dynamic" preview = Enabled +target_version = Py38 ``` ```python diff --git a/crates/ruff_python_formatter/tests/snapshots/format@tab_width.py.snap b/crates/ruff_python_formatter/tests/snapshots/format@tab_width.py.snap index ea85babc1bab74..a3a7b0adfe93d6 100644 --- a/crates/ruff_python_formatter/tests/snapshots/format@tab_width.py.snap +++ b/crates/ruff_python_formatter/tests/snapshots/format@tab_width.py.snap @@ -26,6 +26,7 @@ magic-trailing-comma = Respect docstring-code = Disabled docstring-code-line-width = "dynamic" preview = Disabled +target_version = Py38 ``` ```python @@ -51,6 +52,7 @@ magic-trailing-comma = Respect docstring-code = Disabled docstring-code-line-width = "dynamic" preview = Disabled +target_version = Py38 ``` ```python @@ -79,6 +81,7 @@ magic-trailing-comma = Respect docstring-code = Disabled docstring-code-line-width = "dynamic" preview = Disabled +target_version = Py38 ``` ```python diff --git a/crates/ruff_workspace/src/configuration.rs b/crates/ruff_workspace/src/configuration.rs index fe95418e69c437..e3c899f563259b 100644 --- a/crates/ruff_workspace/src/configuration.rs +++ b/crates/ruff_workspace/src/configuration.rs @@ -175,6 +175,14 @@ impl Configuration { let formatter = FormatterSettings { exclude: FilePatternSet::try_from_iter(format.exclude.unwrap_or_default())?, preview: format_preview, + target_version: match target_version { + PythonVersion::Py37 => ruff_python_formatter::PythonVersion::Py37, + PythonVersion::Py38 => ruff_python_formatter::PythonVersion::Py38, + PythonVersion::Py39 => ruff_python_formatter::PythonVersion::Py39, + PythonVersion::Py310 => ruff_python_formatter::PythonVersion::Py310, + PythonVersion::Py311 => ruff_python_formatter::PythonVersion::Py311, + PythonVersion::Py312 => ruff_python_formatter::PythonVersion::Py311, + }, line_width: self .line_length .map_or(format_defaults.line_width, |length| { diff --git a/crates/ruff_workspace/src/settings.rs b/crates/ruff_workspace/src/settings.rs index fe7c82a85e37f8..446cc95173bd04 100644 --- a/crates/ruff_workspace/src/settings.rs +++ b/crates/ruff_workspace/src/settings.rs @@ -117,6 +117,7 @@ impl FileResolverSettings { pub struct FormatterSettings { pub exclude: FilePatternSet, pub preview: PreviewMode, + pub target_version: ruff_python_formatter::PythonVersion, pub line_width: LineWidth, @@ -157,6 +158,7 @@ impl FormatterSettings { }; PyFormatOptions::from_source_type(source_type) + .with_target_version(self.target_version) .with_indent_style(self.indent_style) .with_indent_width(self.indent_width) .with_quote_style(self.quote_style) @@ -175,6 +177,7 @@ impl Default for FormatterSettings { Self { exclude: FilePatternSet::default(), + target_version: default_options.target_version(), preview: PreviewMode::Disabled, line_width: default_options.line_width(), line_ending: LineEnding::Auto,