diff --git a/crates/ruff/tests/lint.rs b/crates/ruff/tests/lint.rs index efa9b08429..25420017fe 100644 --- a/crates/ruff/tests/lint.rs +++ b/crates/ruff/tests/lint.rs @@ -5780,28 +5780,6 @@ match 42: # invalid-syntax Ok(()) } -#[test] -fn future_annotations_preview_warning() { - assert_cmd_snapshot!( - Command::new(get_cargo_bin(BIN_NAME)) - .args(STDIN_BASE_OPTIONS) - .args(["--config", "lint.future-annotations = true"]) - .args(["--select", "F"]) - .arg("--no-preview") - .arg("-") - .pass_stdin("1"), - @r" - success: true - exit_code: 0 - ----- stdout ----- - All checks passed! - - ----- stderr ----- - warning: The `lint.future-annotations` setting will have no effect because `preview` is disabled - ", - ); -} - #[test] fn up045_nested_optional_flatten_all() { let contents = "\ diff --git a/crates/ruff_linter/src/preview.rs b/crates/ruff_linter/src/preview.rs index 3562493e85..31d0d5b874 100644 --- a/crates/ruff_linter/src/preview.rs +++ b/crates/ruff_linter/src/preview.rs @@ -207,11 +207,6 @@ pub(crate) const fn is_safe_super_call_with_parameters_fix_enabled( settings.preview.is_enabled() } -// https://github.com/astral-sh/ruff/pull/19100 -pub(crate) const fn is_add_future_annotations_imports_enabled(settings: &LinterSettings) -> bool { - settings.preview.is_enabled() -} - // https://github.com/astral-sh/ruff/pull/19851 pub(crate) const fn is_maxsplit_without_separator_fix_enabled(settings: &LinterSettings) -> bool { settings.preview.is_enabled() diff --git a/crates/ruff_linter/src/rules/flake8_type_checking/helpers.rs b/crates/ruff_linter/src/rules/flake8_type_checking/helpers.rs index 6a78d9d16c..03368702d3 100644 --- a/crates/ruff_linter/src/rules/flake8_type_checking/helpers.rs +++ b/crates/ruff_linter/src/rules/flake8_type_checking/helpers.rs @@ -66,7 +66,7 @@ impl TypingReference { } // prefer `from __future__ import annotations` to quoting - if settings.future_annotations() + if settings.future_annotations && !reference.in_typing_only_annotation() && reference.in_runtime_evaluated_annotation() { diff --git a/crates/ruff_linter/src/rules/flake8_type_checking/mod.rs b/crates/ruff_linter/src/rules/flake8_type_checking/mod.rs index 2b66b3a567..fd8f08626d 100644 --- a/crates/ruff_linter/src/rules/flake8_type_checking/mod.rs +++ b/crates/ruff_linter/src/rules/flake8_type_checking/mod.rs @@ -14,7 +14,6 @@ mod tests { use test_case::test_case; use crate::registry::{Linter, Rule}; - use crate::settings::types::PreviewMode; use crate::test::{test_path, test_snippet}; use crate::{assert_diagnostics, settings}; @@ -86,7 +85,6 @@ mod tests { Path::new("flake8_type_checking").join(path).as_path(), &settings::LinterSettings { future_annotations: true, - preview: PreviewMode::Enabled, // also enable quoting annotations to check the interaction. the future import // should take precedence. flake8_type_checking: super::settings::Settings { diff --git a/crates/ruff_linter/src/rules/flake8_type_checking/rules/typing_only_runtime_import.rs b/crates/ruff_linter/src/rules/flake8_type_checking/rules/typing_only_runtime_import.rs index 1d216a6680..9327f6803c 100644 --- a/crates/ruff_linter/src/rules/flake8_type_checking/rules/typing_only_runtime_import.rs +++ b/crates/ruff_linter/src/rules/flake8_type_checking/rules/typing_only_runtime_import.rs @@ -38,6 +38,13 @@ use crate::{Fix, FixAvailability, Violation}; /// [`lint.flake8-type-checking.runtime-evaluated-decorators`] settings to mark them /// as such. /// +/// If [`lint.future-annotations`] is set to `true`, `from __future__ import +/// annotations` will be added if doing so would enable an import to be +/// moved into an `if TYPE_CHECKING:` block. This takes precedence over the +/// [`lint.flake8-type-checking.quote-annotations`] setting described above if +/// both settings are enabled. +/// +/// /// ## Example /// ```python /// from __future__ import annotations @@ -63,14 +70,6 @@ use crate::{Fix, FixAvailability, Violation}; /// return len(sized) /// ``` /// -/// -/// ## Preview -/// If [`lint.future-annotations`] is set to `true`, `from __future__ import -/// annotations` will be added if doing so would enable an import to be moved into an `if -/// TYPE_CHECKING:` block. This takes precedence over the -/// [`lint.flake8-type-checking.quote-annotations`] setting described above if both settings are -/// enabled. -/// /// ## Options /// - `lint.flake8-type-checking.quote-annotations` /// - `lint.flake8-type-checking.runtime-evaluated-base-classes` @@ -122,6 +121,12 @@ impl Violation for TypingOnlyFirstPartyImport { /// [`lint.flake8-type-checking.runtime-evaluated-decorators`] settings to mark them /// as such. /// +/// If [`lint.future-annotations`] is set to `true`, `from __future__ import +/// annotations` will be added if doing so would enable an import to be +/// moved into an `if TYPE_CHECKING:` block. This takes precedence over the +/// [`lint.flake8-type-checking.quote-annotations`] setting described above if +/// both settings are enabled. +/// /// ## Example /// ```python /// from __future__ import annotations @@ -147,13 +152,6 @@ impl Violation for TypingOnlyFirstPartyImport { /// return len(df) /// ``` /// -/// ## Preview -/// If [`lint.future-annotations`] is set to `true`, `from __future__ import -/// annotations` will be added if doing so would enable an import to be moved into an `if -/// TYPE_CHECKING:` block. This takes precedence over the -/// [`lint.flake8-type-checking.quote-annotations`] setting described above if both settings are -/// enabled. -/// /// ## Options /// - `lint.flake8-type-checking.quote-annotations` /// - `lint.flake8-type-checking.runtime-evaluated-base-classes` @@ -205,6 +203,12 @@ impl Violation for TypingOnlyThirdPartyImport { /// [`lint.flake8-type-checking.runtime-evaluated-decorators`] settings to mark them /// as such. /// +/// If [`lint.future-annotations`] is set to `true`, `from __future__ import +/// annotations` will be added if doing so would enable an import to be +/// moved into an `if TYPE_CHECKING:` block. This takes precedence over the +/// [`lint.flake8-type-checking.quote-annotations`] setting described above if +/// both settings are enabled. +/// /// ## Example /// ```python /// from __future__ import annotations @@ -230,15 +234,6 @@ impl Violation for TypingOnlyThirdPartyImport { /// return str(path) /// ``` /// -/// ## Preview -/// -/// When [preview](https://docs.astral.sh/ruff/preview/) is enabled, if -/// [`lint.future-annotations`] is set to `true`, `from __future__ import -/// annotations` will be added if doing so would enable an import to be moved into an `if -/// TYPE_CHECKING:` block. This takes precedence over the -/// [`lint.flake8-type-checking.quote-annotations`] setting described above if both settings are -/// enabled. -/// /// ## Options /// - `lint.flake8-type-checking.quote-annotations` /// - `lint.flake8-type-checking.runtime-evaluated-base-classes` @@ -287,7 +282,7 @@ pub(crate) fn typing_only_runtime_import( // If we can't add a `__future__` import and in un-strict mode, don't flag typing-only // imports that are implicitly loaded by way of a valid runtime import. - if !checker.settings().future_annotations() + if !checker.settings().future_annotations && !checker.settings().flake8_type_checking.strict && runtime_imports .iter() diff --git a/crates/ruff_linter/src/rules/pyupgrade/mod.rs b/crates/ruff_linter/src/rules/pyupgrade/mod.rs index aa2f24313c..313c0e0da0 100644 --- a/crates/ruff_linter/src/rules/pyupgrade/mod.rs +++ b/crates/ruff_linter/src/rules/pyupgrade/mod.rs @@ -147,7 +147,6 @@ mod tests { let diagnostics = test_path( Path::new("pyupgrade").join(path).as_path(), &settings::LinterSettings { - preview: PreviewMode::Enabled, future_annotations: true, ..settings::LinterSettings::for_rule(rule_code) }, diff --git a/crates/ruff_linter/src/rules/pyupgrade/rules/quoted_annotation.rs b/crates/ruff_linter/src/rules/pyupgrade/rules/quoted_annotation.rs index 834616edaa..e641553f84 100644 --- a/crates/ruff_linter/src/rules/pyupgrade/rules/quoted_annotation.rs +++ b/crates/ruff_linter/src/rules/pyupgrade/rules/quoted_annotation.rs @@ -102,7 +102,7 @@ impl AlwaysFixableViolation for QuotedAnnotation { /// UP037 pub(crate) fn quoted_annotation(checker: &Checker, annotation: &str, range: TextRange) { - let add_future_import = checker.settings().future_annotations() + let add_future_import = checker.settings().future_annotations && checker.semantic().in_runtime_evaluated_annotation(); if !(checker.semantic().in_typing_only_annotation() || add_future_import) { diff --git a/crates/ruff_linter/src/rules/ruff/mod.rs b/crates/ruff_linter/src/rules/ruff/mod.rs index 13d03bee51..8f0007a344 100644 --- a/crates/ruff_linter/src/rules/ruff/mod.rs +++ b/crates/ruff_linter/src/rules/ruff/mod.rs @@ -649,7 +649,6 @@ mod tests { let diagnostics = test_path( Path::new("ruff").join(path).as_path(), &settings::LinterSettings { - preview: PreviewMode::Enabled, future_annotations: true, unresolved_target_version: PythonVersion::PY39.into(), ..settings::LinterSettings::for_rule(rule_code) diff --git a/crates/ruff_linter/src/rules/ruff/rules/implicit_optional.rs b/crates/ruff_linter/src/rules/ruff/rules/implicit_optional.rs index 35294f2843..18fc913f24 100644 --- a/crates/ruff_linter/src/rules/ruff/rules/implicit_optional.rs +++ b/crates/ruff_linter/src/rules/ruff/rules/implicit_optional.rs @@ -19,6 +19,10 @@ use crate::rules::ruff::typing::type_hint_explicitly_allows_none; /// Checks for the use of implicit `Optional` in type annotations when the /// default parameter value is `None`. /// +/// If [`lint.future-annotations`] is set to `true`, `from __future__ import +/// annotations` will be added if doing so would allow using the `|` operator on +/// a Python version before 3.10. +/// /// ## Why is this bad? /// Implicit `Optional` is prohibited by [PEP 484]. It is confusing and /// inconsistent with the rest of the type system. @@ -73,12 +77,6 @@ use crate::rules::ruff::typing::type_hint_explicitly_allows_none; /// - `target-version` /// - `lint.future-annotations` /// -/// ## Preview -/// -/// When [preview] is enabled, if [`lint.future-annotations`] is set to `true`, -/// `from __future__ import annotations` will be added if doing so would allow using the `|` -/// operator on a Python version before 3.10. -/// /// ## Fix safety /// /// This fix is always marked as unsafe because it can change the behavior of code that relies on @@ -217,7 +215,7 @@ pub(crate) fn implicit_optional(checker: &Checker, parameters: &Parameters) { }; let conversion_type = if checker.target_version() >= PythonVersion::PY310 - || checker.settings().future_annotations() + || checker.settings().future_annotations { ConversionType::BinOpOr } else { diff --git a/crates/ruff_linter/src/settings/mod.rs b/crates/ruff_linter/src/settings/mod.rs index 4f0aa79194..b94e4edafb 100644 --- a/crates/ruff_linter/src/settings/mod.rs +++ b/crates/ruff_linter/src/settings/mod.rs @@ -475,11 +475,6 @@ impl LinterSettings { .is_match(path) .map_or(self.unresolved_target_version, TargetVersion::from) } - - pub fn future_annotations(&self) -> bool { - // TODO(brent) we can just access the field directly once this is stabilized. - self.future_annotations && crate::preview::is_add_future_annotations_imports_enabled(self) - } } impl Default for LinterSettings { diff --git a/crates/ruff_workspace/src/configuration.rs b/crates/ruff_workspace/src/configuration.rs index fef7148f64..d916ff0324 100644 --- a/crates/ruff_workspace/src/configuration.rs +++ b/crates/ruff_workspace/src/configuration.rs @@ -257,12 +257,6 @@ impl Configuration { conflicting_import_settings(&isort, &flake8_import_conventions)?; let future_annotations = lint.future_annotations.unwrap_or_default(); - if lint_preview.is_disabled() && future_annotations { - warn_user_once!( - "The `lint.future-annotations` setting will have no effect \ - because `preview` is disabled" - ); - } Ok(Settings { cache_dir: self diff --git a/crates/ruff_workspace/src/options.rs b/crates/ruff_workspace/src/options.rs index 5578f4e504..d57a170115 100644 --- a/crates/ruff_workspace/src/options.rs +++ b/crates/ruff_workspace/src/options.rs @@ -537,8 +537,6 @@ pub struct LintOptions { /// For example, `TC001`, `TC002`, and `TC003` can move more imports into `TYPE_CHECKING` blocks /// if `__future__` annotations are enabled. /// - /// This setting is currently in [preview](https://docs.astral.sh/ruff/preview/) and requires - /// preview mode to be enabled to have any effect. #[option( default = "false", value_type = "bool", diff --git a/ruff.schema.json b/ruff.schema.json index dc3585c974..97fec6ae32 100644 --- a/ruff.schema.json +++ b/ruff.schema.json @@ -2291,7 +2291,7 @@ ] }, "future-annotations": { - "description": "Whether to allow rules to add `from __future__ import annotations` in cases where this would simplify a fix or enable a new diagnostic.\n\nFor example, `TC001`, `TC002`, and `TC003` can move more imports into `TYPE_CHECKING` blocks if `__future__` annotations are enabled.\n\nThis setting is currently in [preview](https://docs.astral.sh/ruff/preview/) and requires preview mode to be enabled to have any effect.", + "description": "Whether to allow rules to add `from __future__ import annotations` in cases where this would simplify a fix or enable a new diagnostic.\n\nFor example, `TC001`, `TC002`, and `TC003` can move more imports into `TYPE_CHECKING` blocks if `__future__` annotations are enabled.", "type": [ "boolean", "null"