Switch to Rust 2024 edition (#18129)

This commit is contained in:
Micha Reiser 2025-05-16 13:25:28 +02:00 committed by GitHub
parent e67b35743a
commit 9ae698fe30
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
1082 changed files with 4211 additions and 3300 deletions

View file

@ -495,7 +495,7 @@ jobs:
persist-credentials: false persist-credentials: false
- uses: Swatinem/rust-cache@9d47c6ad4b02e050fd481d890b2ea34778fd09d6 # v2.7.8 - uses: Swatinem/rust-cache@9d47c6ad4b02e050fd481d890b2ea34778fd09d6 # v2.7.8
- name: "Install Rust toolchain" - name: "Install Rust toolchain"
run: rustup component add rustfmt run: rustup show
# Run all code generation scripts, and verify that the current output is # Run all code generation scripts, and verify that the current output is
# already checked into git. # already checked into git.
- run: python crates/ruff_python_ast/generate.py - run: python crates/ruff_python_ast/generate.py
@ -504,12 +504,10 @@ jobs:
# Verify that adding a plugin or rule produces clean code. # Verify that adding a plugin or rule produces clean code.
- run: ./scripts/add_rule.py --name DoTheThing --prefix F --code 999 --linter pyflakes - run: ./scripts/add_rule.py --name DoTheThing --prefix F --code 999 --linter pyflakes
- run: cargo check - run: cargo check
- run: cargo fmt --all --check
- run: | - run: |
./scripts/add_plugin.py test --url https://pypi.org/project/-test/0.1.0/ --prefix TST ./scripts/add_plugin.py test --url https://pypi.org/project/-test/0.1.0/ --prefix TST
./scripts/add_rule.py --name FirstRule --prefix TST --code 001 --linter test ./scripts/add_rule.py --name FirstRule --prefix TST --code 001 --linter test
- run: cargo check - run: cargo check
- run: cargo fmt --all --check
ecosystem: ecosystem:
name: "ecosystem" name: "ecosystem"

View file

@ -3,7 +3,7 @@ members = ["crates/*"]
resolver = "2" resolver = "2"
[workspace.package] [workspace.package]
edition = "2021" edition = "2024"
rust-version = "1.85" rust-version = "1.85"
homepage = "https://docs.astral.sh/ruff" homepage = "https://docs.astral.sh/ruff"
documentation = "https://docs.astral.sh/ruff" documentation = "https://docs.astral.sh/ruff"

View file

@ -8,7 +8,7 @@ use std::sync::Arc;
use crate::commands::completions::config::{OptionString, OptionStringParser}; use crate::commands::completions::config::{OptionString, OptionStringParser};
use anyhow::bail; use anyhow::bail;
use clap::builder::{TypedValueParser, ValueParserFactory}; use clap::builder::{TypedValueParser, ValueParserFactory};
use clap::{command, Parser, Subcommand}; use clap::{Parser, Subcommand, command};
use colored::Colorize; use colored::Colorize;
use itertools::Itertools; use itertools::Itertools;
use path_absolutize::path_dedot; use path_absolutize::path_dedot;
@ -1126,10 +1126,10 @@ impl std::fmt::Display for FormatRangeParseError {
write!( write!(
f, f,
"the start position '{start_invalid}' is greater than the end position '{end_invalid}'.\n {tip} Try switching start and end: '{end}-{start}'", "the start position '{start_invalid}' is greater than the end position '{end_invalid}'.\n {tip} Try switching start and end: '{end}-{start}'",
start_invalid=start.to_string().bold().yellow(), start_invalid = start.to_string().bold().yellow(),
end_invalid=end.to_string().bold().yellow(), end_invalid = end.to_string().bold().yellow(),
start=start.to_string().green().bold(), start = start.to_string().green().bold(),
end=end.to_string().green().bold() end = end.to_string().green().bold()
) )
} }
FormatRangeParseError::InvalidStart(inner) => inner.write(f, true), FormatRangeParseError::InvalidStart(inner) => inner.write(f, true),
@ -1230,30 +1230,36 @@ impl LineColumnParseError {
match self { match self {
LineColumnParseError::ColumnParseError(inner) => { LineColumnParseError::ColumnParseError(inner) => {
write!(f, "the {range}s column is not a valid number ({inner})'\n {tip} The format is 'line:column'.") write!(
f,
"the {range}s column is not a valid number ({inner})'\n {tip} The format is 'line:column'."
)
} }
LineColumnParseError::LineParseError(inner) => { LineColumnParseError::LineParseError(inner) => {
write!(f, "the {range} line is not a valid number ({inner})\n {tip} The format is 'line:column'.") write!(
f,
"the {range} line is not a valid number ({inner})\n {tip} The format is 'line:column'."
)
} }
LineColumnParseError::ZeroColumnIndex { line } => { LineColumnParseError::ZeroColumnIndex { line } => {
write!( write!(
f, f,
"the {range} column is 0, but it should be 1 or greater.\n {tip} The column numbers start at 1.\n {tip} Try {suggestion} instead.", "the {range} column is 0, but it should be 1 or greater.\n {tip} The column numbers start at 1.\n {tip} Try {suggestion} instead.",
suggestion=format!("{line}:1").green().bold() suggestion = format!("{line}:1").green().bold()
) )
} }
LineColumnParseError::ZeroLineIndex { column } => { LineColumnParseError::ZeroLineIndex { column } => {
write!( write!(
f, f,
"the {range} line is 0, but it should be 1 or greater.\n {tip} The line numbers start at 1.\n {tip} Try {suggestion} instead.", "the {range} line is 0, but it should be 1 or greater.\n {tip} The line numbers start at 1.\n {tip} Try {suggestion} instead.",
suggestion=format!("1:{column}").green().bold() suggestion = format!("1:{column}").green().bold()
) )
} }
LineColumnParseError::ZeroLineAndColumnIndex => { LineColumnParseError::ZeroLineAndColumnIndex => {
write!( write!(
f, f,
"the {range} line and column are both 0, but they should be 1 or greater.\n {tip} The line and column numbers start at 1.\n {tip} Try {suggestion} instead.", "the {range} line and column are both 0, but they should be 1 or greater.\n {tip} The line and column numbers start at 1.\n {tip} Try {suggestion} instead.",
suggestion="1:1".to_string().green().bold() suggestion = "1:1".to_string().green().bold()
) )
} }
} }

View file

@ -3,8 +3,8 @@ use std::fs::{self, File};
use std::hash::Hasher; use std::hash::Hasher;
use std::io::{self, BufReader, Write}; use std::io::{self, BufReader, Write};
use std::path::{Path, PathBuf}; use std::path::{Path, PathBuf};
use std::sync::atomic::{AtomicU64, Ordering};
use std::sync::Mutex; use std::sync::Mutex;
use std::sync::atomic::{AtomicU64, Ordering};
use std::time::{Duration, SystemTime}; use std::time::{Duration, SystemTime};
use anyhow::{Context, Result}; use anyhow::{Context, Result};
@ -22,13 +22,13 @@ use ruff_cache::{CacheKey, CacheKeyHasher};
use ruff_diagnostics::Fix; use ruff_diagnostics::Fix;
use ruff_linter::message::{DiagnosticMessage, Message}; use ruff_linter::message::{DiagnosticMessage, Message};
use ruff_linter::package::PackageRoot; use ruff_linter::package::PackageRoot;
use ruff_linter::{warn_user, VERSION}; use ruff_linter::{VERSION, warn_user};
use ruff_macros::CacheKey; use ruff_macros::CacheKey;
use ruff_notebook::NotebookIndex; use ruff_notebook::NotebookIndex;
use ruff_source_file::SourceFileBuilder; use ruff_source_file::SourceFileBuilder;
use ruff_text_size::{TextRange, TextSize}; use ruff_text_size::{TextRange, TextSize};
use ruff_workspace::resolver::Resolver;
use ruff_workspace::Settings; use ruff_workspace::Settings;
use ruff_workspace::resolver::Resolver;
use crate::diagnostics::Diagnostics; use crate::diagnostics::Diagnostics;
@ -597,7 +597,7 @@ mod tests {
use std::time::SystemTime; use std::time::SystemTime;
use anyhow::Result; use anyhow::Result;
use filetime::{set_file_mtime, FileTime}; use filetime::{FileTime, set_file_mtime};
use itertools::Itertools; use itertools::Itertools;
use ruff_linter::settings::LinterSettings; use ruff_linter::settings::LinterSettings;
use test_case::test_case; use test_case::test_case;
@ -612,8 +612,8 @@ mod tests {
use crate::cache::{self, FileCache, FileCacheData, FileCacheKey}; use crate::cache::{self, FileCache, FileCacheData, FileCacheKey};
use crate::cache::{Cache, RelativePathBuf}; use crate::cache::{Cache, RelativePathBuf};
use crate::commands::format::{format_path, FormatCommandError, FormatMode, FormatResult}; use crate::commands::format::{FormatCommandError, FormatMode, FormatResult, format_path};
use crate::diagnostics::{lint_path, Diagnostics}; use crate::diagnostics::{Diagnostics, lint_path};
#[test_case("../ruff_linter/resources/test/fixtures", "ruff_tests/cache_same_results_ruff_linter"; "ruff_linter_fixtures")] #[test_case("../ruff_linter/resources/test/fixtures", "ruff_tests/cache_same_results_ruff_linter"; "ruff_linter_fixtures")]
#[test_case("../ruff_notebook/resources/test/fixtures", "ruff_tests/cache_same_results_ruff_notebook"; "ruff_notebook_fixtures")] #[test_case("../ruff_notebook/resources/test/fixtures", "ruff_tests/cache_same_results_ruff_notebook"; "ruff_notebook_fixtures")]

View file

@ -11,7 +11,7 @@ use ruff_linter::source_kind::SourceKind;
use ruff_linter::warn_user_once; use ruff_linter::warn_user_once;
use ruff_python_ast::{PySourceType, SourceType}; use ruff_python_ast::{PySourceType, SourceType};
use ruff_workspace::resolver::{ use ruff_workspace::resolver::{
match_exclusion, python_files_in_path, PyprojectConfig, ResolvedFile, PyprojectConfig, ResolvedFile, match_exclusion, python_files_in_path,
}; };
use crate::args::ConfigArguments; use crate::args::ConfigArguments;

View file

@ -1,6 +1,6 @@
use crate::args::{AnalyzeGraphArgs, ConfigArguments}; use crate::args::{AnalyzeGraphArgs, ConfigArguments};
use crate::resolve::resolve; use crate::resolve::resolve;
use crate::{resolve_default_files, ExitStatus}; use crate::{ExitStatus, resolve_default_files};
use anyhow::Result; use anyhow::Result;
use log::{debug, warn}; use log::{debug, warn};
use path_absolutize::CWD; use path_absolutize::CWD;
@ -9,7 +9,7 @@ use ruff_graph::{Direction, ImportMap, ModuleDb, ModuleImports};
use ruff_linter::package::PackageRoot; use ruff_linter::package::PackageRoot;
use ruff_linter::{warn_user, warn_user_once}; use ruff_linter::{warn_user, warn_user_once};
use ruff_python_ast::{PySourceType, SourceType}; use ruff_python_ast::{PySourceType, SourceType};
use ruff_workspace::resolver::{match_exclusion, python_files_in_path, ResolvedFile}; use ruff_workspace::resolver::{ResolvedFile, match_exclusion, python_files_in_path};
use rustc_hash::FxHashMap; use rustc_hash::FxHashMap;
use std::io::Write; use std::io::Write;
use std::path::{Path, PathBuf}; use std::path::{Path, PathBuf};

View file

@ -17,12 +17,12 @@ use ruff_linter::message::Message;
use ruff_linter::package::PackageRoot; use ruff_linter::package::PackageRoot;
use ruff_linter::registry::Rule; use ruff_linter::registry::Rule;
use ruff_linter::settings::types::UnsafeFixes; use ruff_linter::settings::types::UnsafeFixes;
use ruff_linter::settings::{flags, LinterSettings}; use ruff_linter::settings::{LinterSettings, flags};
use ruff_linter::{fs, warn_user_once, IOError}; use ruff_linter::{IOError, fs, warn_user_once};
use ruff_source_file::SourceFileBuilder; use ruff_source_file::SourceFileBuilder;
use ruff_text_size::{TextRange, TextSize}; use ruff_text_size::{TextRange, TextSize};
use ruff_workspace::resolver::{ use ruff_workspace::resolver::{
match_exclusion, python_files_in_path, PyprojectConfig, ResolvedFile, PyprojectConfig, ResolvedFile, match_exclusion, python_files_in_path,
}; };
use crate::args::ConfigArguments; use crate::args::ConfigArguments;
@ -228,9 +228,9 @@ mod test {
use ruff_linter::message::{Emitter, EmitterContext, TextEmitter}; use ruff_linter::message::{Emitter, EmitterContext, TextEmitter};
use ruff_linter::registry::Rule; use ruff_linter::registry::Rule;
use ruff_linter::settings::types::UnsafeFixes; use ruff_linter::settings::types::UnsafeFixes;
use ruff_linter::settings::{flags, LinterSettings}; use ruff_linter::settings::{LinterSettings, flags};
use ruff_workspace::resolver::{PyprojectConfig, PyprojectDiscoveryStrategy};
use ruff_workspace::Settings; use ruff_workspace::Settings;
use ruff_workspace::resolver::{PyprojectConfig, PyprojectDiscoveryStrategy};
use crate::args::ConfigArguments; use crate::args::ConfigArguments;

View file

@ -4,10 +4,10 @@ use anyhow::Result;
use ruff_linter::package::PackageRoot; use ruff_linter::package::PackageRoot;
use ruff_linter::packaging; use ruff_linter::packaging;
use ruff_linter::settings::flags; use ruff_linter::settings::flags;
use ruff_workspace::resolver::{match_exclusion, python_file_at_path, PyprojectConfig, Resolver}; use ruff_workspace::resolver::{PyprojectConfig, Resolver, match_exclusion, python_file_at_path};
use crate::args::ConfigArguments; use crate::args::ConfigArguments;
use crate::diagnostics::{lint_stdin, Diagnostics}; use crate::diagnostics::{Diagnostics, lint_stdin};
use crate::stdin::{parrot_stdin, read_from_stdin}; use crate::stdin::{parrot_stdin, read_from_stdin};
/// Run the linter over a single file, read from `stdin`. /// Run the linter over a single file, read from `stdin`.

View file

@ -1,4 +1,4 @@
use anyhow::{anyhow, Result}; use anyhow::{Result, anyhow};
use crate::args::HelpFormat; use crate::args::HelpFormat;

View file

@ -1,7 +1,7 @@
use std::fmt::{Display, Formatter}; use std::fmt::{Display, Formatter};
use std::fs::File; use std::fs::File;
use std::io; use std::io;
use std::io::{stderr, stdout, Write}; use std::io::{Write, stderr, stdout};
use std::path::{Path, PathBuf}; use std::path::{Path, PathBuf};
use std::time::Instant; use std::time::Instant;
@ -16,7 +16,7 @@ use rustc_hash::FxHashSet;
use thiserror::Error; use thiserror::Error;
use tracing::debug; use tracing::debug;
use ruff_db::panic::{catch_unwind, PanicError}; use ruff_db::panic::{PanicError, catch_unwind};
use ruff_diagnostics::SourceMap; use ruff_diagnostics::SourceMap;
use ruff_linter::fs; use ruff_linter::fs;
use ruff_linter::logging::{DisplayParseError, LogLevel}; use ruff_linter::logging::{DisplayParseError, LogLevel};
@ -26,16 +26,16 @@ use ruff_linter::rules::flake8_quotes::settings::Quote;
use ruff_linter::source_kind::{SourceError, SourceKind}; use ruff_linter::source_kind::{SourceError, SourceKind};
use ruff_linter::warn_user_once; use ruff_linter::warn_user_once;
use ruff_python_ast::{PySourceType, SourceType}; use ruff_python_ast::{PySourceType, SourceType};
use ruff_python_formatter::{format_module_source, format_range, FormatModuleError, QuoteStyle}; use ruff_python_formatter::{FormatModuleError, QuoteStyle, format_module_source, format_range};
use ruff_source_file::LineIndex; use ruff_source_file::LineIndex;
use ruff_text_size::{TextLen, TextRange, TextSize}; use ruff_text_size::{TextLen, TextRange, TextSize};
use ruff_workspace::resolver::{match_exclusion, python_files_in_path, ResolvedFile, Resolver};
use ruff_workspace::FormatterSettings; use ruff_workspace::FormatterSettings;
use ruff_workspace::resolver::{ResolvedFile, Resolver, match_exclusion, python_files_in_path};
use crate::args::{ConfigArguments, FormatArguments, FormatRange}; use crate::args::{ConfigArguments, FormatArguments, FormatRange};
use crate::cache::{Cache, FileCacheKey, PackageCacheMap, PackageCaches}; use crate::cache::{Cache, FileCacheKey, PackageCacheMap, PackageCaches};
use crate::resolve::resolve; use crate::resolve::resolve;
use crate::{resolve_default_files, ExitStatus}; use crate::{ExitStatus, resolve_default_files};
#[derive(Debug, Copy, Clone, is_macro::Is)] #[derive(Debug, Copy, Clone, is_macro::Is)]
pub(crate) enum FormatMode { pub(crate) enum FormatMode {
@ -821,9 +821,14 @@ pub(super) fn warn_incompatible_formatter_settings(resolver: &Resolver) {
.collect(); .collect();
rule_names.sort(); rule_names.sort();
if let [rule] = rule_names.as_slice() { if let [rule] = rule_names.as_slice() {
warn_user_once!("The following rule may cause conflicts when used with the formatter: {rule}. To avoid unexpected behavior, we recommend disabling this rule, either by removing it from the `select` or `extend-select` configuration, or adding it to the `ignore` configuration."); warn_user_once!(
"The following rule may cause conflicts when used with the formatter: {rule}. To avoid unexpected behavior, we recommend disabling this rule, either by removing it from the `select` or `extend-select` configuration, or adding it to the `ignore` configuration."
);
} else { } else {
warn_user_once!("The following rules may cause conflicts when used with the formatter: {}. To avoid unexpected behavior, we recommend disabling these rules, either by removing them from the `select` or `extend-select` configuration, or adding them to the `ignore` configuration.", rule_names.join(", ")); warn_user_once!(
"The following rules may cause conflicts when used with the formatter: {}. To avoid unexpected behavior, we recommend disabling these rules, either by removing them from the `select` or `extend-select` configuration, or adding them to the `ignore` configuration.",
rule_names.join(", ")
);
} }
} }
@ -833,7 +838,9 @@ pub(super) fn warn_incompatible_formatter_settings(resolver: &Resolver) {
if setting.linter.rules.enabled(Rule::TabIndentation) if setting.linter.rules.enabled(Rule::TabIndentation)
&& setting.formatter.indent_style.is_tab() && setting.formatter.indent_style.is_tab()
{ {
warn_user_once!("The `format.indent-style=\"tab\"` option is incompatible with `W191`, which lints against all uses of tabs. We recommend disabling these rules when using the formatter, which enforces a consistent indentation style. Alternatively, set the `format.indent-style` option to `\"space\"`."); warn_user_once!(
"The `format.indent-style=\"tab\"` option is incompatible with `W191`, which lints against all uses of tabs. We recommend disabling these rules when using the formatter, which enforces a consistent indentation style. Alternatively, set the `format.indent-style` option to `\"space\"`."
);
} }
if !setting if !setting
@ -846,14 +853,18 @@ pub(super) fn warn_incompatible_formatter_settings(resolver: &Resolver) {
.enabled(Rule::MultiLineImplicitStringConcatenation) .enabled(Rule::MultiLineImplicitStringConcatenation)
&& !setting.linter.flake8_implicit_str_concat.allow_multiline && !setting.linter.flake8_implicit_str_concat.allow_multiline
{ {
warn_user_once!("The `lint.flake8-implicit-str-concat.allow-multiline = false` option is incompatible with the formatter unless `ISC001` is enabled. We recommend enabling `ISC001` or setting `allow-multiline=true`."); warn_user_once!(
"The `lint.flake8-implicit-str-concat.allow-multiline = false` option is incompatible with the formatter unless `ISC001` is enabled. We recommend enabling `ISC001` or setting `allow-multiline=true`."
);
} }
// Validate all rules that rely on tab styles. // Validate all rules that rely on tab styles.
if setting.linter.rules.enabled(Rule::DocstringTabIndentation) if setting.linter.rules.enabled(Rule::DocstringTabIndentation)
&& setting.formatter.indent_style.is_tab() && setting.formatter.indent_style.is_tab()
{ {
warn_user_once!("The `format.indent-style=\"tab\"` option is incompatible with `D206`, with requires space-based indentation. We recommend disabling these rules when using the formatter, which enforces a consistent indentation style. Alternatively, set the `format.indent-style` option to `\"space\"`."); warn_user_once!(
"The `format.indent-style=\"tab\"` option is incompatible with `D206`, with requires space-based indentation. We recommend disabling these rules when using the formatter, which enforces a consistent indentation style. Alternatively, set the `format.indent-style` option to `\"space\"`."
);
} }
// Validate all rules that rely on custom indent widths. // Validate all rules that rely on custom indent widths.
@ -862,7 +873,9 @@ pub(super) fn warn_incompatible_formatter_settings(resolver: &Resolver) {
Rule::IndentationWithInvalidMultipleComment, Rule::IndentationWithInvalidMultipleComment,
]) && setting.formatter.indent_width.value() != 4 ]) && setting.formatter.indent_width.value() != 4
{ {
warn_user_once!("The `format.indent-width` option with a value other than 4 is incompatible with `E111` and `E114`. We recommend disabling these rules when using the formatter, which enforces a consistent indentation width. Alternatively, set the `format.indent-width` option to `4`."); warn_user_once!(
"The `format.indent-width` option with a value other than 4 is incompatible with `E111` and `E114`. We recommend disabling these rules when using the formatter, which enforces a consistent indentation width. Alternatively, set the `format.indent-width` option to `4`."
);
} }
// Validate all rules that rely on quote styles. // Validate all rules that rely on quote styles.
@ -876,10 +889,14 @@ pub(super) fn warn_incompatible_formatter_settings(resolver: &Resolver) {
setting.formatter.quote_style, setting.formatter.quote_style,
) { ) {
(Quote::Double, QuoteStyle::Single) => { (Quote::Double, QuoteStyle::Single) => {
warn_user_once!("The `flake8-quotes.inline-quotes=\"double\"` option is incompatible with the formatter's `format.quote-style=\"single\"`. We recommend disabling `Q000` and `Q003` when using the formatter, which enforces a consistent quote style. Alternatively, set both options to either `\"single\"` or `\"double\"`."); warn_user_once!(
"The `flake8-quotes.inline-quotes=\"double\"` option is incompatible with the formatter's `format.quote-style=\"single\"`. We recommend disabling `Q000` and `Q003` when using the formatter, which enforces a consistent quote style. Alternatively, set both options to either `\"single\"` or `\"double\"`."
);
} }
(Quote::Single, QuoteStyle::Double) => { (Quote::Single, QuoteStyle::Double) => {
warn_user_once!("The `flake8-quotes.inline-quotes=\"single\"` option is incompatible with the formatter's `format.quote-style=\"double\"`. We recommend disabling `Q000` and `Q003` when using the formatter, which enforces a consistent quote style. Alternatively, set both options to either `\"single\"` or `\"double\"`."); warn_user_once!(
"The `flake8-quotes.inline-quotes=\"single\"` option is incompatible with the formatter's `format.quote-style=\"double\"`. We recommend disabling `Q000` and `Q003` when using the formatter, which enforces a consistent quote style. Alternatively, set both options to either `\"single\"` or `\"double\"`."
);
} }
_ => {} _ => {}
} }
@ -892,7 +909,9 @@ pub(super) fn warn_incompatible_formatter_settings(resolver: &Resolver) {
QuoteStyle::Single | QuoteStyle::Double QuoteStyle::Single | QuoteStyle::Double
) )
{ {
warn_user_once!("The `flake8-quotes.multiline-quotes=\"single\"` option is incompatible with the formatter. We recommend disabling `Q001` when using the formatter, which enforces double quotes for multiline strings. Alternatively, set the `flake8-quotes.multiline-quotes` option to `\"double\"`.`"); warn_user_once!(
"The `flake8-quotes.multiline-quotes=\"single\"` option is incompatible with the formatter. We recommend disabling `Q001` when using the formatter, which enforces double quotes for multiline strings. Alternatively, set the `flake8-quotes.multiline-quotes` option to `\"double\"`.`"
);
} }
if setting.linter.rules.enabled(Rule::BadQuotesDocstring) if setting.linter.rules.enabled(Rule::BadQuotesDocstring)
@ -902,7 +921,9 @@ pub(super) fn warn_incompatible_formatter_settings(resolver: &Resolver) {
QuoteStyle::Single | QuoteStyle::Double QuoteStyle::Single | QuoteStyle::Double
) )
{ {
warn_user_once!("The `flake8-quotes.docstring-quotes=\"single\"` option is incompatible with the formatter. We recommend disabling `Q002` when using the formatter, which enforces double quotes for docstrings. Alternatively, set the `flake8-quotes.docstring-quotes` option to `\"double\"`.`"); warn_user_once!(
"The `flake8-quotes.docstring-quotes=\"single\"` option is incompatible with the formatter. We recommend disabling `Q002` when using the formatter, which enforces double quotes for docstrings. Alternatively, set the `flake8-quotes.docstring-quotes` option to `\"double\"`.`"
);
} }
// Validate all isort settings. // Validate all isort settings.
@ -910,12 +931,16 @@ pub(super) fn warn_incompatible_formatter_settings(resolver: &Resolver) {
// The formatter removes empty lines if the value is larger than 2 but always inserts a empty line after imports. // The formatter removes empty lines if the value is larger than 2 but always inserts a empty line after imports.
// Two empty lines are okay because `isort` only uses this setting for top-level imports (not in nested blocks). // Two empty lines are okay because `isort` only uses this setting for top-level imports (not in nested blocks).
if !matches!(setting.linter.isort.lines_after_imports, 1 | 2 | -1) { if !matches!(setting.linter.isort.lines_after_imports, 1 | 2 | -1) {
warn_user_once!("The isort option `isort.lines-after-imports` with a value other than `-1`, `1` or `2` is incompatible with the formatter. To avoid unexpected behavior, we recommend setting the option to one of: `2`, `1`, or `-1` (default)."); warn_user_once!(
"The isort option `isort.lines-after-imports` with a value other than `-1`, `1` or `2` is incompatible with the formatter. To avoid unexpected behavior, we recommend setting the option to one of: `2`, `1`, or `-1` (default)."
);
} }
// Values larger than two get reduced to one line by the formatter if the import is in a nested block. // Values larger than two get reduced to one line by the formatter if the import is in a nested block.
if setting.linter.isort.lines_between_types > 1 { if setting.linter.isort.lines_between_types > 1 {
warn_user_once!("The isort option `isort.lines-between-types` with a value greater than 1 is incompatible with the formatter. To avoid unexpected behavior, we recommend setting the option to one of: `1` or `0` (default)."); warn_user_once!(
"The isort option `isort.lines-between-types` with a value greater than 1 is incompatible with the formatter. To avoid unexpected behavior, we recommend setting the option to one of: `1` or `0` (default)."
);
} }
// isort inserts a trailing comma which the formatter preserves, but only if `skip-magic-trailing-comma` isn't false. // isort inserts a trailing comma which the formatter preserves, but only if `skip-magic-trailing-comma` isn't false.
@ -924,11 +949,15 @@ pub(super) fn warn_incompatible_formatter_settings(resolver: &Resolver) {
&& !setting.linter.isort.force_single_line && !setting.linter.isort.force_single_line
{ {
if setting.linter.isort.force_wrap_aliases { if setting.linter.isort.force_wrap_aliases {
warn_user_once!("The isort option `isort.force-wrap-aliases` is incompatible with the formatter `format.skip-magic-trailing-comma=true` option. To avoid unexpected behavior, we recommend either setting `isort.force-wrap-aliases=false` or `format.skip-magic-trailing-comma=false`."); warn_user_once!(
"The isort option `isort.force-wrap-aliases` is incompatible with the formatter `format.skip-magic-trailing-comma=true` option. To avoid unexpected behavior, we recommend either setting `isort.force-wrap-aliases=false` or `format.skip-magic-trailing-comma=false`."
);
} }
if setting.linter.isort.split_on_trailing_comma { if setting.linter.isort.split_on_trailing_comma {
warn_user_once!("The isort option `isort.split-on-trailing-comma` is incompatible with the formatter `format.skip-magic-trailing-comma=true` option. To avoid unexpected behavior, we recommend either setting `isort.split-on-trailing-comma=false` or `format.skip-magic-trailing-comma=false`."); warn_user_once!(
"The isort option `isort.split-on-trailing-comma` is incompatible with the formatter `format.skip-magic-trailing-comma=true` option. To avoid unexpected behavior, we recommend either setting `isort.split-on-trailing-comma=false` or `format.skip-magic-trailing-comma=false`."
);
} }
} }
} }

View file

@ -6,17 +6,17 @@ use log::error;
use ruff_linter::source_kind::SourceKind; use ruff_linter::source_kind::SourceKind;
use ruff_python_ast::{PySourceType, SourceType}; use ruff_python_ast::{PySourceType, SourceType};
use ruff_workspace::resolver::{match_exclusion, python_file_at_path, Resolver};
use ruff_workspace::FormatterSettings; use ruff_workspace::FormatterSettings;
use ruff_workspace::resolver::{Resolver, match_exclusion, python_file_at_path};
use crate::ExitStatus;
use crate::args::{ConfigArguments, FormatArguments, FormatRange}; use crate::args::{ConfigArguments, FormatArguments, FormatRange};
use crate::commands::format::{ use crate::commands::format::{
format_source, warn_incompatible_formatter_settings, FormatCommandError, FormatMode, FormatCommandError, FormatMode, FormatResult, FormattedSource, format_source,
FormatResult, FormattedSource, warn_incompatible_formatter_settings,
}; };
use crate::resolve::resolve; use crate::resolve::resolve;
use crate::stdin::{parrot_stdin, read_from_stdin}; use crate::stdin::{parrot_stdin, read_from_stdin};
use crate::ExitStatus;
/// Run the formatter over a single file, read from `stdin`. /// Run the formatter over a single file, read from `stdin`.
pub(crate) fn format_stdin( pub(crate) fn format_stdin(

View file

@ -5,7 +5,7 @@ use anyhow::Result;
use itertools::Itertools; use itertools::Itertools;
use ruff_linter::warn_user_once; use ruff_linter::warn_user_once;
use ruff_workspace::resolver::{python_files_in_path, PyprojectConfig, ResolvedFile}; use ruff_workspace::resolver::{PyprojectConfig, ResolvedFile, python_files_in_path};
use crate::args::ConfigArguments; use crate::args::ConfigArguments;

View file

@ -1,10 +1,10 @@
use std::io::Write; use std::io::Write;
use std::path::PathBuf; use std::path::PathBuf;
use anyhow::{bail, Result}; use anyhow::{Result, bail};
use itertools::Itertools; use itertools::Itertools;
use ruff_workspace::resolver::{python_files_in_path, PyprojectConfig, ResolvedFile}; use ruff_workspace::resolver::{PyprojectConfig, ResolvedFile, python_files_in_path};
use crate::args::ConfigArguments; use crate::args::ConfigArguments;

View file

@ -14,14 +14,14 @@ use rustc_hash::FxHashMap;
use ruff_diagnostics::Diagnostic; use ruff_diagnostics::Diagnostic;
use ruff_linter::codes::Rule; use ruff_linter::codes::Rule;
use ruff_linter::linter::{lint_fix, lint_only, FixTable, FixerResult, LinterResult, ParseSource}; use ruff_linter::linter::{FixTable, FixerResult, LinterResult, ParseSource, lint_fix, lint_only};
use ruff_linter::message::Message; use ruff_linter::message::Message;
use ruff_linter::package::PackageRoot; use ruff_linter::package::PackageRoot;
use ruff_linter::pyproject_toml::lint_pyproject_toml; use ruff_linter::pyproject_toml::lint_pyproject_toml;
use ruff_linter::settings::types::UnsafeFixes; use ruff_linter::settings::types::UnsafeFixes;
use ruff_linter::settings::{flags, LinterSettings}; use ruff_linter::settings::{LinterSettings, flags};
use ruff_linter::source_kind::{SourceError, SourceKind}; use ruff_linter::source_kind::{SourceError, SourceKind};
use ruff_linter::{fs, IOError}; use ruff_linter::{IOError, fs};
use ruff_notebook::{Notebook, NotebookError, NotebookIndex}; use ruff_notebook::{Notebook, NotebookError, NotebookIndex};
use ruff_python_ast::{PySourceType, SourceType, TomlSourceType}; use ruff_python_ast::{PySourceType, SourceType, TomlSourceType};
use ruff_source_file::SourceFileBuilder; use ruff_source_file::SourceFileBuilder;

View file

@ -1,7 +1,7 @@
#![allow(clippy::print_stdout)] #![allow(clippy::print_stdout)]
use std::fs::File; use std::fs::File;
use std::io::{self, stdout, BufWriter, Write}; use std::io::{self, BufWriter, Write, stdout};
use std::num::NonZeroUsize; use std::num::NonZeroUsize;
use std::path::{Path, PathBuf}; use std::path::{Path, PathBuf};
use std::process::ExitCode; use std::process::ExitCode;
@ -11,10 +11,10 @@ use anyhow::Result;
use clap::CommandFactory; use clap::CommandFactory;
use colored::Colorize; use colored::Colorize;
use log::warn; use log::warn;
use notify::{recommended_watcher, RecursiveMode, Watcher}; use notify::{RecursiveMode, Watcher, recommended_watcher};
use args::{GlobalConfigArgs, ServerCommand}; use args::{GlobalConfigArgs, ServerCommand};
use ruff_linter::logging::{set_up_logging, LogLevel}; use ruff_linter::logging::{LogLevel, set_up_logging};
use ruff_linter::settings::flags::FixMode; use ruff_linter::settings::flags::FixMode;
use ruff_linter::settings::types::OutputFormat; use ruff_linter::settings::types::OutputFormat;
use ruff_linter::{fs, warn_user, warn_user_once}; use ruff_linter::{fs, warn_user, warn_user_once};
@ -488,7 +488,7 @@ pub fn check(args: CheckCommand, global_options: GlobalConfigArgs) -> Result<Exi
mod test_file_change_detector { mod test_file_change_detector {
use std::path::PathBuf; use std::path::PathBuf;
use crate::{change_detected, ChangeKind}; use crate::{ChangeKind, change_detected};
#[test] #[test]
fn detect_correct_file_change() { fn detect_correct_file_change() {

View file

@ -5,7 +5,7 @@ use clap::Parser;
use colored::Colorize; use colored::Colorize;
use ruff::args::Args; use ruff::args::Args;
use ruff::{run, ExitStatus}; use ruff::{ExitStatus, run};
#[cfg(target_os = "windows")] #[cfg(target_os = "windows")]
#[global_allocator] #[global_allocator]

View file

@ -6,7 +6,7 @@ use std::io::Write;
use anyhow::Result; use anyhow::Result;
use bitflags::bitflags; use bitflags::bitflags;
use colored::Colorize; use colored::Colorize;
use itertools::{iterate, Itertools}; use itertools::{Itertools, iterate};
use serde::Serialize; use serde::Serialize;
use ruff_linter::fs::relativize_path; use ruff_linter::fs::relativize_path;
@ -157,7 +157,8 @@ impl Printer {
} else { } else {
"es" "es"
}; };
writeln!(writer, writeln!(
writer,
"{fix_prefix} {} fixable with the `--fix` option ({} hidden fix{es} can be enabled with the `--unsafe-fixes` option).", "{fix_prefix} {} fixable with the `--fix` option ({} hidden fix{es} can be enabled with the `--unsafe-fixes` option).",
fixables.applicable, fixables.inapplicable_unsafe fixables.applicable, fixables.inapplicable_unsafe
)?; )?;
@ -175,7 +176,8 @@ impl Printer {
} else { } else {
"es" "es"
}; };
writeln!(writer, writeln!(
writer,
"No fixes available ({} hidden fix{es} can be enabled with the `--unsafe-fixes` option).", "No fixes available ({} hidden fix{es} can be enabled with the `--unsafe-fixes` option).",
fixables.inapplicable_unsafe fixables.inapplicable_unsafe
)?; )?;
@ -205,15 +207,27 @@ impl Printer {
if fixed > 0 { if fixed > 0 {
let s = if fixed == 1 { "" } else { "s" }; let s = if fixed == 1 { "" } else { "s" };
if self.fix_mode.is_apply() { if self.fix_mode.is_apply() {
writeln!(writer, "Fixed {fixed} error{s} ({unapplied} additional fix{es} available with `--unsafe-fixes`).")?; writeln!(
writer,
"Fixed {fixed} error{s} ({unapplied} additional fix{es} available with `--unsafe-fixes`)."
)?;
} else { } else {
writeln!(writer, "Would fix {fixed} error{s} ({unapplied} additional fix{es} available with `--unsafe-fixes`).")?; writeln!(
writer,
"Would fix {fixed} error{s} ({unapplied} additional fix{es} available with `--unsafe-fixes`)."
)?;
} }
} else { } else {
if self.fix_mode.is_apply() { if self.fix_mode.is_apply() {
writeln!(writer, "No errors fixed ({unapplied} fix{es} available with `--unsafe-fixes`).")?; writeln!(
writer,
"No errors fixed ({unapplied} fix{es} available with `--unsafe-fixes`)."
)?;
} else { } else {
writeln!(writer, "No errors would be fixed ({unapplied} fix{es} available with `--unsafe-fixes`).")?; writeln!(
writer,
"No errors would be fixed ({unapplied} fix{es} available with `--unsafe-fixes`)."
)?;
} }
} }
} else { } else {

View file

@ -1,14 +1,14 @@
use std::path::Path; use std::path::Path;
use anyhow::{bail, Result}; use anyhow::{Result, bail};
use log::debug; use log::debug;
use path_absolutize::path_dedot; use path_absolutize::path_dedot;
use ruff_workspace::configuration::Configuration; use ruff_workspace::configuration::Configuration;
use ruff_workspace::pyproject::{self, find_fallback_target_version}; use ruff_workspace::pyproject::{self, find_fallback_target_version};
use ruff_workspace::resolver::{ use ruff_workspace::resolver::{
resolve_root_settings, ConfigurationOrigin, ConfigurationTransformer, PyprojectConfig, ConfigurationOrigin, ConfigurationTransformer, PyprojectConfig, PyprojectDiscoveryStrategy,
PyprojectDiscoveryStrategy, resolve_root_settings,
}; };
use ruff_python_ast as ast; use ruff_python_ast as ast;

View file

@ -1157,18 +1157,20 @@ include = ["*.ipy"]
#[test] #[test]
fn warn_invalid_noqa_with_no_diagnostics() { fn warn_invalid_noqa_with_no_diagnostics() {
assert_cmd_snapshot!(Command::new(get_cargo_bin(BIN_NAME)) assert_cmd_snapshot!(
.args(STDIN_BASE_OPTIONS) Command::new(get_cargo_bin(BIN_NAME))
.args(["--isolated"]) .args(STDIN_BASE_OPTIONS)
.arg("--select") .args(["--isolated"])
.arg("F401") .arg("--select")
.arg("-") .arg("F401")
.pass_stdin( .arg("-")
r#" .pass_stdin(
r#"
# ruff: noqa: AAA101 # ruff: noqa: AAA101
print("Hello world!") print("Hello world!")
"# "#
)); )
);
} }
#[test] #[test]
@ -4997,30 +4999,34 @@ fn flake8_import_convention_invalid_aliases_config_module_name() -> Result<()> {
#[test] #[test]
fn flake8_import_convention_unused_aliased_import() { fn flake8_import_convention_unused_aliased_import() {
assert_cmd_snapshot!(Command::new(get_cargo_bin(BIN_NAME)) assert_cmd_snapshot!(
.args(STDIN_BASE_OPTIONS) Command::new(get_cargo_bin(BIN_NAME))
.arg("--config") .args(STDIN_BASE_OPTIONS)
.arg(r#"lint.isort.required-imports = ["import pandas"]"#) .arg("--config")
.args(["--select", "I002,ICN001,F401"]) .arg(r#"lint.isort.required-imports = ["import pandas"]"#)
.args(["--stdin-filename", "test.py"]) .args(["--select", "I002,ICN001,F401"])
.arg("--unsafe-fixes") .args(["--stdin-filename", "test.py"])
.arg("--fix") .arg("--unsafe-fixes")
.arg("-") .arg("--fix")
.pass_stdin("1")); .arg("-")
.pass_stdin("1")
);
} }
#[test] #[test]
fn flake8_import_convention_unused_aliased_import_no_conflict() { fn flake8_import_convention_unused_aliased_import_no_conflict() {
assert_cmd_snapshot!(Command::new(get_cargo_bin(BIN_NAME)) assert_cmd_snapshot!(
.args(STDIN_BASE_OPTIONS) Command::new(get_cargo_bin(BIN_NAME))
.arg("--config") .args(STDIN_BASE_OPTIONS)
.arg(r#"lint.isort.required-imports = ["import pandas as pd"]"#) .arg("--config")
.args(["--select", "I002,ICN001,F401"]) .arg(r#"lint.isort.required-imports = ["import pandas as pd"]"#)
.args(["--stdin-filename", "test.py"]) .args(["--select", "I002,ICN001,F401"])
.arg("--unsafe-fixes") .args(["--stdin-filename", "test.py"])
.arg("--fix") .arg("--unsafe-fixes")
.arg("-") .arg("--fix")
.pass_stdin("1")); .arg("-")
.pass_stdin("1")
);
} }
// See: https://github.com/astral-sh/ruff/issues/16177 // See: https://github.com/astral-sh/ruff/issues/16177

View file

@ -32,7 +32,7 @@
//! //!
//! The above snippet has been built out of the following structure: //! The above snippet has been built out of the following structure:
use crate::snippet; use crate::snippet;
use std::cmp::{max, min, Reverse}; use std::cmp::{Reverse, max, min};
use std::collections::HashMap; use std::collections::HashMap;
use std::fmt::Display; use std::fmt::Display;
use std::ops::Range; use std::ops::Range;
@ -41,7 +41,7 @@ use std::{cmp, fmt};
use unicode_width::UnicodeWidthStr; use unicode_width::UnicodeWidthStr;
use crate::renderer::styled_buffer::StyledBuffer; use crate::renderer::styled_buffer::StyledBuffer;
use crate::renderer::{stylesheet::Stylesheet, Margin, Style, DEFAULT_TERM_WIDTH}; use crate::renderer::{DEFAULT_TERM_WIDTH, Margin, Style, stylesheet::Stylesheet};
const ANONYMIZED_LINE_NUM: &str = "LL"; const ANONYMIZED_LINE_NUM: &str = "LL";
const ERROR_TXT: &str = "error"; const ERROR_TXT: &str = "error";
@ -1273,10 +1273,7 @@ fn fold_body(body: Vec<DisplayLine<'_>>) -> Vec<DisplayLine<'_>> {
let inline_marks = lines let inline_marks = lines
.last() .last()
.and_then(|line| { .and_then(|line| {
if let DisplayLine::Source { if let DisplayLine::Source { inline_marks, .. } = line {
ref inline_marks, ..
} = line
{
let inline_marks = inline_marks.clone(); let inline_marks = inline_marks.clone();
Some(inline_marks) Some(inline_marks)
} else { } else {

View file

@ -2,8 +2,8 @@ mod deserialize;
use crate::deserialize::Fixture; use crate::deserialize::Fixture;
use ruff_annotate_snippets::{Message, Renderer}; use ruff_annotate_snippets::{Message, Renderer};
use snapbox::data::DataFormat;
use snapbox::Data; use snapbox::Data;
use snapbox::data::DataFormat;
use std::error::Error; use std::error::Error;
fn main() { fn main() {

View file

@ -1,14 +1,14 @@
use std::path::Path; use std::path::Path;
use ruff_benchmark::criterion::{ use ruff_benchmark::criterion::{
criterion_group, criterion_main, BenchmarkId, Criterion, Throughput, BenchmarkId, Criterion, Throughput, criterion_group, criterion_main,
}; };
use ruff_benchmark::{ use ruff_benchmark::{
TestCase, LARGE_DATASET, NUMPY_CTYPESLIB, NUMPY_GLOBALS, PYDANTIC_TYPES, UNICODE_PYPINYIN, LARGE_DATASET, NUMPY_CTYPESLIB, NUMPY_GLOBALS, PYDANTIC_TYPES, TestCase, UNICODE_PYPINYIN,
}; };
use ruff_python_formatter::{format_module_ast, PreviewMode, PyFormatOptions}; use ruff_python_formatter::{PreviewMode, PyFormatOptions, format_module_ast};
use ruff_python_parser::{parse, Mode, ParseOptions}; use ruff_python_parser::{Mode, ParseOptions, parse};
use ruff_python_trivia::CommentRanges; use ruff_python_trivia::CommentRanges;
#[cfg(target_os = "windows")] #[cfg(target_os = "windows")]

View file

@ -1,12 +1,12 @@
use ruff_benchmark::criterion; use ruff_benchmark::criterion;
use criterion::{ use criterion::{
criterion_group, criterion_main, measurement::WallTime, BenchmarkId, Criterion, Throughput, BenchmarkId, Criterion, Throughput, criterion_group, criterion_main, measurement::WallTime,
}; };
use ruff_benchmark::{ use ruff_benchmark::{
TestCase, LARGE_DATASET, NUMPY_CTYPESLIB, NUMPY_GLOBALS, PYDANTIC_TYPES, UNICODE_PYPINYIN, LARGE_DATASET, NUMPY_CTYPESLIB, NUMPY_GLOBALS, PYDANTIC_TYPES, TestCase, UNICODE_PYPINYIN,
}; };
use ruff_python_parser::{lexer, Mode, TokenKind}; use ruff_python_parser::{Mode, TokenKind, lexer};
#[cfg(target_os = "windows")] #[cfg(target_os = "windows")]
#[global_allocator] #[global_allocator]

View file

@ -1,18 +1,18 @@
use ruff_benchmark::criterion; use ruff_benchmark::criterion;
use criterion::{ use criterion::{
criterion_group, criterion_main, BenchmarkGroup, BenchmarkId, Criterion, Throughput, BenchmarkGroup, BenchmarkId, Criterion, Throughput, criterion_group, criterion_main,
}; };
use ruff_benchmark::{ use ruff_benchmark::{
TestCase, LARGE_DATASET, NUMPY_CTYPESLIB, NUMPY_GLOBALS, PYDANTIC_TYPES, UNICODE_PYPINYIN, LARGE_DATASET, NUMPY_CTYPESLIB, NUMPY_GLOBALS, PYDANTIC_TYPES, TestCase, UNICODE_PYPINYIN,
}; };
use ruff_linter::linter::{lint_only, ParseSource}; use ruff_linter::linter::{ParseSource, lint_only};
use ruff_linter::rule_selector::PreviewOptions; use ruff_linter::rule_selector::PreviewOptions;
use ruff_linter::settings::rule_table::RuleTable; use ruff_linter::settings::rule_table::RuleTable;
use ruff_linter::settings::types::PreviewMode; use ruff_linter::settings::types::PreviewMode;
use ruff_linter::settings::{flags, LinterSettings}; use ruff_linter::settings::{LinterSettings, flags};
use ruff_linter::source_kind::SourceKind; use ruff_linter::source_kind::SourceKind;
use ruff_linter::{registry::Rule, RuleSelector}; use ruff_linter::{RuleSelector, registry::Rule};
use ruff_python_ast::PySourceType; use ruff_python_ast::PySourceType;
use ruff_python_parser::parse_module; use ruff_python_parser::parse_module;
@ -45,8 +45,8 @@ static GLOBAL: tikv_jemallocator::Jemalloc = tikv_jemallocator::Jemalloc;
target_arch = "powerpc64" target_arch = "powerpc64"
) )
))] ))]
#[unsafe(export_name = "_rjem_malloc_conf")]
#[expect(non_upper_case_globals)] #[expect(non_upper_case_globals)]
#[export_name = "_rjem_malloc_conf"]
#[expect(unsafe_code)] #[expect(unsafe_code)]
pub static _rjem_malloc_conf: &[u8] = b"dirty_decay_ms:-1,muzzy_decay_ms:-1\0"; pub static _rjem_malloc_conf: &[u8] = b"dirty_decay_ms:-1,muzzy_decay_ms:-1\0";

View file

@ -1,13 +1,13 @@
use ruff_benchmark::criterion; use ruff_benchmark::criterion;
use criterion::{ use criterion::{
criterion_group, criterion_main, measurement::WallTime, BenchmarkId, Criterion, Throughput, BenchmarkId, Criterion, Throughput, criterion_group, criterion_main, measurement::WallTime,
}; };
use ruff_benchmark::{ use ruff_benchmark::{
TestCase, LARGE_DATASET, NUMPY_CTYPESLIB, NUMPY_GLOBALS, PYDANTIC_TYPES, UNICODE_PYPINYIN, LARGE_DATASET, NUMPY_CTYPESLIB, NUMPY_GLOBALS, PYDANTIC_TYPES, TestCase, UNICODE_PYPINYIN,
}; };
use ruff_python_ast::statement_visitor::{walk_stmt, StatementVisitor};
use ruff_python_ast::Stmt; use ruff_python_ast::Stmt;
use ruff_python_ast::statement_visitor::{StatementVisitor, walk_stmt};
use ruff_python_parser::parse_module; use ruff_python_parser::parse_module;
#[cfg(target_os = "windows")] #[cfg(target_os = "windows")]

View file

@ -3,13 +3,13 @@ use ruff_benchmark::criterion;
use std::ops::Range; use std::ops::Range;
use criterion::{criterion_group, criterion_main, BatchSize, Criterion}; use criterion::{BatchSize, Criterion, criterion_group, criterion_main};
use rayon::ThreadPoolBuilder; use rayon::ThreadPoolBuilder;
use rustc_hash::FxHashSet; use rustc_hash::FxHashSet;
use ruff_benchmark::TestFile; use ruff_benchmark::TestFile;
use ruff_db::diagnostic::{Diagnostic, DiagnosticId, Severity}; use ruff_db::diagnostic::{Diagnostic, DiagnosticId, Severity};
use ruff_db::files::{system_path_to_file, File}; use ruff_db::files::{File, system_path_to_file};
use ruff_db::source::source_text; use ruff_db::source::source_text;
use ruff_db::system::{MemoryFileSystem, SystemPath, SystemPathBuf, TestSystem}; use ruff_db::system::{MemoryFileSystem, SystemPath, SystemPathBuf, TestSystem};
use ruff_python_ast::PythonVersion; use ruff_python_ast::PythonVersion;

View file

@ -2,8 +2,8 @@ use std::borrow::Cow;
use std::collections::{BTreeMap, BTreeSet, HashMap, HashSet}; use std::collections::{BTreeMap, BTreeSet, HashMap, HashSet};
use std::hash::{Hash, Hasher}; use std::hash::{Hash, Hasher};
use std::num::{ use std::num::{
NonZeroI128, NonZeroI16, NonZeroI32, NonZeroI64, NonZeroI8, NonZeroU128, NonZeroU16, NonZeroI8, NonZeroI16, NonZeroI32, NonZeroI64, NonZeroI128, NonZeroU8, NonZeroU16, NonZeroU32,
NonZeroU32, NonZeroU64, NonZeroU8, NonZeroU64, NonZeroU128,
}; };
use std::path::{Path, PathBuf}; use std::path::{Path, PathBuf};

View file

@ -7,7 +7,7 @@ use ruff_annotate_snippets::Level as AnnotateLevel;
use ruff_text_size::{Ranged, TextRange}; use ruff_text_size::{Ranged, TextRange};
pub use self::render::DisplayDiagnostic; pub use self::render::DisplayDiagnostic;
use crate::{files::File, Db}; use crate::{Db, files::File};
mod render; mod render;
mod stylesheet; mod stylesheet;

View file

@ -7,12 +7,12 @@ use ruff_annotate_snippets::{
use ruff_source_file::{LineIndex, OneIndexed, SourceCode}; use ruff_source_file::{LineIndex, OneIndexed, SourceCode};
use ruff_text_size::{TextRange, TextSize}; use ruff_text_size::{TextRange, TextSize};
use crate::diagnostic::stylesheet::{fmt_styled, DiagnosticStylesheet}; use crate::diagnostic::stylesheet::{DiagnosticStylesheet, fmt_styled};
use crate::{ use crate::{
files::File,
source::{line_index, source_text, SourceText},
system::SystemPath,
Db, Db,
files::File,
source::{SourceText, line_index, source_text},
system::SystemPath,
}; };
use super::{ use super::{
@ -708,11 +708,11 @@ fn relativize_path<'p>(cwd: &SystemPath, path: &'p str) -> &'p str {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use crate::Upcast;
use crate::diagnostic::{Annotation, DiagnosticId, Severity, Span}; use crate::diagnostic::{Annotation, DiagnosticId, Severity, Span};
use crate::files::system_path_to_file; use crate::files::system_path_to_file;
use crate::system::{DbWithWritableSystem, SystemPath}; use crate::system::{DbWithWritableSystem, SystemPath};
use crate::tests::TestDb; use crate::tests::TestDb;
use crate::Upcast;
use super::*; use super::*;

View file

@ -16,7 +16,7 @@ use crate::files::file_root::FileRoots;
use crate::files::private::FileStatus; use crate::files::private::FileStatus;
use crate::system::{SystemPath, SystemPathBuf, SystemVirtualPath, SystemVirtualPathBuf}; use crate::system::{SystemPath, SystemPathBuf, SystemVirtualPath, SystemVirtualPathBuf};
use crate::vendored::{VendoredPath, VendoredPathBuf}; use crate::vendored::{VendoredPath, VendoredPathBuf};
use crate::{vendored, Db, FxDashMap}; use crate::{Db, FxDashMap, vendored};
mod file_root; mod file_root;
mod path; mod path;
@ -552,7 +552,7 @@ impl Ranged for FileRange {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use crate::file_revision::FileRevision; use crate::file_revision::FileRevision;
use crate::files::{system_path_to_file, vendored_path_to_file, FileError}; use crate::files::{FileError, system_path_to_file, vendored_path_to_file};
use crate::system::DbWithWritableSystem as _; use crate::system::DbWithWritableSystem as _;
use crate::tests::TestDb; use crate::tests::TestDb;
use crate::vendored::VendoredFileSystemBuilder; use crate::vendored::VendoredFileSystemBuilder;

View file

@ -3,9 +3,9 @@ use std::fmt::Formatter;
use path_slash::PathExt; use path_slash::PathExt;
use salsa::Durability; use salsa::Durability;
use crate::Db;
use crate::file_revision::FileRevision; use crate::file_revision::FileRevision;
use crate::system::{SystemPath, SystemPathBuf}; use crate::system::{SystemPath, SystemPathBuf};
use crate::Db;
/// A root path for files tracked by the database. /// A root path for files tracked by the database.
/// ///

View file

@ -1,7 +1,7 @@
use crate::files::{system_path_to_file, vendored_path_to_file, File}; use crate::Db;
use crate::files::{File, system_path_to_file, vendored_path_to_file};
use crate::system::{SystemPath, SystemPathBuf, SystemVirtualPath, SystemVirtualPathBuf}; use crate::system::{SystemPath, SystemPathBuf, SystemVirtualPath, SystemVirtualPathBuf};
use crate::vendored::{VendoredPath, VendoredPathBuf}; use crate::vendored::{VendoredPath, VendoredPathBuf};
use crate::Db;
use std::fmt::{Display, Formatter}; use std::fmt::{Display, Formatter};
/// Path to a file. /// Path to a file.

View file

@ -3,11 +3,11 @@ use std::ops::Deref;
use std::sync::Arc; use std::sync::Arc;
use ruff_python_ast::ModModule; use ruff_python_ast::ModModule;
use ruff_python_parser::{parse_unchecked, ParseOptions, Parsed}; use ruff_python_parser::{ParseOptions, Parsed, parse_unchecked};
use crate::Db;
use crate::files::File; use crate::files::File;
use crate::source::source_text; use crate::source::source_text;
use crate::Db;
/// Returns the parsed AST of `file`, including its token stream. /// Returns the parsed AST of `file`, including its token stream.
/// ///
@ -79,6 +79,7 @@ impl Eq for ParsedModule {}
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use crate::Db;
use crate::files::{system_path_to_file, vendored_path_to_file}; use crate::files::{system_path_to_file, vendored_path_to_file};
use crate::parsed::parsed_module; use crate::parsed::parsed_module;
use crate::system::{ use crate::system::{
@ -86,7 +87,6 @@ mod tests {
}; };
use crate::tests::TestDb; use crate::tests::TestDb;
use crate::vendored::{VendoredFileSystemBuilder, VendoredPath}; use crate::vendored::{VendoredFileSystemBuilder, VendoredPath};
use crate::Db;
use zip::CompressionMethod; use zip::CompressionMethod;
#[test] #[test]

View file

@ -7,8 +7,8 @@ use ruff_notebook::Notebook;
use ruff_python_ast::PySourceType; use ruff_python_ast::PySourceType;
use ruff_source_file::LineIndex; use ruff_source_file::LineIndex;
use crate::files::{File, FilePath};
use crate::Db; use crate::Db;
use crate::files::{File, FilePath};
/// Reads the source text of a python text file (must be valid UTF8) or notebook. /// Reads the source text of a python text file (must be valid UTF8) or notebook.
#[salsa::tracked] #[salsa::tracked]
@ -216,9 +216,11 @@ mod tests {
let events = db.take_salsa_events(); let events = db.take_salsa_events();
assert!(!events assert!(
.iter() !events
.any(|event| matches!(event.kind, EventKind::WillExecute { .. }))); .iter()
.any(|event| matches!(event.kind, EventKind::WillExecute { .. }))
);
Ok(()) Ok(())
} }

View file

@ -19,8 +19,8 @@ use walk_directory::WalkDirectoryBuilder;
use crate::file_revision::FileRevision; use crate::file_revision::FileRevision;
pub use self::path::{ pub use self::path::{
deduplicate_nested_paths, DeduplicatedNestedPathsIter, SystemPath, SystemPathBuf, DeduplicatedNestedPathsIter, SystemPath, SystemPathBuf, SystemVirtualPath,
SystemVirtualPath, SystemVirtualPathBuf, SystemVirtualPathBuf, deduplicate_nested_paths,
}; };
mod memory_fs; mod memory_fs;
@ -167,7 +167,7 @@ pub trait System: Debug {
&self, &self,
pattern: &str, pattern: &str,
) -> std::result::Result< ) -> std::result::Result<
Box<dyn Iterator<Item = std::result::Result<SystemPathBuf, GlobError>>>, Box<dyn Iterator<Item = std::result::Result<SystemPathBuf, GlobError>> + '_>,
PatternError, PatternError,
>; >;

View file

@ -7,8 +7,8 @@ use filetime::FileTime;
use rustc_hash::FxHashMap; use rustc_hash::FxHashMap;
use crate::system::{ use crate::system::{
file_time_now, walk_directory, DirectoryEntry, FileType, GlobError, GlobErrorKind, Metadata, DirectoryEntry, FileType, GlobError, GlobErrorKind, Metadata, Result, SystemPath,
Result, SystemPath, SystemPathBuf, SystemVirtualPath, SystemVirtualPathBuf, SystemPathBuf, SystemVirtualPath, SystemVirtualPathBuf, file_time_now, walk_directory,
}; };
use super::walk_directory::{ use super::walk_directory::{
@ -236,7 +236,7 @@ impl MemoryFileSystem {
&self, &self,
pattern: &str, pattern: &str,
) -> std::result::Result< ) -> std::result::Result<
impl Iterator<Item = std::result::Result<SystemPathBuf, GlobError>>, impl Iterator<Item = std::result::Result<SystemPathBuf, GlobError>> + '_,
glob::PatternError, glob::PatternError,
> { > {
// Very naive implementation that iterates over all files and collects all that match the given pattern. // Very naive implementation that iterates over all files and collects all that match the given pattern.
@ -701,8 +701,8 @@ mod tests {
use std::time::Duration; use std::time::Duration;
use crate::system::walk_directory::tests::DirectoryEntryToString;
use crate::system::walk_directory::WalkState; use crate::system::walk_directory::WalkState;
use crate::system::walk_directory::tests::DirectoryEntryToString;
use crate::system::{ use crate::system::{
DirectoryEntry, FileType, MemoryFileSystem, Result, SystemPath, SystemPathBuf, DirectoryEntry, FileType, MemoryFileSystem, Result, SystemPath, SystemPathBuf,
SystemVirtualPath, SystemVirtualPath,

View file

@ -256,7 +256,9 @@ impl OsSystem {
let Ok(canonicalized) = SystemPathBuf::from_path_buf(canonicalized) else { let Ok(canonicalized) = SystemPathBuf::from_path_buf(canonicalized) else {
// The original path is valid UTF8 but the canonicalized path isn't. This definitely suggests // The original path is valid UTF8 but the canonicalized path isn't. This definitely suggests
// that a symlink is involved. Fall back to the slow path. // that a symlink is involved. Fall back to the slow path.
tracing::debug!("Falling back to the slow case-sensitive path existence check because the canonicalized path of `{simplified}` is not valid UTF-8"); tracing::debug!(
"Falling back to the slow case-sensitive path existence check because the canonicalized path of `{simplified}` is not valid UTF-8"
);
return None; return None;
}; };
@ -266,7 +268,9 @@ impl OsSystem {
// `path` pointed to a symlink (or some other none reversible path normalization happened). // `path` pointed to a symlink (or some other none reversible path normalization happened).
// In this case, fall back to the slow path. // In this case, fall back to the slow path.
if simplified_canonicalized.as_str().to_lowercase() != simplified.as_str().to_lowercase() { if simplified_canonicalized.as_str().to_lowercase() != simplified.as_str().to_lowercase() {
tracing::debug!("Falling back to the slow case-sensitive path existence check for `{simplified}` because the canonicalized path `{simplified_canonicalized}` differs not only by casing"); tracing::debug!(
"Falling back to the slow case-sensitive path existence check for `{simplified}` because the canonicalized path `{simplified_canonicalized}` differs not only by casing"
);
return None; return None;
} }
@ -662,8 +666,8 @@ fn detect_case_sensitivity(path: &SystemPath) -> CaseSensitivity {
mod tests { mod tests {
use tempfile::TempDir; use tempfile::TempDir;
use crate::system::walk_directory::tests::DirectoryEntryToString;
use crate::system::DirectoryEntry; use crate::system::DirectoryEntry;
use crate::system::walk_directory::tests::DirectoryEntryToString;
use super::*; use super::*;

View file

@ -3,15 +3,15 @@ use ruff_notebook::{Notebook, NotebookError};
use std::panic::RefUnwindSafe; use std::panic::RefUnwindSafe;
use std::sync::{Arc, Mutex}; use std::sync::{Arc, Mutex};
use crate::Db;
use crate::files::File; use crate::files::File;
use crate::system::{ use crate::system::{
CaseSensitivity, DirectoryEntry, GlobError, MemoryFileSystem, Metadata, Result, System, CaseSensitivity, DirectoryEntry, GlobError, MemoryFileSystem, Metadata, Result, System,
SystemPath, SystemPathBuf, SystemVirtualPath, SystemPath, SystemPathBuf, SystemVirtualPath,
}; };
use crate::Db;
use super::walk_directory::WalkDirectoryBuilder;
use super::WritableSystem; use super::WritableSystem;
use super::walk_directory::WalkDirectoryBuilder;
/// System implementation intended for testing. /// System implementation intended for testing.
/// ///
@ -117,7 +117,7 @@ impl System for TestSystem {
&self, &self,
pattern: &str, pattern: &str,
) -> std::result::Result< ) -> std::result::Result<
Box<dyn Iterator<Item = std::result::Result<SystemPathBuf, GlobError>>>, Box<dyn Iterator<Item = std::result::Result<SystemPathBuf, GlobError>> + '_>,
PatternError, PatternError,
> { > {
self.system().glob(pattern) self.system().glob(pattern)
@ -343,7 +343,7 @@ impl System for InMemorySystem {
&self, &self,
pattern: &str, pattern: &str,
) -> std::result::Result< ) -> std::result::Result<
Box<dyn Iterator<Item = std::result::Result<SystemPathBuf, GlobError>>>, Box<dyn Iterator<Item = std::result::Result<SystemPathBuf, GlobError>> + '_>,
PatternError, PatternError,
> { > {
let iterator = self.memory_fs.glob(pattern)?; let iterator = self.memory_fs.glob(pattern)?;

View file

@ -1,7 +1,7 @@
//! Test helpers for working with Salsa databases //! Test helpers for working with Salsa databases
use tracing_subscriber::layer::SubscriberExt;
use tracing_subscriber::EnvFilter; use tracing_subscriber::EnvFilter;
use tracing_subscriber::layer::SubscriberExt;
pub fn assert_function_query_was_not_run<Db, Q, QDb, I, R>( pub fn assert_function_query_was_not_run<Db, Q, QDb, I, R>(
db: &Db, db: &Db,

View file

@ -7,7 +7,7 @@ use std::sync::{Arc, Mutex, MutexGuard};
use crate::file_revision::FileRevision; use crate::file_revision::FileRevision;
use zip::result::ZipResult; use zip::result::ZipResult;
use zip::write::FileOptions; use zip::write::FileOptions;
use zip::{read::ZipFile, CompressionMethod, ZipArchive, ZipWriter}; use zip::{CompressionMethod, ZipArchive, ZipWriter, read::ZipFile};
pub use self::path::{VendoredPath, VendoredPathBuf}; pub use self::path::{VendoredPath, VendoredPathBuf};
@ -503,9 +503,11 @@ pub(crate) mod tests {
let path = VendoredPath::new(path); let path = VendoredPath::new(path);
assert!(!mock_typeshed.exists(path)); assert!(!mock_typeshed.exists(path));
assert!(mock_typeshed.metadata(path).is_err()); assert!(mock_typeshed.metadata(path).is_err());
assert!(mock_typeshed assert!(
.read_to_string(path) mock_typeshed
.is_err_and(|err| err.to_string().contains("file not found"))); .read_to_string(path)
.is_err_and(|err| err.to_string().contains("file not found"))
);
} }
#[test] #[test]

View file

@ -9,11 +9,11 @@ use std::process::ExitCode;
use std::time::{Duration, Instant}; use std::time::{Duration, Instant};
use std::{fmt, fs, io, iter}; use std::{fmt, fs, io, iter};
use anyhow::{bail, format_err, Context, Error}; use anyhow::{Context, Error, bail, format_err};
use clap::{CommandFactory, FromArgMatches}; use clap::{CommandFactory, FromArgMatches};
use imara_diff::intern::InternedInput; use imara_diff::intern::InternedInput;
use imara_diff::sink::Counter; use imara_diff::sink::Counter;
use imara_diff::{diff, Algorithm}; use imara_diff::{Algorithm, diff};
use indicatif::ProgressStyle; use indicatif::ProgressStyle;
#[cfg_attr(feature = "singlethreaded", allow(unused_imports))] #[cfg_attr(feature = "singlethreaded", allow(unused_imports))]
use rayon::iter::{IntoParallelIterator, ParallelIterator}; use rayon::iter::{IntoParallelIterator, ParallelIterator};
@ -21,11 +21,11 @@ use serde::Deserialize;
use similar::{ChangeTag, TextDiff}; use similar::{ChangeTag, TextDiff};
use tempfile::NamedTempFile; use tempfile::NamedTempFile;
use tracing::{debug, error, info, info_span}; use tracing::{debug, error, info, info_span};
use tracing_indicatif::span_ext::IndicatifSpanExt;
use tracing_indicatif::IndicatifLayer; use tracing_indicatif::IndicatifLayer;
use tracing_indicatif::span_ext::IndicatifSpanExt;
use tracing_subscriber::EnvFilter;
use tracing_subscriber::layer::SubscriberExt; use tracing_subscriber::layer::SubscriberExt;
use tracing_subscriber::util::SubscriberInitExt; use tracing_subscriber::util::SubscriberInitExt;
use tracing_subscriber::EnvFilter;
use ruff::args::{ConfigArguments, FormatArguments, FormatCommand, GlobalConfigArgs, LogLevelArgs}; use ruff::args::{ConfigArguments, FormatArguments, FormatCommand, GlobalConfigArgs, LogLevelArgs};
use ruff::resolve::resolve; use ruff::resolve::resolve;
@ -33,10 +33,10 @@ use ruff_formatter::{FormatError, LineWidth, PrintError};
use ruff_linter::logging::LogLevel; use ruff_linter::logging::LogLevel;
use ruff_linter::settings::types::{FilePattern, FilePatternSet}; use ruff_linter::settings::types::{FilePattern, FilePatternSet};
use ruff_python_formatter::{ use ruff_python_formatter::{
format_module_source, FormatModuleError, MagicTrailingComma, PreviewMode, PyFormatOptions, FormatModuleError, MagicTrailingComma, PreviewMode, PyFormatOptions, format_module_source,
}; };
use ruff_python_parser::ParseError; use ruff_python_parser::ParseError;
use ruff_workspace::resolver::{python_files_in_path, PyprojectConfig, ResolvedFile, Resolver}; use ruff_workspace::resolver::{PyprojectConfig, ResolvedFile, Resolver, python_files_in_path};
fn parse_cli(dirs: &[PathBuf]) -> anyhow::Result<(FormatArguments, ConfigArguments)> { fn parse_cli(dirs: &[PathBuf]) -> anyhow::Result<(FormatArguments, ConfigArguments)> {
let args_matches = FormatCommand::command() let args_matches = FormatCommand::command()

View file

@ -3,14 +3,14 @@
use std::path::PathBuf; use std::path::PathBuf;
use std::{fs, str}; use std::{fs, str};
use anyhow::{bail, Context, Result}; use anyhow::{Context, Result, bail};
use clap::CommandFactory; use clap::CommandFactory;
use pretty_assertions::StrComparison; use pretty_assertions::StrComparison;
use ruff::args; use ruff::args;
use crate::generate_all::{Mode, REGENERATE_ALL_COMMAND};
use crate::ROOT_DIR; use crate::ROOT_DIR;
use crate::generate_all::{Mode, REGENERATE_ALL_COMMAND};
const COMMAND_HELP_BEGIN_PRAGMA: &str = "<!-- Begin auto-generated command help. -->\n"; const COMMAND_HELP_BEGIN_PRAGMA: &str = "<!-- Begin auto-generated command help. -->\n";
const COMMAND_HELP_END_PRAGMA: &str = "<!-- End auto-generated command help. -->"; const COMMAND_HELP_END_PRAGMA: &str = "<!-- End auto-generated command help. -->";
@ -140,7 +140,7 @@ mod tests {
use crate::generate_all::Mode; use crate::generate_all::Mode;
use super::{main, Args}; use super::{Args, main};
#[test] #[test]
fn test_generate_json_schema() -> Result<()> { fn test_generate_json_schema() -> Result<()> {

View file

@ -1,12 +1,12 @@
use std::fs; use std::fs;
use std::path::PathBuf; use std::path::PathBuf;
use anyhow::{bail, Result}; use anyhow::{Result, bail};
use pretty_assertions::StrComparison; use pretty_assertions::StrComparison;
use schemars::schema_for; use schemars::schema_for;
use crate::generate_all::{Mode, REGENERATE_ALL_COMMAND};
use crate::ROOT_DIR; use crate::ROOT_DIR;
use crate::generate_all::{Mode, REGENERATE_ALL_COMMAND};
use ruff_workspace::options::Options; use ruff_workspace::options::Options;
#[derive(clap::Args)] #[derive(clap::Args)]
@ -56,7 +56,7 @@ mod tests {
use crate::generate_all::Mode; use crate::generate_all::Mode;
use super::{main, Args}; use super::{Args, main};
#[test] #[test]
fn test_generate_json_schema() -> Result<()> { fn test_generate_json_schema() -> Result<()> {

View file

@ -100,8 +100,8 @@ fn emit_field(output: &mut String, name: &str, field: &OptionField, parents: &[S
if parents_anchor.is_empty() { if parents_anchor.is_empty() {
let _ = writeln!(output, "{header_level} [`{name}`](#{name}) {{: #{name} }}"); let _ = writeln!(output, "{header_level} [`{name}`](#{name}) {{: #{name} }}");
} else { } else {
let _ = let _ = writeln!(
writeln!(output, output,
"{header_level} [`{name}`](#{parents_anchor}_{name}) {{: #{parents_anchor}_{name} }}" "{header_level} [`{name}`](#{parents_anchor}_{name}) {{: #{parents_anchor}_{name} }}"
); );

View file

@ -48,7 +48,9 @@ fn generate_table(table_out: &mut String, rules: impl IntoIterator<Item = Rule>,
format!("<span title='Automatic fix available'>{FIX_SYMBOL}</span>") format!("<span title='Automatic fix available'>{FIX_SYMBOL}</span>")
} }
FixAvailability::None => { FixAvailability::None => {
format!("<span title='Automatic fix not available' style='opacity: 0.1' aria-hidden='true'>{FIX_SYMBOL}</span>") format!(
"<span title='Automatic fix not available' style='opacity: 0.1' aria-hidden='true'>{FIX_SYMBOL}</span>"
)
} }
}; };
@ -108,22 +110,26 @@ pub(crate) fn generate() -> String {
); );
table_out.push_str("<br />"); table_out.push_str("<br />");
let _ = write!(&mut table_out, let _ = write!(
&mut table_out,
"{SPACER}{PREVIEW_SYMBOL}{SPACER} The rule is unstable and is in [\"preview\"](faq.md#what-is-preview)." "{SPACER}{PREVIEW_SYMBOL}{SPACER} The rule is unstable and is in [\"preview\"](faq.md#what-is-preview)."
); );
table_out.push_str("<br />"); table_out.push_str("<br />");
let _ = write!(&mut table_out, let _ = write!(
&mut table_out,
"{SPACER}{WARNING_SYMBOL}{SPACER} The rule has been deprecated and will be removed in a future release." "{SPACER}{WARNING_SYMBOL}{SPACER} The rule has been deprecated and will be removed in a future release."
); );
table_out.push_str("<br />"); table_out.push_str("<br />");
let _ = write!(&mut table_out, let _ = write!(
&mut table_out,
"{SPACER}{REMOVED_SYMBOL}{SPACER} The rule has been removed only the documentation is available." "{SPACER}{REMOVED_SYMBOL}{SPACER} The rule has been removed only the documentation is available."
); );
table_out.push_str("<br />"); table_out.push_str("<br />");
let _ = write!(&mut table_out, let _ = write!(
&mut table_out,
"{SPACER}{FIX_SYMBOL}{SPACER} The rule is automatically fixable by the `--fix` command-line option." "{SPACER}{FIX_SYMBOL}{SPACER} The rule is automatically fixable by the `--fix` command-line option."
); );
table_out.push_str("<br />"); table_out.push_str("<br />");

View file

@ -2,13 +2,13 @@
use std::cmp::max; use std::cmp::max;
use std::path::PathBuf; use std::path::PathBuf;
use anyhow::{bail, Result}; use anyhow::{Result, bail};
use clap::{Command, CommandFactory}; use clap::{Command, CommandFactory};
use itertools::Itertools; use itertools::Itertools;
use pretty_assertions::StrComparison; use pretty_assertions::StrComparison;
use crate::generate_all::{Mode, REGENERATE_ALL_COMMAND};
use crate::ROOT_DIR; use crate::ROOT_DIR;
use crate::generate_all::{Mode, REGENERATE_ALL_COMMAND};
use ty::Cli; use ty::Cli;
@ -29,24 +29,24 @@ pub(crate) fn main(args: &Args) -> Result<()> {
Mode::DryRun => { Mode::DryRun => {
println!("{reference_string}"); println!("{reference_string}");
} }
Mode::Check => { Mode::Check => match std::fs::read_to_string(reference_path) {
match std::fs::read_to_string(reference_path) { Ok(current) => {
Ok(current) => { if current == reference_string {
if current == reference_string { println!("Up-to-date: {filename}");
println!("Up-to-date: {filename}"); } else {
} else { let comparison = StrComparison::new(&current, &reference_string);
let comparison = StrComparison::new(&current, &reference_string); bail!(
bail!("{filename} changed, please run `{REGENERATE_ALL_COMMAND}`:\n{comparison}"); "{filename} changed, please run `{REGENERATE_ALL_COMMAND}`:\n{comparison}"
} );
}
Err(err) if err.kind() == std::io::ErrorKind::NotFound => {
bail!("{filename} not found, please run `{REGENERATE_ALL_COMMAND}`");
}
Err(err) => {
bail!("{filename} changed, please run `{REGENERATE_ALL_COMMAND}`:\n{err}");
} }
} }
} Err(err) if err.kind() == std::io::ErrorKind::NotFound => {
bail!("{filename} not found, please run `{REGENERATE_ALL_COMMAND}`");
}
Err(err) => {
bail!("{filename} changed, please run `{REGENERATE_ALL_COMMAND}`:\n{err}");
}
},
Mode::Write => match std::fs::read_to_string(&reference_path) { Mode::Write => match std::fs::read_to_string(&reference_path) {
Ok(current) => { Ok(current) => {
if current == reference_string { if current == reference_string {
@ -325,7 +325,7 @@ mod tests {
use crate::generate_all::Mode; use crate::generate_all::Mode;
use super::{main, Args}; use super::{Args, main};
#[test] #[test]
fn ty_cli_reference_is_up_to_date() -> Result<()> { fn ty_cli_reference_is_up_to_date() -> Result<()> {

View file

@ -9,8 +9,8 @@ use ruff_options_metadata::{OptionField, OptionSet, OptionsMetadata, Visit};
use ty_project::metadata::Options; use ty_project::metadata::Options;
use crate::{ use crate::{
generate_all::{Mode, REGENERATE_ALL_COMMAND},
ROOT_DIR, ROOT_DIR,
generate_all::{Mode, REGENERATE_ALL_COMMAND},
}; };
#[derive(clap::Args)] #[derive(clap::Args)]
@ -247,7 +247,7 @@ mod tests {
use crate::generate_all::Mode; use crate::generate_all::Mode;
use super::{main, Args}; use super::{Args, main};
#[test] #[test]
fn ty_configuration_markdown_up_to_date() -> Result<()> { fn ty_configuration_markdown_up_to_date() -> Result<()> {

View file

@ -5,12 +5,12 @@ use std::fmt::Write as _;
use std::fs; use std::fs;
use std::path::PathBuf; use std::path::PathBuf;
use anyhow::{bail, Result}; use anyhow::{Result, bail};
use itertools::Itertools as _; use itertools::Itertools as _;
use pretty_assertions::StrComparison; use pretty_assertions::StrComparison;
use crate::generate_all::{Mode, REGENERATE_ALL_COMMAND};
use crate::ROOT_DIR; use crate::ROOT_DIR;
use crate::generate_all::{Mode, REGENERATE_ALL_COMMAND};
#[derive(clap::Args)] #[derive(clap::Args)]
pub(crate) struct Args { pub(crate) struct Args {
@ -134,7 +134,7 @@ mod tests {
use crate::generate_all::Mode; use crate::generate_all::Mode;
use super::{main, Args}; use super::{Args, main};
#[test] #[test]
fn ty_rules_up_to_date() -> Result<()> { fn ty_rules_up_to_date() -> Result<()> {

View file

@ -1,12 +1,12 @@
use std::fs; use std::fs;
use std::path::PathBuf; use std::path::PathBuf;
use anyhow::{bail, Result}; use anyhow::{Result, bail};
use pretty_assertions::StrComparison; use pretty_assertions::StrComparison;
use schemars::schema_for; use schemars::schema_for;
use crate::generate_all::{Mode, REGENERATE_ALL_COMMAND};
use crate::ROOT_DIR; use crate::ROOT_DIR;
use crate::generate_all::{Mode, REGENERATE_ALL_COMMAND};
use ty_project::metadata::options::Options; use ty_project::metadata::options::Options;
#[derive(clap::Args)] #[derive(clap::Args)]
@ -56,7 +56,7 @@ mod tests {
use crate::generate_all::Mode; use crate::generate_all::Mode;
use super::{main, Args}; use super::{Args, main};
#[test] #[test]
fn test_generate_json_schema() -> Result<()> { fn test_generate_json_schema() -> Result<()> {

View file

@ -6,7 +6,7 @@ use anyhow::Result;
use ruff_linter::source_kind::SourceKind; use ruff_linter::source_kind::SourceKind;
use ruff_python_ast::PySourceType; use ruff_python_ast::PySourceType;
use ruff_python_parser::{parse, ParseOptions}; use ruff_python_parser::{ParseOptions, parse};
#[derive(clap::Args)] #[derive(clap::Args)]
pub(crate) struct Args { pub(crate) struct Args {

View file

@ -3,7 +3,7 @@
use std::fs; use std::fs;
use std::path::PathBuf; use std::path::PathBuf;
use anyhow::{bail, Result}; use anyhow::{Result, bail};
#[derive(clap::Args)] #[derive(clap::Args)]
pub(crate) struct Args { pub(crate) struct Args {

View file

@ -17,7 +17,7 @@ impl<'fmt, Context> Argument<'fmt, Context> {
/// Called by the [ruff_formatter::format_args] macro. /// Called by the [ruff_formatter::format_args] macro.
#[doc(hidden)] #[doc(hidden)]
#[inline] #[inline]
pub fn new<F: Format<Context>>(value: &'fmt F) -> Self { pub const fn new<F: Format<Context>>(value: &'fmt F) -> Self {
Self { value } Self { value }
} }
@ -55,7 +55,7 @@ pub struct Arguments<'fmt, Context>(pub &'fmt [Argument<'fmt, Context>]);
impl<'fmt, Context> Arguments<'fmt, Context> { impl<'fmt, Context> Arguments<'fmt, Context> {
#[doc(hidden)] #[doc(hidden)]
#[inline] #[inline]
pub fn new(arguments: &'fmt [Argument<'fmt, Context>]) -> Self { pub const fn new(arguments: &'fmt [Argument<'fmt, Context>]) -> Self {
Self(arguments) Self(arguments)
} }
@ -98,7 +98,7 @@ impl<'fmt, Context> From<&'fmt Argument<'fmt, Context>> for Arguments<'fmt, Cont
mod tests { mod tests {
use crate::format_element::tag::Tag; use crate::format_element::tag::Tag;
use crate::prelude::*; use crate::prelude::*;
use crate::{format_args, write, FormatState, VecBuffer}; use crate::{FormatState, VecBuffer, format_args, write};
#[test] #[test]
fn test_nesting() { fn test_nesting() {

View file

@ -1,4 +1,4 @@
use super::{write, Arguments, FormatElement}; use super::{Arguments, FormatElement, write};
use crate::format_element::Interned; use crate::format_element::Interned;
use crate::prelude::{LineMode, Tag}; use crate::prelude::{LineMode, Tag};
use crate::{FormatResult, FormatState}; use crate::{FormatResult, FormatState};

View file

@ -2,14 +2,14 @@ use std::cell::Cell;
use std::marker::PhantomData; use std::marker::PhantomData;
use std::num::NonZeroU8; use std::num::NonZeroU8;
use ruff_text_size::TextRange;
#[allow(clippy::enum_glob_use)] #[allow(clippy::enum_glob_use)]
use Tag::*; use Tag::*;
use ruff_text_size::TextRange;
use crate::format_element::tag::{Condition, Tag}; use crate::format_element::tag::{Condition, Tag};
use crate::prelude::tag::{DedentMode, GroupMode, LabelId}; use crate::prelude::tag::{DedentMode, GroupMode, LabelId};
use crate::prelude::*; use crate::prelude::*;
use crate::{write, Argument, Arguments, FormatContext, FormatOptions, GroupId, TextSize}; use crate::{Argument, Arguments, FormatContext, FormatOptions, GroupId, TextSize, write};
use crate::{Buffer, VecBuffer}; use crate::{Buffer, VecBuffer};
/// A line break that only gets printed if the enclosing `Group` doesn't fit on a single line. /// A line break that only gets printed if the enclosing `Group` doesn't fit on a single line.
@ -402,7 +402,10 @@ where
} }
fn debug_assert_no_newlines(text: &str) { fn debug_assert_no_newlines(text: &str) {
debug_assert!(!text.contains('\r'), "The content '{text}' contains an unsupported '\\r' line terminator character but text must only use line feeds '\\n' as line separator. Use '\\n' instead of '\\r' and '\\r\\n' to insert a line break in strings."); debug_assert!(
!text.contains('\r'),
"The content '{text}' contains an unsupported '\\r' line terminator character but text must only use line feeds '\\n' as line separator. Use '\\n' instead of '\\r' and '\\r\\n' to insert a line break in strings."
);
} }
/// Pushes some content to the end of the current line. /// Pushes some content to the end of the current line.
@ -2564,7 +2567,7 @@ impl<'a, Context> BestFitting<'a, Context> {
/// # Panics /// # Panics
/// ///
/// When the slice contains less than two variants. /// When the slice contains less than two variants.
pub fn from_arguments_unchecked(variants: Arguments<'a, Context>) -> Self { pub const fn from_arguments_unchecked(variants: Arguments<'a, Context>) -> Self {
assert!( assert!(
variants.0.len() >= 2, variants.0.len() >= 2,
"Requires at least the least expanded and most expanded variants" "Requires at least the least expanded and most expanded variants"
@ -2572,7 +2575,7 @@ impl<'a, Context> BestFitting<'a, Context> {
Self { Self {
variants, variants,
mode: BestFittingMode::default(), mode: BestFittingMode::FirstLine,
} }
} }

View file

@ -1,5 +1,5 @@
use crate::prelude::TagKind;
use crate::GroupId; use crate::GroupId;
use crate::prelude::TagKind;
use ruff_text_size::TextRange; use ruff_text_size::TextRange;
use std::error::Error; use std::error::Error;
@ -29,16 +29,22 @@ pub enum FormatError {
impl std::fmt::Display for FormatError { impl std::fmt::Display for FormatError {
fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self { match self {
FormatError::SyntaxError {message} => { FormatError::SyntaxError { message } => {
std::write!(fmt, "syntax error: {message}") std::write!(fmt, "syntax error: {message}")
}, }
FormatError::RangeError { input, tree } => std::write!( FormatError::RangeError { input, tree } => std::write!(
fmt, fmt,
"formatting range {input:?} is larger than syntax tree {tree:?}" "formatting range {input:?} is larger than syntax tree {tree:?}"
), ),
FormatError::InvalidDocument(error) => std::write!(fmt, "Invalid document: {error}\n\n This is an internal Rome error. Please report if necessary."), FormatError::InvalidDocument(error) => std::write!(
fmt,
"Invalid document: {error}\n\n This is an internal Rome error. Please report if necessary."
),
FormatError::PoorLayout => { FormatError::PoorLayout => {
std::write!(fmt, "Poor layout: The formatter wasn't able to pick a good layout for your document. This is an internal Rome error. Please report if necessary.") std::write!(
fmt,
"Poor layout: The formatter wasn't able to pick a good layout for your document. This is an internal Rome error. Please report if necessary."
)
} }
} }
} }
@ -139,24 +145,37 @@ impl std::fmt::Display for InvalidDocumentError {
InvalidDocumentError::ExpectedStart { InvalidDocumentError::ExpectedStart {
expected_start, expected_start,
actual, actual,
} => { } => match actual {
match actual { ActualStart::EndOfDocument => {
ActualStart::EndOfDocument => { std::write!(
std::write!(f, "Expected start tag of kind {expected_start:?} but at the end of document.") f,
} "Expected start tag of kind {expected_start:?} but at the end of document."
ActualStart::Start(start) => { )
std::write!(f, "Expected start tag of kind {expected_start:?} but found start tag of kind {start:?}.")
}
ActualStart::End(end) => {
std::write!(f, "Expected start tag of kind {expected_start:?} but found end tag of kind {end:?}.")
}
ActualStart::Content => {
std::write!(f, "Expected start tag of kind {expected_start:?} but found non-tag element.")
}
} }
} ActualStart::Start(start) => {
std::write!(
f,
"Expected start tag of kind {expected_start:?} but found start tag of kind {start:?}."
)
}
ActualStart::End(end) => {
std::write!(
f,
"Expected start tag of kind {expected_start:?} but found end tag of kind {end:?}."
)
}
ActualStart::Content => {
std::write!(
f,
"Expected start tag of kind {expected_start:?} but found non-tag element."
)
}
},
InvalidDocumentError::UnknownGroupId { group_id } => { InvalidDocumentError::UnknownGroupId { group_id } => {
std::write!(f, "Encountered unknown group id {group_id:?}. Ensure that the group with the id {group_id:?} exists and that the group is a parent of or comes before the element referring to it.") std::write!(
f,
"Encountered unknown group id {group_id:?}. Ensure that the group with the id {group_id:?} exists and that the group is a parent of or comes before the element referring to it."
)
} }
} }
} }

View file

@ -543,7 +543,7 @@ impl TextWidth {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use crate::format_element::{normalize_newlines, LINE_TERMINATORS}; use crate::format_element::{LINE_TERMINATORS, normalize_newlines};
#[test] #[test]
fn test_normalize_newlines() { fn test_normalize_newlines() {

View file

@ -8,8 +8,8 @@ use crate::prelude::tag::GroupMode;
use crate::prelude::*; use crate::prelude::*;
use crate::source_code::SourceCode; use crate::source_code::SourceCode;
use crate::{ use crate::{
format, write, BufferExtensions, Format, FormatContext, FormatElement, FormatOptions, BufferExtensions, Format, FormatContext, FormatElement, FormatOptions, FormatResult, Formatter,
FormatResult, Formatter, IndentStyle, IndentWidth, LineWidth, PrinterOptions, IndentStyle, IndentWidth, LineWidth, PrinterOptions, format, write,
}; };
use super::tag::Tag; use super::tag::Tag;
@ -811,8 +811,8 @@ mod tests {
use ruff_text_size::{TextRange, TextSize}; use ruff_text_size::{TextRange, TextSize};
use crate::prelude::*; use crate::prelude::*;
use crate::{format, format_args, write};
use crate::{SimpleFormatContext, SourceCode}; use crate::{SimpleFormatContext, SourceCode};
use crate::{format, format_args, write};
#[test] #[test]
fn display_elements() { fn display_elements() {

View file

@ -370,7 +370,10 @@ impl PartialEq for LabelId {
#[cfg(debug_assertions)] #[cfg(debug_assertions)]
{ {
if is_equal { if is_equal {
assert_eq!(self.name, other.name, "Two `LabelId`s with different names have the same `value`. Are you mixing labels of two different `LabelDefinition` or are the values returned by the `LabelDefinition` not unique?"); assert_eq!(
self.name, other.name,
"Two `LabelId`s with different names have the same `value`. Are you mixing labels of two different `LabelDefinition` or are the values returned by the `LabelDefinition` not unique?"
);
} }
} }

View file

@ -38,7 +38,7 @@ use crate::prelude::TagKind;
use std::fmt; use std::fmt;
use std::fmt::{Debug, Display}; use std::fmt::{Debug, Display};
use std::marker::PhantomData; use std::marker::PhantomData;
use std::num::{NonZeroU16, NonZeroU8, TryFromIntError}; use std::num::{NonZeroU8, NonZeroU16, TryFromIntError};
use crate::format_element::document::Document; use crate::format_element::document::Document;
use crate::printer::{Printer, PrinterOptions}; use crate::printer::{Printer, PrinterOptions};
@ -50,7 +50,7 @@ pub use builders::BestFitting;
pub use source_code::{SourceCode, SourceCodeSlice}; pub use source_code::{SourceCode, SourceCodeSlice};
pub use crate::diagnostics::{ActualStart, FormatError, InvalidDocumentError, PrintError}; pub use crate::diagnostics::{ActualStart, FormatError, InvalidDocumentError, PrintError};
pub use format_element::{normalize_newlines, FormatElement, LINE_TERMINATORS}; pub use format_element::{FormatElement, LINE_TERMINATORS, normalize_newlines};
pub use group_id::GroupId; pub use group_id::GroupId;
use ruff_macros::CacheKey; use ruff_macros::CacheKey;
use ruff_text_size::{TextLen, TextRange, TextSize}; use ruff_text_size::{TextLen, TextRange, TextSize};

View file

@ -328,16 +328,16 @@ macro_rules! format {
/// [`MostExpanded`]: crate::format_element::BestFittingVariants::most_expanded /// [`MostExpanded`]: crate::format_element::BestFittingVariants::most_expanded
#[macro_export] #[macro_export]
macro_rules! best_fitting { macro_rules! best_fitting {
($least_expanded:expr, $($tail:expr),+ $(,)?) => {{ ($least_expanded:expr, $($tail:expr),+ $(,)?) => {
// OK because the macro syntax requires at least two variants. // OK because the macro syntax requires at least two variants.
$crate::BestFitting::from_arguments_unchecked($crate::format_args!($least_expanded, $($tail),+)) $crate::BestFitting::from_arguments_unchecked($crate::format_args!($least_expanded, $($tail),+))
}} }
} }
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use crate::prelude::*; use crate::prelude::*;
use crate::{write, FormatState, SimpleFormatOptions, VecBuffer}; use crate::{FormatState, SimpleFormatOptions, VecBuffer, write};
struct TestFormat; struct TestFormat;
@ -386,7 +386,7 @@ mod tests {
#[test] #[test]
fn best_fitting_variants_print_as_lists() { fn best_fitting_variants_print_as_lists() {
use crate::prelude::*; use crate::prelude::*;
use crate::{format, format_args, Formatted}; use crate::{Formatted, format, format_args};
// The second variant below should be selected when printing at a width of 30 // The second variant below should be selected when printing at a width of 30
let formatted_best_fitting = format!( let formatted_best_fitting = format!(
@ -398,34 +398,36 @@ mod tests {
format_args![token( format_args![token(
"Something that will not fit on a line with 30 character print width." "Something that will not fit on a line with 30 character print width."
)], )],
format_args![group(&format_args![ format_args![
token("Start"), group(&format_args![
soft_line_break(), token("Start"),
group(&soft_block_indent(&format_args![ soft_line_break(),
token("1,"), group(&soft_block_indent(&format_args![
soft_line_break_or_space(), token("1,"),
token("2,"),
soft_line_break_or_space(),
token("3"),
])),
soft_line_break_or_space(),
soft_block_indent(&format_args![
token("1,"),
soft_line_break_or_space(),
token("2,"),
soft_line_break_or_space(),
group(&format_args!(
token("A,"),
soft_line_break_or_space(), soft_line_break_or_space(),
token("B") token("2,"),
)), soft_line_break_or_space(),
token("3"),
])),
soft_line_break_or_space(), soft_line_break_or_space(),
token("3") soft_block_indent(&format_args![
]), token("1,"),
soft_line_break_or_space(), soft_line_break_or_space(),
token("End") token("2,"),
]) soft_line_break_or_space(),
.should_expand(true)], group(&format_args!(
token("A,"),
soft_line_break_or_space(),
token("B")
)),
soft_line_break_or_space(),
token("3")
]),
soft_line_break_or_space(),
token("End")
])
.should_expand(true)
],
format_args!(token("Most"), hard_line_break(), token("Expanded")) format_args!(token("Most"), hard_line_break(), token("Expanded"))
] ]
] ]

View file

@ -7,6 +7,6 @@ pub use crate::formatter::Formatter;
pub use crate::printer::PrinterOptions; pub use crate::printer::PrinterOptions;
pub use crate::{ pub use crate::{
best_fitting, dbg_write, format, format_args, write, Buffer as _, BufferExtensions, Format, Buffer as _, BufferExtensions, Format, Format as _, FormatResult, FormatRule,
Format as _, FormatResult, FormatRule, FormatWithRule as _, SimpleFormatContext, FormatWithRule as _, SimpleFormatContext, best_fitting, dbg_write, format, format_args, write,
}; };

View file

@ -1,5 +1,5 @@
use crate::format_element::tag::TagKind;
use crate::format_element::PrintMode; use crate::format_element::PrintMode;
use crate::format_element::tag::TagKind;
use crate::printer::stack::{Stack, StackedStack}; use crate::printer::stack::{Stack, StackedStack};
use crate::printer::{Indentation, MeasureMode}; use crate::printer::{Indentation, MeasureMode};
use crate::{IndentStyle, InvalidDocumentError, PrintError, PrintResult}; use crate::{IndentStyle, InvalidDocumentError, PrintError, PrintResult};

View file

@ -1,5 +1,5 @@
use crate::printer::call_stack::PrintElementArgs;
use crate::FormatElement; use crate::FormatElement;
use crate::printer::call_stack::PrintElementArgs;
/// Stores the queued line suffixes. /// Stores the queued line suffixes.
#[derive(Debug, Default)] #[derive(Debug, Default)]

View file

@ -10,7 +10,7 @@ use crate::format_element::document::Document;
use crate::format_element::tag::{Condition, GroupMode}; use crate::format_element::tag::{Condition, GroupMode};
use crate::format_element::{BestFittingMode, BestFittingVariants, LineMode, PrintMode}; use crate::format_element::{BestFittingMode, BestFittingVariants, LineMode, PrintMode};
use crate::prelude::tag::{DedentMode, Tag, TagKind, VerbatimKind}; use crate::prelude::tag::{DedentMode, Tag, TagKind, VerbatimKind};
use crate::prelude::{tag, TextWidth}; use crate::prelude::{TextWidth, tag};
use crate::printer::call_stack::{ use crate::printer::call_stack::{
CallStack, FitsCallStack, PrintCallStack, PrintElementArgs, StackFrame, CallStack, FitsCallStack, PrintCallStack, PrintElementArgs, StackFrame,
}; };
@ -1199,7 +1199,7 @@ impl<'a, 'print> FitsMeasurer<'a, 'print> {
text_width: *text_width, text_width: *text_width,
}, },
args, args,
)) ));
} }
FormatElement::SourceCodeSlice { slice, text_width } => { FormatElement::SourceCodeSlice { slice, text_width } => {
let text = slice.text(self.printer.source_code); let text = slice.text(self.printer.source_code);
@ -1597,11 +1597,7 @@ enum Fits {
impl From<bool> for Fits { impl From<bool> for Fits {
fn from(value: bool) -> Self { fn from(value: bool) -> Self {
if value { if value { Fits::Yes } else { Fits::No }
Fits::Yes
} else {
Fits::No
}
} }
} }
@ -1662,8 +1658,8 @@ mod tests {
use crate::printer::{LineEnding, Printer, PrinterOptions}; use crate::printer::{LineEnding, Printer, PrinterOptions};
use crate::source_code::SourceCode; use crate::source_code::SourceCode;
use crate::{ use crate::{
format_args, write, Document, FormatState, IndentStyle, IndentWidth, LineWidth, Printed, Document, FormatState, IndentStyle, IndentWidth, LineWidth, Printed, VecBuffer,
VecBuffer, format_args, write,
}; };
fn format(root: &dyn Format<SimpleFormatContext>) -> Printed { fn format(root: &dyn Format<SimpleFormatContext>) -> Printed {
@ -1985,10 +1981,21 @@ two lines`,
token("]") token("]")
]), ]),
token(";"), token(";"),
line_suffix(&format_args![space(), token("// Using reserved width causes this content to not fit even though it's a line suffix element")], 93) line_suffix(
&format_args![
space(),
token(
"// Using reserved width causes this content to not fit even though it's a line suffix element"
)
],
93
)
]); ]);
assert_eq!(printed.as_code(), "[\n 1, 2, 3\n]; // Using reserved width causes this content to not fit even though it's a line suffix element"); assert_eq!(
printed.as_code(),
"[\n 1, 2, 3\n]; // Using reserved width causes this content to not fit even though it's a line suffix element"
);
} }
#[test] #[test]
@ -2015,7 +2022,10 @@ two lines`,
let printed = format(&content); let printed = format(&content);
assert_eq!(printed.as_code(), "The referenced group breaks.\nThis group breaks because:\nIt measures with the 'if_group_breaks' variant because the referenced group breaks and that's just way too much text."); assert_eq!(
printed.as_code(),
"The referenced group breaks.\nThis group breaks because:\nIt measures with the 'if_group_breaks' variant because the referenced group breaks and that's just way too much text."
);
} }
#[test] #[test]

View file

@ -325,10 +325,10 @@ impl FitsEndPredicate for SingleEntryPredicate {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use crate::FormatElement;
use crate::format_element::LineMode; use crate::format_element::LineMode;
use crate::prelude::Tag; use crate::prelude::Tag;
use crate::printer::queue::{PrintQueue, Queue}; use crate::printer::queue::{PrintQueue, Queue};
use crate::FormatElement;
#[test] #[test]
fn extend_back_pop_last() { fn extend_back_pop_last() {

View file

@ -65,7 +65,10 @@ pub struct SourceCodeSlice {
impl SourceCodeSlice { impl SourceCodeSlice {
/// Returns the slice's text. /// Returns the slice's text.
pub fn text<'a>(&self, code: SourceCode<'a>) -> &'a str { pub fn text<'a>(&self, code: SourceCode<'a>) -> &'a str {
assert!(usize::from(self.range.end()) <= code.text.len(), "The range of this slice is out of bounds. Did you provide the correct source code for this slice?"); assert!(
usize::from(self.range.end()) <= code.text.len(),
"The range of this slice is out of bounds. Did you provide the correct source code for this slice?"
);
&code.text[self.range] &code.text[self.range]
} }
} }

View file

@ -1,5 +1,5 @@
use ruff_python_ast::visitor::source_order::{ use ruff_python_ast::visitor::source_order::{
walk_expr, walk_module, walk_stmt, SourceOrderVisitor, SourceOrderVisitor, walk_expr, walk_module, walk_stmt,
}; };
use ruff_python_ast::{self as ast, Expr, Mod, Stmt}; use ruff_python_ast::{self as ast, Expr, Mod, Stmt};
use ty_python_semantic::ModuleName; use ty_python_semantic::ModuleName;

View file

@ -9,8 +9,8 @@ use ruff_db::{Db as SourceDb, Upcast};
use ruff_python_ast::PythonVersion; use ruff_python_ast::PythonVersion;
use ty_python_semantic::lint::{LintRegistry, RuleSelection}; use ty_python_semantic::lint::{LintRegistry, RuleSelection};
use ty_python_semantic::{ use ty_python_semantic::{
default_lint_registry, Db, Program, ProgramSettings, PythonPath, PythonPlatform, Db, Program, ProgramSettings, PythonPath, PythonPlatform, SearchPathSettings,
SearchPathSettings, default_lint_registry,
}; };
static EMPTY_VENDORED: std::sync::LazyLock<VendoredFileSystem> = std::sync::LazyLock::new(|| { static EMPTY_VENDORED: std::sync::LazyLock<VendoredFileSystem> = std::sync::LazyLock::new(|| {

View file

@ -4,7 +4,7 @@ use anyhow::Result;
use ruff_db::system::{SystemPath, SystemPathBuf}; use ruff_db::system::{SystemPath, SystemPathBuf};
use ruff_python_ast::helpers::to_module_path; use ruff_python_ast::helpers::to_module_path;
use ruff_python_parser::{parse, Mode, ParseOptions}; use ruff_python_parser::{Mode, ParseOptions, parse};
use crate::collector::Collector; use crate::collector::Collector;
pub use crate::db::ModuleDb; pub use crate::db::ModuleDb;

View file

@ -1,8 +1,8 @@
use ruff_db::files::FilePath; use ruff_db::files::FilePath;
use ty_python_semantic::resolve_module; use ty_python_semantic::resolve_module;
use crate::collector::CollectedImport;
use crate::ModuleDb; use crate::ModuleDb;
use crate::collector::CollectedImport;
/// Collect all imports for a given Python file. /// Collect all imports for a given Python file.
pub(crate) struct Resolver<'a> { pub(crate) struct Resolver<'a> {

View file

@ -1,5 +1,5 @@
use crate::vec::IndexVec;
use crate::Idx; use crate::Idx;
use crate::vec::IndexVec;
use std::fmt::{Debug, Formatter}; use std::fmt::{Debug, Formatter};
use std::marker::PhantomData; use std::marker::PhantomData;
use std::ops::{Index, IndexMut, Range}; use std::ops::{Index, IndexMut, Range};

View file

@ -1,5 +1,5 @@
use crate::slice::IndexSlice;
use crate::Idx; use crate::Idx;
use crate::slice::IndexSlice;
use std::borrow::{Borrow, BorrowMut}; use std::borrow::{Borrow, BorrowMut};
use std::fmt::{Debug, Formatter}; use std::fmt::{Debug, Formatter};
use std::marker::PhantomData; use std::marker::PhantomData;
@ -191,6 +191,6 @@ where
#[expect(unsafe_code)] #[expect(unsafe_code)]
unsafe fn maybe_update(old_pointer: *mut Self, new_value: Self) -> bool { unsafe fn maybe_update(old_pointer: *mut Self, new_value: Self) -> bool {
let old_vec: &mut IndexVec<I, T> = unsafe { &mut *old_pointer }; let old_vec: &mut IndexVec<I, T> = unsafe { &mut *old_pointer };
salsa::Update::maybe_update(&mut old_vec.raw, new_value.raw) unsafe { salsa::Update::maybe_update(&mut old_vec.raw, new_value.raw) }
} }
} }

View file

@ -4,8 +4,8 @@ use ruff_python_literal::cformat::{CFormatError, CFormatErrorType};
use ruff_diagnostics::Diagnostic; use ruff_diagnostics::Diagnostic;
use ruff_python_ast::types::Node; use ruff_python_ast::types::Node;
use ruff_python_semantic::analyze::typing;
use ruff_python_semantic::ScopeKind; use ruff_python_semantic::ScopeKind;
use ruff_python_semantic::analyze::typing;
use ruff_text_size::Ranged; use ruff_text_size::Ranged;
use crate::checkers::ast::Checker; use crate::checkers::ast::Checker;

View file

@ -46,7 +46,7 @@ impl AnnotationContext {
semantic, semantic,
) => ) =>
{ {
return Self::RuntimeRequired return Self::RuntimeRequired;
} }
ScopeKind::Function(function_def) ScopeKind::Function(function_def)
if flake8_type_checking::helpers::runtime_required_function( if flake8_type_checking::helpers::runtime_required_function(
@ -55,7 +55,7 @@ impl AnnotationContext {
semantic, semantic,
) => ) =>
{ {
return Self::RuntimeRequired return Self::RuntimeRequired;
} }
_ => {} _ => {}
} }

View file

@ -37,16 +37,16 @@ use ruff_python_ast::helpers::{collect_import_from_member, is_docstring_stmt, to
use ruff_python_ast::identifier::Identifier; use ruff_python_ast::identifier::Identifier;
use ruff_python_ast::name::QualifiedName; use ruff_python_ast::name::QualifiedName;
use ruff_python_ast::str::Quote; use ruff_python_ast::str::Quote;
use ruff_python_ast::visitor::{walk_except_handler, walk_pattern, Visitor}; use ruff_python_ast::visitor::{Visitor, walk_except_handler, walk_pattern};
use ruff_python_ast::{ use ruff_python_ast::{
self as ast, AnyParameterRef, ArgOrKeyword, Comprehension, ElifElseClause, ExceptHandler, Expr, self as ast, AnyParameterRef, ArgOrKeyword, Comprehension, ElifElseClause, ExceptHandler, Expr,
ExprContext, FStringElement, Keyword, MatchCase, ModModule, Parameter, Parameters, Pattern, ExprContext, FStringElement, Keyword, MatchCase, ModModule, Parameter, Parameters, Pattern,
PythonVersion, Stmt, Suite, UnaryOp, PythonVersion, Stmt, Suite, UnaryOp,
}; };
use ruff_python_ast::{helpers, str, visitor, PySourceType}; use ruff_python_ast::{PySourceType, helpers, str, visitor};
use ruff_python_codegen::{Generator, Stylist}; use ruff_python_codegen::{Generator, Stylist};
use ruff_python_index::Indexer; use ruff_python_index::Indexer;
use ruff_python_parser::typing::{parse_type_annotation, AnnotationKind, ParsedAnnotation}; use ruff_python_parser::typing::{AnnotationKind, ParsedAnnotation, parse_type_annotation};
use ruff_python_parser::{ParseError, Parsed, Tokens}; use ruff_python_parser::{ParseError, Parsed, Tokens};
use ruff_python_semantic::all::{DunderAllDefinition, DunderAllFlags}; use ruff_python_semantic::all::{DunderAllDefinition, DunderAllFlags};
use ruff_python_semantic::analyze::{imports, typing}; use ruff_python_semantic::analyze::{imports, typing};
@ -55,7 +55,7 @@ use ruff_python_semantic::{
Import, Module, ModuleKind, ModuleSource, NodeId, ScopeId, ScopeKind, SemanticModel, Import, Module, ModuleKind, ModuleSource, NodeId, ScopeId, ScopeKind, SemanticModel,
SemanticModelFlags, StarImport, SubmoduleImport, SemanticModelFlags, StarImport, SubmoduleImport,
}; };
use ruff_python_stdlib::builtins::{python_builtins, MAGIC_GLOBALS}; use ruff_python_stdlib::builtins::{MAGIC_GLOBALS, python_builtins};
use ruff_python_trivia::CommentRanges; use ruff_python_trivia::CommentRanges;
use ruff_source_file::{OneIndexed, SourceRow}; use ruff_source_file::{OneIndexed, SourceRow};
use ruff_text_size::{Ranged, TextRange, TextSize}; use ruff_text_size::{Ranged, TextRange, TextSize};
@ -72,8 +72,8 @@ use crate::rules::pyflakes::rules::{
}; };
use crate::rules::pylint::rules::{AwaitOutsideAsync, LoadBeforeGlobalDeclaration}; use crate::rules::pylint::rules::{AwaitOutsideAsync, LoadBeforeGlobalDeclaration};
use crate::rules::{flake8_pyi, flake8_type_checking, pyflakes, pyupgrade}; use crate::rules::{flake8_pyi, flake8_type_checking, pyflakes, pyupgrade};
use crate::settings::{flags, LinterSettings, TargetVersion}; use crate::settings::{LinterSettings, TargetVersion, flags};
use crate::{docstrings, noqa, Locator}; use crate::{Locator, docstrings, noqa};
mod analyze; mod analyze;
mod annotation; mod annotation;
@ -2160,7 +2160,9 @@ impl<'a> Checker<'a> {
self.visit_expr(&generator.iter); self.visit_expr(&generator.iter);
self.semantic.push_scope(ScopeKind::Generator { self.semantic.push_scope(ScopeKind::Generator {
kind, kind,
is_async: generators.iter().any(|gen| gen.is_async), is_async: generators
.iter()
.any(|comprehension| comprehension.is_async),
}); });
self.visit_expr(&generator.target); self.visit_expr(&generator.target);

View file

@ -4,6 +4,7 @@ use ruff_diagnostics::Diagnostic;
use ruff_python_ast::PythonVersion; use ruff_python_ast::PythonVersion;
use ruff_python_trivia::CommentRanges; use ruff_python_trivia::CommentRanges;
use crate::Locator;
use crate::package::PackageRoot; use crate::package::PackageRoot;
use crate::preview::is_allow_nested_roots_enabled; use crate::preview::is_allow_nested_roots_enabled;
use crate::registry::Rule; use crate::registry::Rule;
@ -11,7 +12,6 @@ use crate::rules::flake8_builtins::rules::stdlib_module_shadowing;
use crate::rules::flake8_no_pep420::rules::implicit_namespace_package; use crate::rules::flake8_no_pep420::rules::implicit_namespace_package;
use crate::rules::pep8_naming::rules::invalid_module_name; use crate::rules::pep8_naming::rules::invalid_module_name;
use crate::settings::LinterSettings; use crate::settings::LinterSettings;
use crate::Locator;
pub(crate) fn check_file_path( pub(crate) fn check_file_path(
path: &Path, path: &Path,

View file

@ -8,13 +8,13 @@ use ruff_python_codegen::Stylist;
use ruff_python_index::Indexer; use ruff_python_index::Indexer;
use ruff_python_parser::Parsed; use ruff_python_parser::Parsed;
use crate::Locator;
use crate::directives::IsortDirectives; use crate::directives::IsortDirectives;
use crate::package::PackageRoot; use crate::package::PackageRoot;
use crate::registry::Rule; use crate::registry::Rule;
use crate::rules::isort; use crate::rules::isort;
use crate::rules::isort::block::{Block, BlockBuilder}; use crate::rules::isort::block::{Block, BlockBuilder};
use crate::settings::LinterSettings; use crate::settings::LinterSettings;
use crate::Locator;
#[expect(clippy::too_many_arguments)] #[expect(clippy::too_many_arguments)]
pub(crate) fn check_imports( pub(crate) fn check_imports(

View file

@ -5,16 +5,17 @@ use ruff_python_parser::{TokenKind, Tokens};
use ruff_source_file::LineRanges; use ruff_source_file::LineRanges;
use ruff_text_size::{Ranged, TextRange}; use ruff_text_size::{Ranged, TextRange};
use crate::Locator;
use crate::line_width::IndentWidth; use crate::line_width::IndentWidth;
use crate::registry::{AsRule, Rule}; use crate::registry::{AsRule, Rule};
use crate::rules::pycodestyle::rules::logical_lines::{ use crate::rules::pycodestyle::rules::logical_lines::{
extraneous_whitespace, indentation, missing_whitespace, missing_whitespace_after_keyword, LogicalLines, TokenFlags, extraneous_whitespace, indentation, missing_whitespace,
missing_whitespace_around_operator, redundant_backslash, space_after_comma, missing_whitespace_after_keyword, missing_whitespace_around_operator, redundant_backslash,
space_around_operator, whitespace_around_keywords, whitespace_around_named_parameter_equals, space_after_comma, space_around_operator, whitespace_around_keywords,
whitespace_before_comment, whitespace_before_parameters, LogicalLines, TokenFlags, whitespace_around_named_parameter_equals, whitespace_before_comment,
whitespace_before_parameters,
}; };
use crate::settings::LinterSettings; use crate::settings::LinterSettings;
use crate::Locator;
/// Return the amount of indentation, expanding tabs to the next multiple of the settings' tab size. /// Return the amount of indentation, expanding tabs to the next multiple of the settings' tab size.
pub(crate) fn expand_indent(line: &str, indent_width: IndentWidth) -> usize { pub(crate) fn expand_indent(line: &str, indent_width: IndentWidth) -> usize {

View file

@ -9,6 +9,7 @@ use ruff_diagnostics::{Diagnostic, Edit, Fix};
use ruff_python_trivia::CommentRanges; use ruff_python_trivia::CommentRanges;
use ruff_text_size::Ranged; use ruff_text_size::Ranged;
use crate::Locator;
use crate::fix::edits::delete_comment; use crate::fix::edits::delete_comment;
use crate::noqa::{ use crate::noqa::{
Code, Directive, FileExemption, FileNoqaDirectives, NoqaDirectives, NoqaMapping, Code, Directive, FileExemption, FileNoqaDirectives, NoqaDirectives, NoqaMapping,
@ -20,7 +21,6 @@ use crate::rules::pygrep_hooks;
use crate::rules::ruff; use crate::rules::ruff;
use crate::rules::ruff::rules::{UnusedCodes, UnusedNOQA}; use crate::rules::ruff::rules::{UnusedCodes, UnusedNOQA};
use crate::settings::LinterSettings; use crate::settings::LinterSettings;
use crate::Locator;
#[expect(clippy::too_many_arguments)] #[expect(clippy::too_many_arguments)]
pub(crate) fn check_noqa( pub(crate) fn check_noqa(

View file

@ -6,6 +6,7 @@ use ruff_python_index::Indexer;
use ruff_source_file::UniversalNewlines; use ruff_source_file::UniversalNewlines;
use ruff_text_size::TextSize; use ruff_text_size::TextSize;
use crate::Locator;
use crate::registry::Rule; use crate::registry::Rule;
use crate::rules::flake8_copyright::rules::missing_copyright_notice; use crate::rules::flake8_copyright::rules::missing_copyright_notice;
use crate::rules::pycodestyle::rules::{ use crate::rules::pycodestyle::rules::{
@ -15,7 +16,6 @@ use crate::rules::pycodestyle::rules::{
use crate::rules::pylint; use crate::rules::pylint;
use crate::rules::ruff::rules::indented_form_feed; use crate::rules::ruff::rules::indented_form_feed;
use crate::settings::LinterSettings; use crate::settings::LinterSettings;
use crate::Locator;
pub(crate) fn check_physical_lines( pub(crate) fn check_physical_lines(
locator: &Locator, locator: &Locator,
@ -101,11 +101,11 @@ mod tests {
use ruff_python_index::Indexer; use ruff_python_index::Indexer;
use ruff_python_parser::parse_module; use ruff_python_parser::parse_module;
use crate::Locator;
use crate::line_width::LineLength; use crate::line_width::LineLength;
use crate::registry::Rule; use crate::registry::Rule;
use crate::rules::pycodestyle; use crate::rules::pycodestyle;
use crate::settings::LinterSettings; use crate::settings::LinterSettings;
use crate::Locator;
use super::check_physical_lines; use super::check_physical_lines;

View file

@ -9,6 +9,7 @@ use ruff_python_codegen::Stylist;
use ruff_python_index::Indexer; use ruff_python_index::Indexer;
use ruff_python_parser::Tokens; use ruff_python_parser::Tokens;
use crate::Locator;
use crate::directives::TodoComment; use crate::directives::TodoComment;
use crate::registry::{AsRule, Rule}; use crate::registry::{AsRule, Rule};
use crate::rules::pycodestyle::rules::BlankLinesChecker; use crate::rules::pycodestyle::rules::BlankLinesChecker;
@ -17,7 +18,6 @@ use crate::rules::{
flake8_pyi, flake8_todos, pycodestyle, pygrep_hooks, pylint, pyupgrade, ruff, flake8_pyi, flake8_todos, pycodestyle, pygrep_hooks, pylint, pyupgrade, ruff,
}; };
use crate::settings::LinterSettings; use crate::settings::LinterSettings;
use crate::Locator;
#[expect(clippy::too_many_arguments)] #[expect(clippy::too_many_arguments)]
pub(crate) fn check_tokens( pub(crate) fn check_tokens(

View file

@ -19,14 +19,14 @@ pub(crate) fn or_space(whitespace: ParenthesizableWhitespace) -> Parenthesizable
/// Negate a condition, i.e., `a` => `not a` and `not a` => `a`. /// Negate a condition, i.e., `a` => `not a` and `not a` => `a`.
pub(crate) fn negate<'a>(expression: &Expression<'a>) -> Expression<'a> { pub(crate) fn negate<'a>(expression: &Expression<'a>) -> Expression<'a> {
if let Expression::UnaryOperation(ref expression) = expression { if let Expression::UnaryOperation(expression) = expression {
if matches!(expression.operator, libcst_native::UnaryOp::Not { .. }) { if matches!(expression.operator, libcst_native::UnaryOp::Not { .. }) {
return *expression.expression.clone(); return *expression.expression.clone();
} }
} }
// If the expression is `True` or `False`, return the opposite. // If the expression is `True` or `False`, return the opposite.
if let Expression::Name(ref expression) = expression { if let Expression::Name(expression) = expression {
match expression.value { match expression.value {
"True" => { "True" => {
return Expression::Name(Box::new(Name { return Expression::Name(Box::new(Name {

View file

@ -1,5 +1,5 @@
use crate::fix::codemods::CodegenStylist; use crate::fix::codemods::CodegenStylist;
use anyhow::{bail, Result}; use anyhow::{Result, bail};
use libcst_native::{ use libcst_native::{
Arg, Attribute, Call, Comparison, CompoundStatement, Dict, Expression, FormattedString, Arg, Attribute, Call, Comparison, CompoundStatement, Dict, Expression, FormattedString,
FormattedStringContent, FormattedStringExpression, FunctionDef, GeneratorExp, If, Import, FormattedStringContent, FormattedStringExpression, FunctionDef, GeneratorExp, If, Import,

View file

@ -11,9 +11,9 @@ use ruff_python_trivia::CommentRanges;
use ruff_source_file::LineRanges; use ruff_source_file::LineRanges;
use ruff_text_size::{Ranged, TextLen, TextRange, TextSize}; use ruff_text_size::{Ranged, TextLen, TextRange, TextSize};
use crate::Locator;
use crate::noqa::NoqaMapping; use crate::noqa::NoqaMapping;
use crate::settings::LinterSettings; use crate::settings::LinterSettings;
use crate::Locator;
bitflags! { bitflags! {
#[derive(Debug, Copy, Clone)] #[derive(Debug, Copy, Clone)]
@ -366,11 +366,11 @@ mod tests {
use ruff_python_trivia::CommentRanges; use ruff_python_trivia::CommentRanges;
use ruff_text_size::{TextLen, TextRange, TextSize}; use ruff_text_size::{TextLen, TextRange, TextSize};
use crate::Locator;
use crate::directives::{ use crate::directives::{
extract_isort_directives, extract_noqa_line_for, TodoDirective, TodoDirectiveKind, TodoDirective, TodoDirectiveKind, extract_isort_directives, extract_noqa_line_for,
}; };
use crate::noqa::NoqaMapping; use crate::noqa::NoqaMapping;
use crate::Locator;
use super::IsortDirectives; use super::IsortDirectives;

View file

@ -4,7 +4,7 @@
use std::iter::FusedIterator; use std::iter::FusedIterator;
use std::slice::Iter; use std::slice::Iter;
use ruff_python_ast::statement_visitor::{walk_stmt, StatementVisitor}; use ruff_python_ast::statement_visitor::{StatementVisitor, walk_stmt};
use ruff_python_ast::{self as ast, Stmt, Suite}; use ruff_python_ast::{self as ast, Stmt, Suite};
use ruff_python_parser::{Token, TokenKind, Tokens}; use ruff_python_parser::{Token, TokenKind, Tokens};
use ruff_source_file::UniversalNewlineIterator; use ruff_source_file::UniversalNewlineIterator;

View file

@ -444,8 +444,7 @@ fn is_docstring_section(
if next_line.is_empty() { if next_line.is_empty() {
false false
} else { } else {
let next_line_is_underline = next_line.chars().all(|char| matches!(char, '-' | '=')); next_line.chars().all(|char| matches!(char, '-' | '='))
next_line_is_underline
} }
}); });
if next_line_is_underline { if next_line_is_underline {

View file

@ -2,21 +2,21 @@
//! and return the modified code snippet as output. //! and return the modified code snippet as output.
use std::borrow::Cow; use std::borrow::Cow;
use anyhow::{bail, Result}; use anyhow::{Result, bail};
use libcst_native::{ use libcst_native::{
Codegen, CodegenState, Expression, ImportNames, NameOrAttribute, ParenthesizableWhitespace, Codegen, CodegenState, Expression, ImportNames, NameOrAttribute, ParenthesizableWhitespace,
SmallStatement, Statement, SmallStatement, Statement,
}; };
use rustc_hash::{FxHashMap, FxHashSet}; use rustc_hash::{FxHashMap, FxHashSet};
use smallvec::{smallvec, SmallVec}; use smallvec::{SmallVec, smallvec};
use unicode_normalization::UnicodeNormalization; use unicode_normalization::UnicodeNormalization;
use ruff_python_ast::name::UnqualifiedName;
use ruff_python_ast::Stmt; use ruff_python_ast::Stmt;
use ruff_python_ast::name::UnqualifiedName;
use ruff_python_codegen::Stylist; use ruff_python_codegen::Stylist;
use crate::cst::matchers::match_statement;
use crate::Locator; use crate::Locator;
use crate::cst::matchers::match_statement;
/// Glue code to make libcst codegen work with ruff's Stylist /// Glue code to make libcst codegen work with ruff's Stylist
pub(crate) trait CodegenStylist<'a>: Codegen<'a> { pub(crate) trait CodegenStylist<'a>: Codegen<'a> {

View file

@ -10,17 +10,17 @@ use ruff_python_codegen::Stylist;
use ruff_python_index::Indexer; use ruff_python_index::Indexer;
use ruff_python_trivia::textwrap::dedent_to; use ruff_python_trivia::textwrap::dedent_to;
use ruff_python_trivia::{ use ruff_python_trivia::{
has_leading_content, is_python_whitespace, CommentRanges, PythonWhitespace, SimpleTokenKind, CommentRanges, PythonWhitespace, SimpleTokenKind, SimpleTokenizer, has_leading_content,
SimpleTokenizer, is_python_whitespace,
}; };
use ruff_source_file::{LineRanges, NewlineWithTrailingNewline, UniversalNewlines}; use ruff_source_file::{LineRanges, NewlineWithTrailingNewline, UniversalNewlines};
use ruff_text_size::{Ranged, TextLen, TextRange, TextSize}; use ruff_text_size::{Ranged, TextLen, TextRange, TextSize};
use crate::Locator;
use crate::cst::matchers::{match_function_def, match_indented_block, match_statement}; use crate::cst::matchers::{match_function_def, match_indented_block, match_statement};
use crate::fix::codemods; use crate::fix::codemods;
use crate::fix::codemods::CodegenStylist; use crate::fix::codemods::CodegenStylist;
use crate::line_width::{IndentWidth, LineLength, LineWidthBuilder}; use crate::line_width::{IndentWidth, LineLength, LineWidthBuilder};
use crate::Locator;
/// Return the [`Edit`] to use when deleting a [`Stmt`]. /// Return the [`Edit`] to use when deleting a [`Stmt`].
/// ///
@ -591,7 +591,7 @@ fn all_lines_fit(
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use anyhow::{anyhow, Result}; use anyhow::{Result, anyhow};
use ruff_source_file::SourceFileBuilder; use ruff_source_file::SourceFileBuilder;
use test_case::test_case; use test_case::test_case;
@ -601,12 +601,12 @@ mod tests {
use ruff_python_parser::{parse_expression, parse_module}; use ruff_python_parser::{parse_expression, parse_module};
use ruff_text_size::{Ranged, TextRange, TextSize}; use ruff_text_size::{Ranged, TextRange, TextSize};
use crate::Locator;
use crate::fix::apply_fixes; use crate::fix::apply_fixes;
use crate::fix::edits::{ use crate::fix::edits::{
add_to_dunder_all, make_redundant_alias, next_stmt_break, trailing_semicolon, add_to_dunder_all, make_redundant_alias, next_stmt_break, trailing_semicolon,
}; };
use crate::message::DiagnosticMessage; use crate::message::DiagnosticMessage;
use crate::Locator;
/// Parse the given source using [`Mode::Module`] and return the first statement. /// Parse the given source using [`Mode::Module`] and return the first statement.
fn parse_first_stmt(source: &str) -> Result<Stmt> { fn parse_first_stmt(source: &str) -> Result<Stmt> {

View file

@ -6,11 +6,11 @@ use rustc_hash::{FxHashMap, FxHashSet};
use ruff_diagnostics::{Edit, Fix, IsolationLevel, SourceMap}; use ruff_diagnostics::{Edit, Fix, IsolationLevel, SourceMap};
use ruff_text_size::{Ranged, TextLen, TextRange, TextSize}; use ruff_text_size::{Ranged, TextLen, TextRange, TextSize};
use crate::Locator;
use crate::linter::FixTable; use crate::linter::FixTable;
use crate::message::{DiagnosticMessage, Message}; use crate::message::{DiagnosticMessage, Message};
use crate::registry::{AsRule, Rule}; use crate::registry::{AsRule, Rule};
use crate::settings::types::UnsafeFixes; use crate::settings::types::UnsafeFixes;
use crate::Locator;
pub(crate) mod codemods; pub(crate) mod codemods;
pub(crate) mod edits; pub(crate) mod edits;
@ -162,10 +162,10 @@ mod tests {
use ruff_source_file::SourceFileBuilder; use ruff_source_file::SourceFileBuilder;
use ruff_text_size::{Ranged, TextSize}; use ruff_text_size::{Ranged, TextSize};
use crate::fix::{apply_fixes, FixResult}; use crate::Locator;
use crate::fix::{FixResult, apply_fixes};
use crate::message::DiagnosticMessage; use crate::message::DiagnosticMessage;
use crate::rules::pycodestyle::rules::MissingNewlineAtEndOfFile; use crate::rules::pycodestyle::rules::MissingNewlineAtEndOfFile;
use crate::Locator;
fn create_diagnostics( fn create_diagnostics(
filename: &str, filename: &str,

View file

@ -2,11 +2,11 @@
use std::ops::Add; use std::ops::Add;
use ruff_diagnostics::Edit; use ruff_diagnostics::Edit;
use ruff_python_ast::helpers::is_docstring_stmt;
use ruff_python_ast::Stmt; use ruff_python_ast::Stmt;
use ruff_python_ast::helpers::is_docstring_stmt;
use ruff_python_codegen::Stylist; use ruff_python_codegen::Stylist;
use ruff_python_parser::{TokenKind, Tokens}; use ruff_python_parser::{TokenKind, Tokens};
use ruff_python_trivia::{textwrap::indent, PythonWhitespace}; use ruff_python_trivia::{PythonWhitespace, textwrap::indent};
use ruff_source_file::{LineRanges, UniversalNewlineIterator}; use ruff_source_file::{LineRanges, UniversalNewlineIterator};
use ruff_text_size::{Ranged, TextSize}; use ruff_text_size::{Ranged, TextSize};

View file

@ -18,11 +18,11 @@ use ruff_python_semantic::{
use ruff_python_trivia::textwrap::indent; use ruff_python_trivia::textwrap::indent;
use ruff_text_size::{Ranged, TextSize}; use ruff_text_size::{Ranged, TextSize};
use crate::Locator;
use crate::cst::matchers::{match_aliases, match_import_from, match_statement}; use crate::cst::matchers::{match_aliases, match_import_from, match_statement};
use crate::fix; use crate::fix;
use crate::fix::codemods::CodegenStylist; use crate::fix::codemods::CodegenStylist;
use crate::importer::insertion::Insertion; use crate::importer::insertion::Insertion;
use crate::Locator;
mod insertion; mod insertion;

View file

@ -9,9 +9,9 @@ pub use locator::Locator;
pub use noqa::generate_noqa_edits; pub use noqa::generate_noqa_edits;
#[cfg(feature = "clap")] #[cfg(feature = "clap")]
pub use registry::clap_completion::RuleParser; pub use registry::clap_completion::RuleParser;
pub use rule_selector::RuleSelector;
#[cfg(feature = "clap")] #[cfg(feature = "clap")]
pub use rule_selector::clap_completion::RuleSelectorParser; pub use rule_selector::clap_completion::RuleSelectorParser;
pub use rule_selector::RuleSelector;
pub use rules::pycodestyle::rules::IOError; pub use rules::pycodestyle::rules::IOError;
pub const VERSION: &str = env!("CARGO_PKG_VERSION"); pub const VERSION: &str = env!("CARGO_PKG_VERSION");

View file

@ -1,7 +1,7 @@
use std::error::Error; use std::error::Error;
use std::fmt; use std::fmt;
use std::hash::Hasher; use std::hash::Hasher;
use std::num::{NonZeroU16, NonZeroU8, ParseIntError}; use std::num::{NonZeroU8, NonZeroU16, ParseIntError};
use std::str::FromStr; use std::str::FromStr;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};

View file

@ -3,7 +3,7 @@ use std::cell::LazyCell;
use std::ops::Deref; use std::ops::Deref;
use std::path::Path; use std::path::Path;
use anyhow::{anyhow, Result}; use anyhow::{Result, anyhow};
use colored::Colorize; use colored::Colorize;
use itertools::Itertools; use itertools::Itertools;
use ruff_python_parser::semantic_errors::SemanticSyntaxError; use ruff_python_parser::semantic_errors::SemanticSyntaxError;
@ -26,18 +26,18 @@ use crate::checkers::physical_lines::check_physical_lines;
use crate::checkers::tokens::check_tokens; use crate::checkers::tokens::check_tokens;
use crate::directives::Directives; use crate::directives::Directives;
use crate::doc_lines::{doc_lines_from_ast, doc_lines_from_tokens}; use crate::doc_lines::{doc_lines_from_ast, doc_lines_from_tokens};
use crate::fix::{fix_file, FixResult}; use crate::fix::{FixResult, fix_file};
use crate::message::Message; use crate::message::Message;
use crate::noqa::add_noqa; use crate::noqa::add_noqa;
use crate::package::PackageRoot; use crate::package::PackageRoot;
use crate::preview::{is_py314_support_enabled, is_unsupported_syntax_enabled}; use crate::preview::{is_py314_support_enabled, is_unsupported_syntax_enabled};
use crate::registry::{AsRule, Rule, RuleSet}; use crate::registry::{AsRule, Rule, RuleSet};
#[cfg(any(feature = "test-rules", test))] #[cfg(any(feature = "test-rules", test))]
use crate::rules::ruff::rules::test_rules::{self, TestRule, TEST_RULES}; use crate::rules::ruff::rules::test_rules::{self, TEST_RULES, TestRule};
use crate::settings::types::UnsafeFixes; use crate::settings::types::UnsafeFixes;
use crate::settings::{flags, LinterSettings, TargetVersion}; use crate::settings::{LinterSettings, TargetVersion, flags};
use crate::source_kind::SourceKind; use crate::source_kind::SourceKind;
use crate::{directives, fs, warn_user_once, Locator}; use crate::{Locator, directives, fs, warn_user_once};
pub struct LinterResult { pub struct LinterResult {
/// A collection of diagnostic messages generated by the linter. /// A collection of diagnostic messages generated by the linter.
@ -454,7 +454,9 @@ pub fn lint_only(
if matches!(target_version, TargetVersion(Some(PythonVersion::PY314))) if matches!(target_version, TargetVersion(Some(PythonVersion::PY314)))
&& !is_py314_support_enabled(settings) && !is_py314_support_enabled(settings)
{ {
warn_user_once!("Support for Python 3.14 is under development and may be unstable. Enable `preview` to remove this warning."); warn_user_once!(
"Support for Python 3.14 is under development and may be unstable. Enable `preview` to remove this warning."
);
} }
let parsed = source.into_parsed(source_kind, source_type, target_version.parser_version()); let parsed = source.into_parsed(source_kind, source_type, target_version.parser_version());
@ -568,7 +570,9 @@ pub fn lint_fix<'a>(
if matches!(target_version, TargetVersion(Some(PythonVersion::PY314))) if matches!(target_version, TargetVersion(Some(PythonVersion::PY314)))
&& !is_py314_support_enabled(settings) && !is_py314_support_enabled(settings)
{ {
warn_user_once!("Support for Python 3.14 is under development and may be unstable. Enable `preview` to remove this warning."); warn_user_once!(
"Support for Python 3.14 is under development and may be unstable. Enable `preview` to remove this warning."
);
} }
// Continuously fix until the source code stabilizes. // Continuously fix until the source code stabilizes.
@ -806,8 +810,8 @@ mod tests {
use crate::registry::Rule; use crate::registry::Rule;
use crate::settings::LinterSettings; use crate::settings::LinterSettings;
use crate::source_kind::SourceKind; use crate::source_kind::SourceKind;
use crate::test::{assert_notebook_path, test_contents, test_snippet, TestedNotebook}; use crate::test::{TestedNotebook, assert_notebook_path, test_contents, test_snippet};
use crate::{assert_messages, directives, settings, Locator}; use crate::{Locator, assert_messages, directives, settings};
/// Construct a path to a Jupyter notebook in the `resources/test/fixtures/jupyter` directory. /// Construct a path to a Jupyter notebook in the `resources/test/fixtures/jupyter` directory.
fn notebook_path(path: impl AsRef<Path>) -> std::path::PathBuf { fn notebook_path(path: impl AsRef<Path>) -> std::path::PathBuf {

View file

@ -47,10 +47,10 @@ impl Emitter for AzureEmitter {
mod tests { mod tests {
use insta::assert_snapshot; use insta::assert_snapshot;
use crate::message::AzureEmitter;
use crate::message::tests::{ use crate::message::tests::{
capture_emitter_output, create_messages, create_syntax_error_messages, capture_emitter_output, create_messages, create_syntax_error_messages,
}; };
use crate::message::AzureEmitter;
#[test] #[test]
fn output() { fn output() {

View file

@ -32,7 +32,9 @@ impl Emitter for GithubEmitter {
write!( write!(
writer, writer,
"::error title=Ruff{code},file={file},line={row},col={column},endLine={end_row},endColumn={end_column}::", "::error title=Ruff{code},file={file},line={row},col={column},endLine={end_row},endColumn={end_column}::",
code = message.rule().map_or_else(String::new, |rule| format!(" ({})", rule.noqa_code())), code = message
.rule()
.map_or_else(String::new, |rule| format!(" ({})", rule.noqa_code())),
file = message.filename(), file = message.filename(),
row = source_location.line, row = source_location.line,
column = source_location.column, column = source_location.column,
@ -63,10 +65,10 @@ impl Emitter for GithubEmitter {
mod tests { mod tests {
use insta::assert_snapshot; use insta::assert_snapshot;
use crate::message::GithubEmitter;
use crate::message::tests::{ use crate::message::tests::{
capture_emitter_output, create_messages, create_syntax_error_messages, capture_emitter_output, create_messages, create_syntax_error_messages,
}; };
use crate::message::GithubEmitter;
#[test] #[test]
fn output() { fn output() {

View file

@ -1,5 +1,5 @@
use std::collections::hash_map::DefaultHasher;
use std::collections::HashSet; use std::collections::HashSet;
use std::collections::hash_map::DefaultHasher;
use std::hash::{Hash, Hasher}; use std::hash::{Hash, Hasher};
use std::io::Write; use std::io::Write;
@ -137,10 +137,10 @@ fn fingerprint(message: &Message, project_path: &str, salt: u64) -> u64 {
mod tests { mod tests {
use insta::assert_snapshot; use insta::assert_snapshot;
use crate::message::GitlabEmitter;
use crate::message::tests::{ use crate::message::tests::{
capture_emitter_output, create_messages, create_syntax_error_messages, capture_emitter_output, create_messages, create_syntax_error_messages,
}; };
use crate::message::GitlabEmitter;
#[test] #[test]
fn output() { fn output() {

View file

@ -11,7 +11,7 @@ use crate::fs::relativize_path;
use crate::message::diff::calculate_print_width; use crate::message::diff::calculate_print_width;
use crate::message::text::{MessageCodeFrame, RuleCodeAndBody}; use crate::message::text::{MessageCodeFrame, RuleCodeAndBody};
use crate::message::{ use crate::message::{
group_messages_by_filename, Emitter, EmitterContext, Message, MessageWithLocation, Emitter, EmitterContext, Message, MessageWithLocation, group_messages_by_filename,
}; };
use crate::settings::types::UnsafeFixes; use crate::settings::types::UnsafeFixes;
@ -205,10 +205,10 @@ impl std::fmt::Write for PadAdapter<'_> {
mod tests { mod tests {
use insta::assert_snapshot; use insta::assert_snapshot;
use crate::message::GroupedEmitter;
use crate::message::tests::{ use crate::message::tests::{
capture_emitter_output, create_messages, create_syntax_error_messages, capture_emitter_output, create_messages, create_syntax_error_messages,
}; };
use crate::message::GroupedEmitter;
use crate::settings::types::UnsafeFixes; use crate::settings::types::UnsafeFixes;
#[test] #[test]

View file

@ -2,7 +2,7 @@ use std::io::Write;
use serde::ser::SerializeSeq; use serde::ser::SerializeSeq;
use serde::{Serialize, Serializer}; use serde::{Serialize, Serializer};
use serde_json::{json, Value}; use serde_json::{Value, json};
use ruff_diagnostics::Edit; use ruff_diagnostics::Edit;
use ruff_notebook::NotebookIndex; use ruff_notebook::NotebookIndex;
@ -178,11 +178,11 @@ impl Serialize for ExpandedEdits<'_> {
mod tests { mod tests {
use insta::assert_snapshot; use insta::assert_snapshot;
use crate::message::JsonEmitter;
use crate::message::tests::{ use crate::message::tests::{
capture_emitter_notebook_output, capture_emitter_output, create_messages, capture_emitter_notebook_output, capture_emitter_output, create_messages,
create_notebook_messages, create_syntax_error_messages, create_notebook_messages, create_syntax_error_messages,
}; };
use crate::message::JsonEmitter;
#[test] #[test]
fn output() { fn output() {

View file

@ -6,7 +6,7 @@ use quick_junit::{NonSuccessKind, Report, TestCase, TestCaseStatus, TestSuite, X
use ruff_source_file::LineColumn; use ruff_source_file::LineColumn;
use crate::message::{ use crate::message::{
group_messages_by_filename, Emitter, EmitterContext, Message, MessageWithLocation, Emitter, EmitterContext, Message, MessageWithLocation, group_messages_by_filename,
}; };
#[derive(Default)] #[derive(Default)]
@ -95,10 +95,10 @@ impl Emitter for JunitEmitter {
mod tests { mod tests {
use insta::assert_snapshot; use insta::assert_snapshot;
use crate::message::JunitEmitter;
use crate::message::tests::{ use crate::message::tests::{
capture_emitter_output, create_messages, create_syntax_error_messages, capture_emitter_output, create_messages, create_syntax_error_messages,
}; };
use crate::message::JunitEmitter;
#[test] #[test]
fn output() { fn output() {

Some files were not shown because too many files have changed in this diff Show more