Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ info:
- concise
- "--show-settings"
- test.py
snapshot_kind: text
---
success: true
exit_code: 0
Expand Down Expand Up @@ -265,7 +264,7 @@ linter.ruff.parenthesize_tuple_in_subscript = false

# Formatter Settings
formatter.exclude = []
formatter.unresolved_target_version = 3.9
formatter.unresolved_target_version = 3.10
formatter.per_file_target_version = {}
formatter.preview = disabled
formatter.line_width = 88
Expand All @@ -280,7 +279,7 @@ formatter.docstring_code_line_width = dynamic
# Analyze Settings
analyze.exclude = []
analyze.preview = disabled
analyze.target_version = 3.9
analyze.target_version = 3.10
analyze.string_imports = disabled
analyze.extension = ExtensionMapping({})
analyze.include_dependencies = {}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ info:
- concise
- "--show-settings"
- foo/test.py
snapshot_kind: text
---
success: true
exit_code: 0
Expand Down Expand Up @@ -265,7 +264,7 @@ linter.ruff.parenthesize_tuple_in_subscript = false

# Formatter Settings
formatter.exclude = []
formatter.unresolved_target_version = 3.9
formatter.unresolved_target_version = 3.10
formatter.per_file_target_version = {}
formatter.preview = disabled
formatter.line_width = 88
Expand All @@ -280,7 +279,7 @@ formatter.docstring_code_line_width = dynamic
# Analyze Settings
analyze.exclude = []
analyze.preview = disabled
analyze.target_version = 3.9
analyze.target_version = 3.10
analyze.string_imports = disabled
analyze.extension = ExtensionMapping({})
analyze.include_dependencies = {}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,6 @@ class Bar:
]


# OK: Allow named expressions in annotations.
# This is no longer allowed on Python 3.14+
x: (y := 1)
print(y)
Original file line number Diff line number Diff line change
Expand Up @@ -13,16 +13,16 @@

# References to a class from inside the class:
class C:
other: C = ... # valid in a `.pyi` stub file, not in a `.py` runtime file
other: C = ... # valid in a `.pyi` stub file, and in a `.py` runtime file with deferred annotations
other2: "C" = ... # always okay
def from_str(self, s: str) -> C: ... # valid in a `.pyi` stub file, not in a `.py` runtime file
def from_str(self, s: str) -> C: ... # valid in a `.pyi` stub file, and in a `.py` runtime file with deferred annotations
def from_str2(self, s: str) -> "C": ... # always okay

# Circular references:
class A:
foo: B # valid in a `.pyi` stub file, not in a `.py` runtime file
foo: B # valid in a `.pyi` stub file, and in a `.py` runtime file with deferred annotations
foo2: "B" # always okay
bar: dict[str, B] # valid in a `.pyi` stub file, not in a `.py` runtime file
bar: dict[str, B] # valid in a `.pyi` stub file, and in a `.py` runtime file with deferred annotations
bar2: dict[str, "A"] # always okay

class B:
Expand Down
19 changes: 1 addition & 18 deletions crates/ruff_linter/src/linter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,14 +27,13 @@ use crate::fix::{FixResult, fix_file};
use crate::message::create_syntax_error_diagnostic;
use crate::noqa::add_noqa;
use crate::package::PackageRoot;
use crate::preview::is_py314_support_enabled;
use crate::registry::Rule;
#[cfg(any(feature = "test-rules", test))]
use crate::rules::ruff::rules::test_rules::{self, TEST_RULES, TestRule};
use crate::settings::types::UnsafeFixes;
use crate::settings::{LinterSettings, TargetVersion, flags};
use crate::source_kind::SourceKind;
use crate::{Locator, directives, fs, warn_user_once};
use crate::{Locator, directives, fs};

pub(crate) mod float;

Expand Down Expand Up @@ -442,14 +441,6 @@ pub fn lint_only(
) -> LinterResult {
let target_version = settings.resolve_target_version(path);

if matches!(target_version, TargetVersion(Some(PythonVersion::PY314)))
&& !is_py314_support_enabled(settings)
{
warn_user_once!(
"Support for Python 3.14 is in preview and may undergo breaking changes. Enable `preview` to remove this warning."
);
}

let parsed = source.into_parsed(source_kind, source_type, target_version.parser_version());

// Map row and column locations to byte slices (lazily).
Expand Down Expand Up @@ -551,14 +542,6 @@ pub fn lint_fix<'a>(

let target_version = settings.resolve_target_version(path);

if matches!(target_version, TargetVersion(Some(PythonVersion::PY314)))
&& !is_py314_support_enabled(settings)
{
warn_user_once!(
"Support for Python 3.14 is in preview and may undergo breaking changes. Enable `preview` to remove this warning."
);
}

// Continuously fix until the source code stabilizes.
loop {
// Parse once.
Expand Down
4 changes: 0 additions & 4 deletions crates/ruff_linter/src/preview.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,6 @@

use crate::settings::LinterSettings;

pub(crate) const fn is_py314_support_enabled(settings: &LinterSettings) -> bool {
settings.preview.is_enabled()
}

// Rule-specific behavior

// https://github.com/astral-sh/ruff/pull/15541
Expand Down
36 changes: 31 additions & 5 deletions crates/ruff_linter/src/rules/fastapi/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,12 @@ mod tests {
use anyhow::Result;
use test_case::test_case;

use ruff_python_ast::PythonVersion;

use crate::registry::Rule;
use crate::settings::LinterSettings;
use crate::test::test_path;
use crate::{assert_diagnostics, settings};
use crate::{assert_diagnostics, assert_diagnostics_diff};

#[test_case(Rule::FastApiRedundantResponseModel, Path::new("FAST001.py"))]
#[test_case(Rule::FastApiNonAnnotatedDependency, Path::new("FAST002_0.py"))]
Expand All @@ -20,12 +23,35 @@ mod tests {
let snapshot = format!("{}_{}", rule_code.name(), path.to_string_lossy());
let diagnostics = test_path(
Path::new("fastapi").join(path).as_path(),
&settings::LinterSettings::for_rule(rule_code),
&LinterSettings::for_rule(rule_code),
)?;
assert_diagnostics!(snapshot, diagnostics);
Ok(())
}

#[test_case(Rule::FastApiRedundantResponseModel, Path::new("FAST001.py"))]
#[test_case(Rule::FastApiUnusedPathParameter, Path::new("FAST003.py"))]
fn deferred_annotations_diff(rule_code: Rule, path: &Path) -> Result<()> {
let snapshot = format!(
"deferred_annotations_diff_{}_{}",
rule_code.name(),
path.to_string_lossy()
);
assert_diagnostics_diff!(
snapshot,
Path::new("fastapi").join(path).as_path(),
&LinterSettings {
unresolved_target_version: PythonVersion::PY313.into(),
..LinterSettings::for_rule(rule_code)
},
&LinterSettings {
unresolved_target_version: PythonVersion::PY314.into(),
..LinterSettings::for_rule(rule_code)
},
);
Ok(())
}

// FAST002 autofixes use `typing_extensions` on Python 3.8,
// since `typing.Annotated` was added in Python 3.9
#[test_case(Rule::FastApiNonAnnotatedDependency, Path::new("FAST002_0.py"))]
Expand All @@ -34,9 +60,9 @@ mod tests {
let snapshot = format!("{}_{}_py38", rule_code.name(), path.to_string_lossy());
let diagnostics = test_path(
Path::new("fastapi").join(path).as_path(),
&settings::LinterSettings {
unresolved_target_version: ruff_python_ast::PythonVersion::PY38.into(),
..settings::LinterSettings::for_rule(rule_code)
&LinterSettings {
unresolved_target_version: PythonVersion::PY38.into(),
..LinterSettings::for_rule(rule_code)
},
)?;
assert_diagnostics!(snapshot, diagnostics);
Expand Down
Loading