mirror of https://github.com/astral-sh/ruff
Upgrade to Rust 1.86 and bump MSRV to 1.84 (#17171)
<!-- Thank you for contributing to Ruff! To help us out with reviewing, please consider the following: - Does this pull request include a summary of the change? (See below.) - Does this pull request include a descriptive title? - Does this pull request include references to any relevant issues? --> ## Summary I decided to disable the new [`needless_continue`](https://rust-lang.github.io/rust-clippy/master/index.html#needless_continue) rule because I often found the explicit `continue` more readable over an empty block or having to invert the condition of an other branch. ## Test Plan `cargo test` --------- Co-authored-by: Alex Waygood <Alex.Waygood@Gmail.com>
This commit is contained in:
parent
fedd982fd5
commit
8a4158c5f8
|
|
@ -4,7 +4,7 @@ resolver = "2"
|
|||
|
||||
[workspace.package]
|
||||
edition = "2021"
|
||||
rust-version = "1.83"
|
||||
rust-version = "1.84"
|
||||
homepage = "https://docs.astral.sh/ruff"
|
||||
documentation = "https://docs.astral.sh/ruff"
|
||||
repository = "https://github.com/astral-sh/ruff"
|
||||
|
|
@ -209,6 +209,7 @@ must_use_candidate = "allow"
|
|||
similar_names = "allow"
|
||||
single_match_else = "allow"
|
||||
too_many_lines = "allow"
|
||||
needless_continue = "allow" # An explicit continue can be more readable, especially if the alternative is an empty block.
|
||||
# Without the hashes we run into a `rustfmt` bug in some snapshot tests, see #13250
|
||||
needless_raw_string_hashes = "allow"
|
||||
# Disallowed restriction lints
|
||||
|
|
@ -227,6 +228,10 @@ redundant_clone = "warn"
|
|||
debug_assert_with_mut_call = "warn"
|
||||
unused_peekable = "warn"
|
||||
|
||||
# Has false positives
|
||||
# https://github.com/rust-lang/rust-clippy/issues/14275
|
||||
doc_overindented_list_items = "allow"
|
||||
|
||||
# Diagnostics are not actionable: Enable once https://github.com/rust-lang/rust-clippy/issues/13774 is resolved.
|
||||
large_stack_arrays = "allow"
|
||||
|
||||
|
|
|
|||
|
|
@ -159,7 +159,7 @@ impl salsa::Database for ProjectDatabase {
|
|||
}
|
||||
|
||||
let event = event();
|
||||
if matches!(event.kind, salsa::EventKind::WillCheckCancellation { .. }) {
|
||||
if matches!(event.kind, salsa::EventKind::WillCheckCancellation) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -187,7 +187,7 @@ impl ProjectDatabase {
|
|||
let program = Program::get(self);
|
||||
if let Err(error) = program.update_from_settings(self, program_settings) {
|
||||
tracing::error!("Failed to update the program settings, keeping the old program settings: {error}");
|
||||
};
|
||||
}
|
||||
|
||||
if metadata.root() == project.root(self) {
|
||||
tracing::debug!("Reloading project after structural change");
|
||||
|
|
|
|||
|
|
@ -322,6 +322,7 @@ fn python_version_from_versions_file_string(
|
|||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use std::fmt::Write as _;
|
||||
use std::num::{IntErrorKind, NonZeroU16};
|
||||
use std::path::Path;
|
||||
|
||||
|
|
@ -333,8 +334,7 @@ mod tests {
|
|||
|
||||
const TYPESHED_STDLIB_DIR: &str = "stdlib";
|
||||
|
||||
#[allow(unsafe_code)]
|
||||
const ONE: Option<NonZeroU16> = Some(unsafe { NonZeroU16::new_unchecked(1) });
|
||||
const ONE: Option<NonZeroU16> = Some(NonZeroU16::new(1).unwrap());
|
||||
|
||||
impl TypeshedVersions {
|
||||
#[must_use]
|
||||
|
|
@ -571,7 +571,7 @@ foo: 3.8- # trailing comment
|
|||
|
||||
let mut massive_versions_file = String::new();
|
||||
for i in 0..too_many {
|
||||
massive_versions_file.push_str(&format!("x{i}: 3.8-\n"));
|
||||
let _ = writeln!(&mut massive_versions_file, "x{i}: 3.8-");
|
||||
}
|
||||
|
||||
assert_eq!(
|
||||
|
|
|
|||
|
|
@ -1448,7 +1448,7 @@ where
|
|||
self.visit_expr(subject);
|
||||
if cases.is_empty() {
|
||||
return;
|
||||
};
|
||||
}
|
||||
|
||||
let after_subject = self.flow_snapshot();
|
||||
let mut vis_constraints = vec![];
|
||||
|
|
|
|||
|
|
@ -145,7 +145,7 @@ pub(crate) fn check_suppressions(db: &dyn Db, file: File, diagnostics: &mut Type
|
|||
fn check_unknown_rule(context: &mut CheckSuppressionsContext) {
|
||||
if context.is_lint_disabled(&UNKNOWN_RULE) {
|
||||
return;
|
||||
};
|
||||
}
|
||||
|
||||
for unknown in &context.suppressions.unknown {
|
||||
match &unknown.reason {
|
||||
|
|
@ -174,7 +174,7 @@ fn check_unknown_rule(context: &mut CheckSuppressionsContext) {
|
|||
format_args!("Unknown rule `{prefixed}`. Did you mean `{suggestion}`?"),
|
||||
);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -267,7 +267,7 @@ fn check_unused_suppressions(context: &mut CheckSuppressionsContext) {
|
|||
suppression.range,
|
||||
format_args!("Unused `{kind}` without a code", kind = suppression.kind),
|
||||
),
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -657,7 +657,7 @@ fn symbol_from_bindings_impl<'db>(
|
|||
binding,
|
||||
visibility_constraint,
|
||||
narrowing_constraint: _,
|
||||
}) if binding.map_or(true, is_non_exported) => {
|
||||
}) if binding.is_none_or(is_non_exported) => {
|
||||
visibility_constraints.evaluate(db, predicates, *visibility_constraint)
|
||||
}
|
||||
_ => Truthiness::AlwaysFalse,
|
||||
|
|
@ -794,7 +794,7 @@ fn symbol_from_declarations_impl<'db>(
|
|||
Some(DeclarationWithConstraint {
|
||||
declaration,
|
||||
visibility_constraint,
|
||||
}) if declaration.map_or(true, is_non_exported) => {
|
||||
}) if declaration.is_none_or(is_non_exported) => {
|
||||
visibility_constraints.evaluate(db, predicates, *visibility_constraint)
|
||||
}
|
||||
_ => Truthiness::AlwaysFalse,
|
||||
|
|
|
|||
|
|
@ -502,13 +502,13 @@ impl<'db> Bindings<'db> {
|
|||
if let Some(len_ty) = first_arg.len(db) {
|
||||
overload.set_return_type(len_ty);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
Some(KnownFunction::Repr) => {
|
||||
if let [Some(first_arg)] = overload.parameter_types() {
|
||||
overload.set_return_type(first_arg.repr(db));
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
Some(KnownFunction::Cast) => {
|
||||
|
|
|
|||
|
|
@ -985,7 +985,7 @@ impl<'db> TypeInferenceBuilder<'db> {
|
|||
Some(KnownClass::Float | KnownClass::Int | KnownClass::Bool)
|
||||
) => {}
|
||||
_ => return false,
|
||||
};
|
||||
}
|
||||
|
||||
let (op, by_zero) = match op {
|
||||
ast::Operator::Div => ("divide", "by zero"),
|
||||
|
|
@ -1036,7 +1036,7 @@ impl<'db> TypeInferenceBuilder<'db> {
|
|||
report_invalid_assignment(&self.context, node, declared_ty, bound_ty);
|
||||
// allow declarations to override inference in case of invalid assignment
|
||||
bound_ty = declared_ty;
|
||||
};
|
||||
}
|
||||
|
||||
self.types.bindings.insert(binding, bound_ty);
|
||||
}
|
||||
|
|
@ -2216,7 +2216,7 @@ impl<'db> TypeInferenceBuilder<'db> {
|
|||
}
|
||||
}
|
||||
ast::Pattern::MatchStar(_) | ast::Pattern::MatchSingleton(_) => {}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
fn infer_assignment_statement(&mut self, assignment: &ast::StmtAssign) {
|
||||
|
|
@ -3242,7 +3242,7 @@ impl<'db> TypeInferenceBuilder<'db> {
|
|||
&DeclaredAndInferredType::AreTheSame(ty),
|
||||
);
|
||||
return;
|
||||
};
|
||||
}
|
||||
|
||||
// If the module doesn't bind the symbol, check if it's a submodule. This won't get
|
||||
// handled by the `Type::member` call because it relies on the semantic index's
|
||||
|
|
@ -4044,7 +4044,7 @@ impl<'db> TypeInferenceBuilder<'db> {
|
|||
parameter_ty=parameter_ty.display(self.db())
|
||||
),
|
||||
);
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -4895,7 +4895,7 @@ impl<'db> TypeInferenceBuilder<'db> {
|
|||
|
||||
if done {
|
||||
return Type::Never;
|
||||
};
|
||||
}
|
||||
|
||||
match (truthiness, op) {
|
||||
(Truthiness::AlwaysTrue, ast::BoolOp::And) => Type::Never,
|
||||
|
|
@ -5815,7 +5815,7 @@ impl<'db> TypeInferenceBuilder<'db> {
|
|||
Err(CallDunderError::MethodNotAvailable) => {
|
||||
// try `__class_getitem__`
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// Otherwise, if the value is itself a class and defines `__class_getitem__`,
|
||||
// return its return type.
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ impl SlotsKind {
|
|||
|
||||
if matches!(bound, Boundness::PossiblyUnbound) {
|
||||
return Self::Dynamic;
|
||||
};
|
||||
}
|
||||
|
||||
match slots_ty {
|
||||
// __slots__ = ("a", "b")
|
||||
|
|
@ -98,6 +98,6 @@ pub(super) fn check_class_slots(context: &InferContext, class: Class, node: &ast
|
|||
if let Some(index) = first_with_solid_base {
|
||||
let base_node = &node.bases()[index];
|
||||
report_base_with_incompatible_slots(context, base_node);
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -116,8 +116,10 @@ impl<'db> Unpacker<'db> {
|
|||
// it's worth it.
|
||||
TupleType::from_elements(
|
||||
self.db(),
|
||||
std::iter::repeat(Type::LiteralString)
|
||||
.take(string_literal_ty.python_len(self.db())),
|
||||
std::iter::repeat_n(
|
||||
Type::LiteralString,
|
||||
string_literal_ty.python_len(self.db()),
|
||||
),
|
||||
)
|
||||
}
|
||||
_ => ty,
|
||||
|
|
|
|||
|
|
@ -131,7 +131,7 @@ impl<'a> Iterator for AssertionWithRangeIterator<'a> {
|
|||
let comment = &self.file_assertions.source[inner_next];
|
||||
if let Some(assertion) = UnparsedAssertion::from_comment(comment) {
|
||||
return Some(AssertionWithRange(assertion, inner_next));
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -265,13 +265,13 @@ fn run_test(
|
|||
match info.location {
|
||||
Some(location) => messages.push(format!("panicked at {location}")),
|
||||
None => messages.push("panicked at unknown location".to_string()),
|
||||
};
|
||||
}
|
||||
match info.payload {
|
||||
Some(payload) => messages.push(payload),
|
||||
// Mimic the default panic hook's rendering of the panic payload if it's
|
||||
// not a string.
|
||||
None => messages.push("Box<dyn Any>".to_string()),
|
||||
};
|
||||
}
|
||||
if let Some(backtrace) = info.backtrace {
|
||||
if std::env::var("RUST_BACKTRACE").is_ok() {
|
||||
messages.extend(backtrace.to_string().split('\n').map(String::from));
|
||||
|
|
|
|||
|
|
@ -673,7 +673,7 @@ impl<'s> Parser<'s> {
|
|||
"Test `{test_name}` has duplicate files named `{}`.",
|
||||
path.as_str(),
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
if has_explicit_file_paths {
|
||||
bail!("Merged snippets in test `{test_name}` are not allowed in the presence of other files.");
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
use std::cmp::Ordering;
|
||||
use std::fmt::Formatter;
|
||||
use std::fmt::{Formatter, Write as _};
|
||||
use std::ops::Deref;
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::str::FromStr;
|
||||
|
|
@ -974,12 +974,13 @@ A `--config` flag must either be a path to a `.toml` configuration file
|
|||
.is_some_and(|ext| ext.eq_ignore_ascii_case("toml"))
|
||||
{
|
||||
if !value.contains('=') {
|
||||
tip.push_str(&format!(
|
||||
let _ = write!(
|
||||
&mut tip,
|
||||
"
|
||||
|
||||
It looks like you were trying to pass a path to a configuration file.
|
||||
The path `{value}` does not point to a configuration file"
|
||||
));
|
||||
);
|
||||
}
|
||||
} else if let Some((key, value)) = value.split_once('=') {
|
||||
let key = key.trim_ascii();
|
||||
|
|
@ -993,7 +994,8 @@ The path `{value}` does not point to a configuration file"
|
|||
.map(|(name, _)| format!("- `{key}.{name}`"))
|
||||
.join("\n");
|
||||
|
||||
tip.push_str(&format!(
|
||||
let _ = write!(
|
||||
&mut tip,
|
||||
"
|
||||
|
||||
`{key}` is a table of configuration options.
|
||||
|
|
@ -1002,13 +1004,14 @@ Did you want to override one of the table's subkeys?
|
|||
Possible choices:
|
||||
|
||||
{prefixed_subfields}"
|
||||
));
|
||||
);
|
||||
}
|
||||
_ => {
|
||||
tip.push_str(&format!(
|
||||
let _ = write!(
|
||||
&mut tip,
|
||||
"\n\n{}:\n\n{underlying_error}",
|
||||
config_parse_error.description()
|
||||
));
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
use std::fmt::Write as _;
|
||||
use std::io::{self, BufWriter, Write};
|
||||
|
||||
use anyhow::Result;
|
||||
|
|
@ -43,12 +44,16 @@ impl<'a> Explanation<'a> {
|
|||
|
||||
fn format_rule_text(rule: Rule) -> String {
|
||||
let mut output = String::new();
|
||||
output.push_str(&format!("# {} ({})", rule.as_ref(), rule.noqa_code()));
|
||||
let _ = write!(&mut output, "# {} ({})", rule.as_ref(), rule.noqa_code());
|
||||
output.push('\n');
|
||||
output.push('\n');
|
||||
|
||||
let (linter, _) = Linter::parse_code(&rule.noqa_code().to_string()).unwrap();
|
||||
output.push_str(&format!("Derived from the **{}** linter.", linter.name()));
|
||||
let _ = write!(
|
||||
&mut output,
|
||||
"Derived from the **{}** linter.",
|
||||
linter.name()
|
||||
);
|
||||
output.push('\n');
|
||||
output.push('\n');
|
||||
|
||||
|
|
@ -76,7 +81,7 @@ fn format_rule_text(rule: Rule) -> String {
|
|||
output.push_str("Message formats:");
|
||||
for format in rule.message_formats() {
|
||||
output.push('\n');
|
||||
output.push_str(&format!("* {format}"));
|
||||
let _ = write!(&mut output, "* {format}");
|
||||
}
|
||||
}
|
||||
output
|
||||
|
|
@ -92,7 +97,7 @@ pub(crate) fn rule(rule: Rule, format: HelpFormat) -> Result<()> {
|
|||
HelpFormat::Json => {
|
||||
serde_json::to_writer_pretty(stdout, &Explanation::from_rule(&rule))?;
|
||||
}
|
||||
};
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -16,6 +16,6 @@ pub(crate) fn version(output_format: HelpFormat) -> Result<()> {
|
|||
HelpFormat::Json => {
|
||||
serde_json::to_writer_pretty(stdout, &version_info)?;
|
||||
}
|
||||
};
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ pub fn main() -> ExitCode {
|
|||
|
||||
// support FORCE_COLOR env var
|
||||
if let Some(force_color) = std::env::var_os("FORCE_COLOR") {
|
||||
if force_color.len() > 0 {
|
||||
if !force_color.is_empty() {
|
||||
colored::control::set_override(true);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -315,7 +315,7 @@ impl DisplaySet<'_> {
|
|||
None => {
|
||||
buffer.putc(line_offset, lineno_width + 1, '|', *lineno_color);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
if let DisplaySourceLine::Content { text, .. } = line {
|
||||
// The width of the line number, a space, pipe, and a space
|
||||
|
|
@ -1753,7 +1753,7 @@ fn format_inline_marks(
|
|||
DisplayMarkType::AnnotationThrough(depth) => {
|
||||
buf.putc(line, 3 + lineno_width + depth, '|', *annotation_style);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
#![allow(clippy::print_stdout, clippy::print_stderr)]
|
||||
|
||||
use std::collections::HashSet;
|
||||
use std::fmt::Write as _;
|
||||
use std::fs;
|
||||
use std::path::PathBuf;
|
||||
|
||||
|
|
@ -29,8 +30,7 @@ pub(crate) fn main(args: &Args) -> Result<()> {
|
|||
if let Some(explanation) = rule.explanation() {
|
||||
let mut output = String::new();
|
||||
|
||||
output.push_str(&format!("# {} ({})", rule.as_ref(), rule.noqa_code()));
|
||||
output.push('\n');
|
||||
let _ = writeln!(&mut output, "# {} ({})", rule.as_ref(), rule.noqa_code());
|
||||
|
||||
let (linter, _) = Linter::parse_code(&rule.noqa_code().to_string()).unwrap();
|
||||
if linter.url().is_some() {
|
||||
|
|
@ -49,11 +49,12 @@ pub(crate) fn main(args: &Args) -> Result<()> {
|
|||
common_prefix.to_lowercase()
|
||||
);
|
||||
|
||||
output.push_str(&format!(
|
||||
let _ = write!(
|
||||
output,
|
||||
"Derived from the **[{}](../rules.md#{})** linter.",
|
||||
linter.name(),
|
||||
anchor
|
||||
));
|
||||
anchor,
|
||||
);
|
||||
output.push('\n');
|
||||
output.push('\n');
|
||||
}
|
||||
|
|
@ -155,8 +156,8 @@ fn process_documentation(documentation: &str, out: &mut String, rule_name: &str)
|
|||
}
|
||||
|
||||
let anchor = option.replace('.', "_");
|
||||
out.push_str(&format!("- [`{option}`][{option}]\n"));
|
||||
after.push_str(&format!("[{option}]: ../settings.md#{anchor}\n"));
|
||||
let _ = writeln!(out, "- [`{option}`][{option}]");
|
||||
let _ = writeln!(&mut after, "[{option}]: ../settings.md#{anchor}");
|
||||
referenced_options.insert(option);
|
||||
|
||||
continue;
|
||||
|
|
@ -171,7 +172,7 @@ fn process_documentation(documentation: &str, out: &mut String, rule_name: &str)
|
|||
if let Some(OptionEntry::Field(field)) = Options::metadata().find(option) {
|
||||
if referenced_options.insert(option) {
|
||||
let anchor = option.replace('.', "_");
|
||||
after.push_str(&format!("[{option}]: ../settings.md#{anchor}\n"));
|
||||
let _ = writeln!(&mut after, "[{option}]: ../settings.md#{anchor}");
|
||||
}
|
||||
if field.deprecated.is_some() {
|
||||
eprintln!("Rule {rule_name} references deprecated option {option}.");
|
||||
|
|
|
|||
|
|
@ -98,17 +98,16 @@ fn emit_field(output: &mut String, name: &str, field: &OptionField, parents: &[S
|
|||
let parents_anchor = parents.iter().filter_map(|parent| parent.name()).join("_");
|
||||
|
||||
if parents_anchor.is_empty() {
|
||||
output.push_str(&format!(
|
||||
"{header_level} [`{name}`](#{name}) {{: #{name} }}\n"
|
||||
));
|
||||
let _ = writeln!(output, "{header_level} [`{name}`](#{name}) {{: #{name} }}");
|
||||
} else {
|
||||
output.push_str(&format!(
|
||||
"{header_level} [`{name}`](#{parents_anchor}_{name}) {{: #{parents_anchor}_{name} }}\n"
|
||||
));
|
||||
let _ =
|
||||
writeln!(output,
|
||||
"{header_level} [`{name}`](#{parents_anchor}_{name}) {{: #{parents_anchor}_{name} }}"
|
||||
);
|
||||
|
||||
// the anchor used to just be the name, but now it's the group name
|
||||
// for backwards compatibility, we need to keep the old anchor
|
||||
output.push_str(&format!("<span id=\"{name}\"></span>\n"));
|
||||
let _ = writeln!(output, "<span id=\"{name}\"></span>");
|
||||
}
|
||||
|
||||
output.push('\n');
|
||||
|
|
@ -132,9 +131,9 @@ fn emit_field(output: &mut String, name: &str, field: &OptionField, parents: &[S
|
|||
|
||||
output.push_str(field.doc);
|
||||
output.push_str("\n\n");
|
||||
output.push_str(&format!("**Default value**: `{}`\n", field.default));
|
||||
let _ = writeln!(output, "**Default value**: `{}`", field.default);
|
||||
output.push('\n');
|
||||
output.push_str(&format!("**Type**: `{}`\n", field.value_type));
|
||||
let _ = writeln!(output, "**Type**: `{}`", field.value_type);
|
||||
output.push('\n');
|
||||
output.push_str("**Example usage**:\n\n");
|
||||
output.push_str(&format_tab(
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@
|
|||
use itertools::Itertools;
|
||||
use ruff_linter::codes::RuleGroup;
|
||||
use std::borrow::Cow;
|
||||
use std::fmt::Write;
|
||||
use strum::IntoEnumIterator;
|
||||
|
||||
use ruff_diagnostics::FixAvailability;
|
||||
|
|
@ -78,7 +79,8 @@ fn generate_table(table_out: &mut String, rules: impl IntoIterator<Item = Rule>,
|
|||
}
|
||||
|
||||
#[allow(clippy::or_fun_call)]
|
||||
table_out.push_str(&format!(
|
||||
let _ = write!(
|
||||
table_out,
|
||||
"| {ss}{0}{1}{se} {{ #{0}{1} }} | {ss}{2}{se} | {ss}{3}{se} | {ss}{4}{se} |",
|
||||
linter.common_prefix(),
|
||||
linter.code_for_rule(rule).unwrap(),
|
||||
|
|
@ -88,7 +90,7 @@ fn generate_table(table_out: &mut String, rules: impl IntoIterator<Item = Rule>,
|
|||
.unwrap_or(format_args!("{rule_name}")),
|
||||
message,
|
||||
tokens,
|
||||
));
|
||||
);
|
||||
table_out.push('\n');
|
||||
}
|
||||
table_out.push('\n');
|
||||
|
|
@ -101,29 +103,30 @@ pub(crate) fn generate() -> String {
|
|||
table_out.push_str("### Legend");
|
||||
table_out.push('\n');
|
||||
|
||||
table_out.push_str(&format!(
|
||||
let _ = write!(
|
||||
&mut table_out,
|
||||
"{SPACER}{STABLE_SYMBOL}{SPACER} The rule is stable."
|
||||
));
|
||||
);
|
||||
table_out.push_str("<br />");
|
||||
|
||||
table_out.push_str(&format!(
|
||||
let _ = write!(&mut table_out,
|
||||
"{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(&format!(
|
||||
let _ = write!(&mut table_out,
|
||||
"{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(&format!(
|
||||
let _ = write!(&mut table_out,
|
||||
"{SPACER}{REMOVED_SYMBOL}{SPACER} The rule has been removed only the documentation is available."
|
||||
));
|
||||
);
|
||||
table_out.push_str("<br />");
|
||||
|
||||
table_out.push_str(&format!(
|
||||
let _ = write!(&mut table_out,
|
||||
"{SPACER}{FIX_SYMBOL}{SPACER} The rule is automatically fixable by the `--fix` command-line option."
|
||||
));
|
||||
);
|
||||
table_out.push_str("<br />");
|
||||
table_out.push('\n');
|
||||
|
||||
|
|
@ -137,7 +140,7 @@ pub(crate) fn generate() -> String {
|
|||
.join(", "),
|
||||
prefix => prefix.to_string(),
|
||||
};
|
||||
table_out.push_str(&format!("### {} ({codes_csv})", linter.name()));
|
||||
let _ = write!(&mut table_out, "### {} ({codes_csv})", linter.name());
|
||||
table_out.push('\n');
|
||||
table_out.push('\n');
|
||||
|
||||
|
|
@ -147,7 +150,8 @@ pub(crate) fn generate() -> String {
|
|||
.split('/')
|
||||
.next()
|
||||
.unwrap();
|
||||
table_out.push_str(&format!(
|
||||
let _ = write!(
|
||||
table_out,
|
||||
"For more, see [{}]({}) on {}.",
|
||||
linter.name(),
|
||||
url,
|
||||
|
|
@ -160,17 +164,18 @@ pub(crate) fn generate() -> String {
|
|||
linter.name()
|
||||
),
|
||||
}
|
||||
));
|
||||
);
|
||||
table_out.push('\n');
|
||||
table_out.push('\n');
|
||||
}
|
||||
|
||||
if Options::metadata().has(&format!("lint.{}", linter.name())) {
|
||||
table_out.push_str(&format!(
|
||||
let _ = write!(
|
||||
table_out,
|
||||
"For related settings, see [{}](settings.md#lint{}).",
|
||||
linter.name(),
|
||||
linter.name(),
|
||||
));
|
||||
);
|
||||
table_out.push('\n');
|
||||
table_out.push('\n');
|
||||
}
|
||||
|
|
@ -200,10 +205,10 @@ pub(crate) fn generate() -> String {
|
|||
let UpstreamCategoryAndPrefix { category, prefix } = opt.unwrap();
|
||||
match codes_csv.as_str() {
|
||||
"PL" => {
|
||||
table_out.push_str(&format!("#### {category} ({codes_csv}{prefix})"));
|
||||
let _ = write!(table_out, "#### {category} ({codes_csv}{prefix})");
|
||||
}
|
||||
_ => {
|
||||
table_out.push_str(&format!("#### {category} ({prefix})"));
|
||||
let _ = write!(table_out, "#### {category} ({prefix})");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -610,7 +610,7 @@ impl Format<IrFormatContext<'_>> for &[FormatElement] {
|
|||
}
|
||||
}
|
||||
|
||||
StartEntry | StartBestFittingEntry { .. } => {
|
||||
StartEntry | StartBestFittingEntry => {
|
||||
// handled after the match for all start tags
|
||||
}
|
||||
EndEntry | EndBestFittingEntry => write!(f, [ContentArrayEnd])?,
|
||||
|
|
@ -630,7 +630,7 @@ impl Format<IrFormatContext<'_>> for &[FormatElement] {
|
|||
| EndVerbatim => {
|
||||
write!(f, [ContentArrayEnd, token(")")])?;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
if tag.is_start() {
|
||||
write!(f, [ContentArrayStart])?;
|
||||
|
|
|
|||
|
|
@ -144,7 +144,7 @@ impl Tag {
|
|||
StartVerbatim(_) | EndVerbatim => TagKind::Verbatim,
|
||||
StartLabelled(_) | EndLabelled => TagKind::Labelled,
|
||||
StartFitsExpanded { .. } | EndFitsExpanded => TagKind::FitsExpanded,
|
||||
StartBestFittingEntry { .. } | EndBestFittingEntry => TagKind::BestFittingEntry,
|
||||
StartBestFittingEntry | EndBestFittingEntry => TagKind::BestFittingEntry,
|
||||
StartBestFitParenthesize { .. } | EndBestFitParenthesize => {
|
||||
TagKind::BestFitParenthesize
|
||||
}
|
||||
|
|
|
|||
|
|
@ -362,9 +362,7 @@ impl<'a> Printer<'a> {
|
|||
stack.push(TagKind::FitsExpanded, args);
|
||||
}
|
||||
|
||||
FormatElement::Tag(
|
||||
tag @ (StartLabelled(_) | StartEntry | StartBestFittingEntry { .. }),
|
||||
) => {
|
||||
FormatElement::Tag(tag @ (StartLabelled(_) | StartEntry | StartBestFittingEntry)) => {
|
||||
stack.push(tag.kind(), args);
|
||||
}
|
||||
|
||||
|
|
@ -386,7 +384,7 @@ impl<'a> Printer<'a> {
|
|||
) => {
|
||||
stack.pop(tag.kind())?;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
|
@ -1416,7 +1414,7 @@ impl<'a, 'print> FitsMeasurer<'a, 'print> {
|
|||
| StartVerbatim(_)
|
||||
| StartLabelled(_)
|
||||
| StartEntry
|
||||
| StartBestFittingEntry { .. }),
|
||||
| StartBestFittingEntry),
|
||||
) => {
|
||||
self.stack.push(tag.kind(), args);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1749,5 +1749,5 @@ pub(crate) fn expression(expr: &Expr, checker: &Checker) {
|
|||
}
|
||||
}
|
||||
_ => {}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -645,7 +645,7 @@ pub(crate) fn statement(stmt: &Stmt, checker: &mut Checker) {
|
|||
}
|
||||
}
|
||||
if let Some(asname) = &alias.asname {
|
||||
let name = alias.name.split('.').last().unwrap();
|
||||
let name = alias.name.split('.').next_back().unwrap();
|
||||
if checker.enabled(Rule::ConstantImportedAsNonConstant) {
|
||||
if let Some(diagnostic) =
|
||||
pep8_naming::rules::constant_imported_as_non_constant(
|
||||
|
|
|
|||
|
|
@ -1164,7 +1164,7 @@ impl<'a> Visitor<'a> for Checker<'a> {
|
|||
}
|
||||
}
|
||||
_ => visitor::walk_stmt(self, stmt),
|
||||
};
|
||||
}
|
||||
|
||||
if self.semantic().at_top_level() || self.semantic().current_scope().kind.is_class() {
|
||||
match stmt {
|
||||
|
|
@ -1726,7 +1726,7 @@ impl<'a> Visitor<'a> for Checker<'a> {
|
|||
self.semantic.pop_scope();
|
||||
}
|
||||
_ => {}
|
||||
};
|
||||
}
|
||||
|
||||
// Step 4: Analysis
|
||||
match expr {
|
||||
|
|
|
|||
|
|
@ -320,7 +320,7 @@ impl<'a> TodoDirective<'a> {
|
|||
subset = &comment[relative_offset.to_usize()..];
|
||||
} else {
|
||||
break;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
None
|
||||
|
|
|
|||
|
|
@ -288,7 +288,7 @@ pub(crate) fn add_parameter(parameter: &str, parameters: &Parameters, source: &s
|
|||
.args
|
||||
.iter()
|
||||
.filter(|arg| arg.default.is_none())
|
||||
.last()
|
||||
.next_back()
|
||||
{
|
||||
// Case 1: at least one regular parameter, so append after the last one.
|
||||
Edit::insertion(format!(", {parameter}"), last.end())
|
||||
|
|
|
|||
|
|
@ -162,7 +162,7 @@ impl Display for RuleCodeAndBody<'_> {
|
|||
);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
if let Some(rule) = self.message.rule() {
|
||||
write!(
|
||||
|
|
|
|||
|
|
@ -291,7 +291,7 @@ impl<'a> FileNoqaDirectives<'a> {
|
|||
warn!("Invalid `# ruff: noqa` directive at {path_display}:{line}: {err}");
|
||||
}
|
||||
Ok(None) => {}
|
||||
};
|
||||
}
|
||||
}
|
||||
Self(lines)
|
||||
}
|
||||
|
|
@ -990,7 +990,7 @@ fn generate_noqa_edit<'a>(
|
|||
codes = Some(existing_codes);
|
||||
}
|
||||
Some(Directive::All(_)) => return None,
|
||||
};
|
||||
}
|
||||
|
||||
Some(NoqaEdit {
|
||||
edit_range,
|
||||
|
|
|
|||
|
|
@ -216,8 +216,7 @@ impl RuleSelector {
|
|||
}
|
||||
// Deprecated rules are excluded in preview mode and with 'All' option unless explicitly selected
|
||||
RuleGroup::Deprecated => {
|
||||
(!preview_enabled || self.is_exact())
|
||||
&& !matches!(self, RuleSelector::All { .. })
|
||||
(!preview_enabled || self.is_exact()) && !matches!(self, RuleSelector::All)
|
||||
}
|
||||
// Removed rules are included if explicitly selected but will error downstream
|
||||
RuleGroup::Removed => self.is_exact(),
|
||||
|
|
|
|||
|
|
@ -91,7 +91,7 @@ pub(crate) fn airflow_3_removal_expr(checker: &Checker, expr: &Expr) {
|
|||
) => {
|
||||
if let Some(qualified_name) = checker.semantic().resolve_qualified_name(func) {
|
||||
check_call_arguments(checker, &qualified_name, arguments);
|
||||
};
|
||||
}
|
||||
check_method(checker, call_expr);
|
||||
check_context_key_usage_in_call(checker, call_expr);
|
||||
}
|
||||
|
|
@ -256,7 +256,7 @@ fn check_call_arguments(checker: &Checker, qualified_name: &QualifiedName, argum
|
|||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/// Check whether a removed Airflow class attribute (include property) is called.
|
||||
|
|
@ -930,7 +930,7 @@ fn check_name(checker: &Checker, expr: &Expr, range: TextRange) {
|
|||
let replacement_edit = Edit::range_replacement(binding, range);
|
||||
Ok(Fix::safe_edits(import_edit, [replacement_edit]))
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
checker.report_diagnostic(diagnostic);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -72,7 +72,7 @@ pub(crate) fn cancel_scope_no_checkpoint(
|
|||
None
|
||||
}
|
||||
})
|
||||
.last()
|
||||
.next_back()
|
||||
else {
|
||||
return;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -78,7 +78,7 @@ pub(crate) fn sync_call(checker: &Checker, call: &ExprCall) {
|
|||
.is_some_and(Expr::is_await_expr)
|
||||
{
|
||||
return;
|
||||
};
|
||||
}
|
||||
|
||||
let mut diagnostic = Diagnostic::new(TrioSyncCall { method_name }, call.range);
|
||||
if checker.semantic().in_async_context() {
|
||||
|
|
|
|||
|
|
@ -70,5 +70,5 @@ pub(crate) fn hardcoded_bind_all_interfaces(checker: &Checker, string: StringLik
|
|||
}
|
||||
}
|
||||
StringLike::Bytes(_) => (),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -599,7 +599,7 @@ pub(crate) fn suspicious_imports(checker: &Checker, stmt: &Stmt) {
|
|||
}
|
||||
}
|
||||
_ => panic!("Expected Stmt::Import | Stmt::ImportFrom"),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
fn check_and_push_diagnostic(checker: &Checker, diagnostic_kind: DiagnosticKind, range: TextRange) {
|
||||
|
|
|
|||
|
|
@ -97,7 +97,7 @@ pub(crate) fn assert_raises_exception(checker: &Checker, items: &[WithItem]) {
|
|||
&& arguments.find_keyword("match").is_none())
|
||||
{
|
||||
continue;
|
||||
};
|
||||
}
|
||||
|
||||
checker.report_diagnostic(Diagnostic::new(
|
||||
AssertRaisesException { exception },
|
||||
|
|
|
|||
|
|
@ -74,7 +74,7 @@ pub(crate) fn duplicate_value(checker: &Checker, set: &ast::ExprSet) {
|
|||
|
||||
checker.report_diagnostic(diagnostic);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
use std::fmt::Write;
|
||||
|
||||
use ruff_diagnostics::{Diagnostic, Edit, Fix, FixAvailability, Violation};
|
||||
use ruff_macros::{derive_message_formats, ViolationMetadata};
|
||||
use ruff_python_ast::helpers::is_docstring_stmt;
|
||||
|
|
@ -160,14 +162,15 @@ fn move_initialization(
|
|||
|
||||
// Add an `if`, to set the argument to its original value if still `None`.
|
||||
let mut content = String::new();
|
||||
content.push_str(&format!("if {} is None:", parameter.name()));
|
||||
let _ = write!(&mut content, "if {} is None:", parameter.name());
|
||||
content.push_str(stylist.line_ending().as_str());
|
||||
content.push_str(stylist.indentation());
|
||||
content.push_str(&format!(
|
||||
let _ = write!(
|
||||
&mut content,
|
||||
"{} = {}",
|
||||
parameter.name(),
|
||||
generator.expr(default)
|
||||
));
|
||||
);
|
||||
content.push_str(stylist.line_ending().as_str());
|
||||
|
||||
// Determine the indentation depth of the function body.
|
||||
|
|
@ -204,7 +207,7 @@ fn move_initialization(
|
|||
}
|
||||
} else {
|
||||
break;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
let initialization_edit = Edit::insertion(content, pos);
|
||||
|
|
|
|||
|
|
@ -61,5 +61,5 @@ pub(crate) fn unintentional_type_annotation(
|
|||
}
|
||||
}
|
||||
_ => {}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -426,7 +426,7 @@ pub(crate) fn fix_unnecessary_call_around_sorted(
|
|||
tree = Expression::Call(Box::new((*inner_call).clone()));
|
||||
if inner_needs_parens {
|
||||
tree = tree.with_parens(LeftParen::default(), RightParen::default());
|
||||
};
|
||||
}
|
||||
} else {
|
||||
// If the `reverse` argument is used...
|
||||
let args = if inner_call.args.iter().any(|arg| {
|
||||
|
|
|
|||
|
|
@ -79,7 +79,7 @@ pub(crate) fn unnecessary_subscript_reversal(checker: &Checker, call: &ast::Expr
|
|||
};
|
||||
if *val != 1 {
|
||||
return;
|
||||
};
|
||||
}
|
||||
let Some(function_name) = checker.semantic().resolve_builtin_symbol(&call.func) else {
|
||||
return;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -132,7 +132,7 @@ pub(crate) fn call_datetime_strptime_without_zone(checker: &Checker, call: &ast:
|
|||
}
|
||||
_ => {}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
let semantic = checker.semantic();
|
||||
if let Some(antipattern) = find_antipattern(
|
||||
|
|
|
|||
|
|
@ -95,7 +95,7 @@ pub(crate) fn all_with_model_form(checker: &Checker, class_def: &ast::StmtClassD
|
|||
}
|
||||
}
|
||||
_ => (),
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -54,7 +54,7 @@ impl Violation for PrintfInGetTextFuncCall {
|
|||
pub(crate) fn printf_in_gettext_func_call(checker: &Checker, args: &[Expr]) {
|
||||
if let Some(first) = args.first() {
|
||||
if let Expr::BinOp(ast::ExprBinOp {
|
||||
op: Operator::Mod { .. },
|
||||
op: Operator::Mod,
|
||||
left,
|
||||
..
|
||||
}) = &first
|
||||
|
|
|
|||
|
|
@ -160,7 +160,7 @@ pub(crate) fn implicit(
|
|||
}
|
||||
|
||||
diagnostics.push(diagnostic);
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -63,12 +63,12 @@ pub(crate) fn unnecessary_range_start(checker: &Checker, call: &ast::ExprCall) {
|
|||
};
|
||||
if *value != 0 {
|
||||
return;
|
||||
};
|
||||
}
|
||||
|
||||
// Verify that the call is to the `range` builtin.
|
||||
if !checker.semantic().match_builtin_expr(&call.func, "range") {
|
||||
return;
|
||||
};
|
||||
}
|
||||
|
||||
let mut diagnostic = Diagnostic::new(UnnecessaryRangeStart, start.range());
|
||||
diagnostic.try_set_fix(|| {
|
||||
|
|
|
|||
|
|
@ -209,7 +209,7 @@ pub(crate) fn bad_generator_return_type(function_def: &ast::StmtFunctionDef, che
|
|||
_ => return,
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
let mut diagnostic = Diagnostic::new(
|
||||
GeneratorReturnFromIterMethod {
|
||||
return_type: member.to_iter(),
|
||||
|
|
|
|||
|
|
@ -149,6 +149,6 @@ pub(crate) fn bad_version_info_comparison(checker: &Checker, test: &Expr, has_el
|
|||
} else {
|
||||
if checker.enabled(Rule::BadVersionInfoComparison) {
|
||||
checker.report_diagnostic(Diagnostic::new(BadVersionInfoComparison, test.range()));
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -107,7 +107,7 @@ pub(crate) fn duplicate_literal_member<'a>(checker: &Checker, expr: &'a Expr) {
|
|||
for diagnostic in &mut diagnostics {
|
||||
diagnostic.set_fix(fix.clone());
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
checker.report_diagnostics(diagnostics);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -47,7 +47,7 @@ pub(crate) fn from_future_import(checker: &Checker, target: &StmtImportFrom) {
|
|||
|
||||
if module_name != "__future__" {
|
||||
return;
|
||||
};
|
||||
}
|
||||
|
||||
if names.iter().all(|alias| &*alias.name != "annotations") {
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -73,7 +73,7 @@ pub(crate) fn prefix_type_params(checker: &Checker, value: &Expr, targets: &[Exp
|
|||
if id.starts_with('_') {
|
||||
return;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
let Expr::Call(ast::ExprCall { func, .. }) = value else {
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -646,7 +646,7 @@ impl<'a> Visitor<'a> for SkipFunctionsVisitor<'a> {
|
|||
.is_some_and(|name| matches!(name.segments(), ["request", "addfinalizer"]))
|
||||
{
|
||||
self.addfinalizer_call = Some(expr);
|
||||
};
|
||||
}
|
||||
visitor::walk_expr(self, expr);
|
||||
}
|
||||
_ => {}
|
||||
|
|
|
|||
|
|
@ -59,7 +59,7 @@ pub(crate) fn import_from(
|
|||
// If level is not zero or module is none, return
|
||||
if level != 0 {
|
||||
return None;
|
||||
};
|
||||
}
|
||||
|
||||
if let Some(module) = module {
|
||||
if is_pytest_or_subpackage(module) {
|
||||
|
|
@ -68,7 +68,7 @@ pub(crate) fn import_from(
|
|||
import_from.range(),
|
||||
));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
None
|
||||
}
|
||||
|
|
|
|||
|
|
@ -458,7 +458,7 @@ fn check_names(checker: &Checker, call: &ExprCall, expr: &Expr, argvalues: &Expr
|
|||
checker.report_diagnostic(diagnostic);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
Expr::List(ast::ExprList { elts, .. }) => {
|
||||
if elts.len() == 1 {
|
||||
|
|
@ -505,7 +505,7 @@ fn check_names(checker: &Checker, call: &ExprCall, expr: &Expr, argvalues: &Expr
|
|||
checker.report_diagnostic(diagnostic);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -195,7 +195,7 @@ pub(crate) fn if_expr_with_true_false(
|
|||
),
|
||||
expr.range(),
|
||||
)));
|
||||
};
|
||||
}
|
||||
checker.report_diagnostic(diagnostic);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -295,6 +295,6 @@ pub(crate) fn double_negation(checker: &Checker, expr: &Expr, op: UnaryOp, opera
|
|||
checker.generator().expr(&node1.into()),
|
||||
expr.range(),
|
||||
)));
|
||||
};
|
||||
}
|
||||
checker.report_diagnostic(diagnostic);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -114,7 +114,7 @@ pub(crate) fn if_else_block_instead_of_dict_lookup(checker: &Checker, stmt_if: &
|
|||
contains_effect(value, |id| checker.semantic().has_builtin_binding(id))
|
||||
}) {
|
||||
return;
|
||||
};
|
||||
}
|
||||
}
|
||||
// `elif`
|
||||
Some(Expr::Compare(ast::ExprCompare {
|
||||
|
|
@ -140,7 +140,7 @@ pub(crate) fn if_else_block_instead_of_dict_lookup(checker: &Checker, stmt_if: &
|
|||
contains_effect(value, |id| checker.semantic().has_builtin_binding(id))
|
||||
}) {
|
||||
return;
|
||||
};
|
||||
}
|
||||
|
||||
// The `expr` was checked to be a literal above, so this is safe.
|
||||
literals.insert(literal_expr.into());
|
||||
|
|
|
|||
|
|
@ -71,7 +71,7 @@ pub(crate) fn zip_dict_keys_and_values(checker: &Checker, expr: &ast::ExprCall)
|
|||
arg: Some(name), ..
|
||||
}] if name.as_str() == "strict" => {}
|
||||
_ => return,
|
||||
};
|
||||
}
|
||||
let [arg1, arg2] = &args[..] else {
|
||||
return;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -128,7 +128,7 @@ pub(crate) fn banned_relative_import(
|
|||
fix_banned_relative_import(stmt, level, module, module_path, checker.generator())
|
||||
{
|
||||
diagnostic.set_fix(fix);
|
||||
};
|
||||
}
|
||||
Some(diagnostic)
|
||||
} else {
|
||||
None
|
||||
|
|
|
|||
|
|
@ -216,7 +216,7 @@ pub(crate) fn is_singledispatch_implementation(
|
|||
|
||||
if attribute.attr.as_str() != "register" {
|
||||
return false;
|
||||
};
|
||||
}
|
||||
|
||||
let Some(id) = semantic.lookup_attribute(attribute.value.as_ref()) else {
|
||||
return false;
|
||||
|
|
|
|||
|
|
@ -74,7 +74,7 @@ pub(crate) fn os_sep_split(checker: &Checker, call: &ast::ExprCall) {
|
|||
|
||||
if attr.as_str() != "split" {
|
||||
return;
|
||||
};
|
||||
}
|
||||
|
||||
// Match `.split(os.sep)` or `.split(sep=os.sep)`, but avoid cases in which a `maxsplit` is
|
||||
// specified.
|
||||
|
|
|
|||
|
|
@ -110,7 +110,7 @@ pub(crate) fn path_constructor_current_directory(checker: &Checker, call: &ExprC
|
|||
let edit = remove_argument(arg, arguments, Parentheses::Preserve, checker.source())?;
|
||||
Ok(Fix::applicable_edit(edit, applicability(call.range())))
|
||||
}),
|
||||
};
|
||||
}
|
||||
|
||||
checker.report_diagnostic(diagnostic);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -178,7 +178,7 @@ fn is_file_descriptor(expr: &Expr, semantic: &SemanticModel) -> bool {
|
|||
})
|
||||
) {
|
||||
return true;
|
||||
};
|
||||
}
|
||||
|
||||
let Some(name) = expr.as_name_expr() else {
|
||||
return false;
|
||||
|
|
|
|||
|
|
@ -706,7 +706,7 @@ pub(crate) fn numpy_2_0_deprecation(checker: &Checker, expr: &Expr) {
|
|||
Edit::range_replacement(python_expr.to_string(), expr.range()),
|
||||
)),
|
||||
Details::Manual { guideline: _ } => {}
|
||||
};
|
||||
}
|
||||
checker.report_diagnostic(diagnostic);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -307,7 +307,7 @@ pub(crate) fn compound_statements(
|
|||
match_ = Some(token.range());
|
||||
}
|
||||
_ => {}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -175,7 +175,7 @@ pub(crate) fn missing_whitespace_around_operator(
|
|||
TokenKind::Lpar | TokenKind::Lambda => parens += 1,
|
||||
TokenKind::Rpar => parens = parens.saturating_sub(1),
|
||||
_ => {}
|
||||
};
|
||||
}
|
||||
|
||||
let needs_space = if kind == TokenKind::Equal
|
||||
&& (parens > 0 || fstrings > 0 || definition_state.in_type_params())
|
||||
|
|
|
|||
|
|
@ -68,7 +68,7 @@ pub(crate) fn too_many_newlines_at_end_of_file(
|
|||
diagnostics.extend(notebook_newline_diagnostics(tokens_iter, cell_offsets));
|
||||
} else if let Some(diagnostic) = newline_diagnostic(&mut tokens_iter, false) {
|
||||
diagnostics.push(diagnostic);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/// Collects trailing newline diagnostics for each cell
|
||||
|
|
@ -127,7 +127,7 @@ fn newline_diagnostic<'a>(
|
|||
|
||||
if num_trailing_newlines == 0 || num_trailing_newlines == 1 {
|
||||
return None;
|
||||
};
|
||||
}
|
||||
|
||||
let (start, end) = (match (newline_range_start, newline_range_end) {
|
||||
(Some(s), Some(e)) => Some((s, e)),
|
||||
|
|
|
|||
|
|
@ -119,7 +119,7 @@ pub(crate) fn get_section_contexts<'a>(
|
|||
Ordering::Greater => return google_sections,
|
||||
Ordering::Less => return numpy_sections,
|
||||
Ordering::Equal => {}
|
||||
};
|
||||
}
|
||||
|
||||
// 0 sections of either convention? Default to numpy
|
||||
if google_sections.len() == 0 {
|
||||
|
|
|
|||
|
|
@ -115,6 +115,6 @@ pub(crate) fn ends_with_period(checker: &Checker, docstring: &Docstring) {
|
|||
)));
|
||||
}
|
||||
checker.report_diagnostic(diagnostic);
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -114,6 +114,6 @@ pub(crate) fn ends_with_punctuation(checker: &Checker, docstring: &Docstring) {
|
|||
)));
|
||||
}
|
||||
checker.report_diagnostic(diagnostic);
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -146,7 +146,7 @@ pub(crate) fn multi_line_summary_start(checker: &Checker, docstring: &Docstring)
|
|||
.is_none()
|
||||
{
|
||||
return;
|
||||
};
|
||||
}
|
||||
let mut content_lines =
|
||||
UniversalNewlineIterator::with_offset(docstring.contents(), docstring.start());
|
||||
|
||||
|
|
@ -201,7 +201,7 @@ pub(crate) fn multi_line_summary_start(checker: &Checker, docstring: &Docstring)
|
|||
indentation.push_str(checker.stylist().indentation());
|
||||
fixable = true;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
if fixable {
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@ impl From<&CFormatString> for CFormatSummary {
|
|||
None => {
|
||||
num_positional += 1;
|
||||
}
|
||||
};
|
||||
}
|
||||
if min_field_width == &Some(CFormatQuantity::FromValuesTuple) {
|
||||
num_positional += 1;
|
||||
starred = true;
|
||||
|
|
|
|||
|
|
@ -55,7 +55,7 @@ impl TryFrom<&str> for FormatSummary {
|
|||
FieldType::Auto => autos.push(autos.len()),
|
||||
FieldType::Index(i) => indices.push(i),
|
||||
FieldType::Keyword(k) => keywords.push(Name::from(k)),
|
||||
};
|
||||
}
|
||||
|
||||
let nested = FormatString::from_str(format_spec)?;
|
||||
for nested_part in nested.format_parts {
|
||||
|
|
@ -67,7 +67,7 @@ impl TryFrom<&str> for FormatSummary {
|
|||
FieldType::Auto => autos.push(autos.len()),
|
||||
FieldType::Index(i) => indices.push(i),
|
||||
FieldType::Keyword(k) => keywords.push(Name::from(k)),
|
||||
};
|
||||
}
|
||||
has_nested_parts = true;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -80,7 +80,7 @@ pub(crate) fn bad_staticmethod_argument(checker: &Checker, scope: &Scope) {
|
|||
FunctionType::Function | FunctionType::Method | FunctionType::ClassMethod => {
|
||||
return;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
let Some(ParameterWithDefault {
|
||||
parameter: self_or_cls,
|
||||
|
|
|
|||
|
|
@ -108,6 +108,6 @@ pub(crate) fn percent(checker: &Checker, expr: &Expr, format_string: &ExprString
|
|||
expr.range(),
|
||||
));
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -230,7 +230,7 @@ pub(crate) fn bad_string_format_type(
|
|||
// Parse the format string (e.g. `"%s"`) into a list of `PercentFormat`.
|
||||
if let Ok(format_string) = CFormatString::from_str(string) {
|
||||
format_strings.push(format_string);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
// Parse the parameters.
|
||||
|
|
|
|||
|
|
@ -72,6 +72,6 @@ pub(crate) fn comparison_of_constant(
|
|||
);
|
||||
|
||||
checker.report_diagnostic(diagnostic);
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -72,7 +72,7 @@ pub(crate) fn dict_iter_missing_items(checker: &Checker, target: &Expr, iter: &E
|
|||
|
||||
if tuple.len() != 2 {
|
||||
return;
|
||||
};
|
||||
}
|
||||
|
||||
let Expr::Name(name) = iter else {
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -105,7 +105,7 @@ pub(crate) fn logging_call(checker: &Checker, call: &ast::ExprCall) {
|
|||
Expr::Attribute(ast::ExprAttribute { attr, .. }) => {
|
||||
if LoggingLevel::from_attribute(attr).is_none() {
|
||||
return;
|
||||
};
|
||||
}
|
||||
if !logging::is_logger_candidate(
|
||||
&call.func,
|
||||
checker.semantic(),
|
||||
|
|
@ -126,10 +126,10 @@ pub(crate) fn logging_call(checker: &Checker, call: &ast::ExprCall) {
|
|||
};
|
||||
if LoggingLevel::from_attribute(attribute).is_none() {
|
||||
return;
|
||||
};
|
||||
}
|
||||
}
|
||||
_ => return,
|
||||
};
|
||||
}
|
||||
|
||||
let Some(Expr::StringLiteral(ast::ExprStringLiteral { value, .. })) =
|
||||
call.arguments.find_positional(0)
|
||||
|
|
|
|||
|
|
@ -135,16 +135,16 @@ fn get_undecorated_methods(checker: &Checker, class_stmt: &Stmt, method_type: &M
|
|||
if target_name == *id {
|
||||
explicit_decorator_calls.insert(id.clone(), stmt);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if explicit_decorator_calls.is_empty() {
|
||||
return;
|
||||
};
|
||||
}
|
||||
|
||||
for stmt in &class_def.body {
|
||||
if let Stmt::FunctionDef(ast::StmtFunctionDef {
|
||||
|
|
@ -196,7 +196,7 @@ fn get_undecorated_methods(checker: &Checker, class_stmt: &Stmt, method_type: &M
|
|||
None => {
|
||||
continue;
|
||||
}
|
||||
};
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -103,8 +103,8 @@ pub(crate) fn self_or_cls_assignment(checker: &Checker, target: &Expr) {
|
|||
);
|
||||
|
||||
let method_type = match (function_type, self_or_cls.name().as_str()) {
|
||||
(FunctionType::Method { .. }, "self") => MethodType::Instance,
|
||||
(FunctionType::ClassMethod { .. }, "cls") => MethodType::Class,
|
||||
(FunctionType::Method, "self") => MethodType::Instance,
|
||||
(FunctionType::ClassMethod, "cls") => MethodType::Class,
|
||||
(FunctionType::NewMethod, "cls") => MethodType::New,
|
||||
_ => return,
|
||||
};
|
||||
|
|
|
|||
|
|
@ -101,9 +101,9 @@ pub(crate) fn super_without_brackets(checker: &Checker, func: &Expr) {
|
|||
);
|
||||
if !matches!(
|
||||
classification,
|
||||
function_type::FunctionType::Method { .. }
|
||||
| function_type::FunctionType::ClassMethod { .. }
|
||||
| function_type::FunctionType::StaticMethod { .. }
|
||||
function_type::FunctionType::Method
|
||||
| function_type::FunctionType::ClassMethod
|
||||
| function_type::FunctionType::StaticMethod
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -79,7 +79,7 @@ pub(crate) fn sys_exit_alias(checker: &Checker, call: &ExprCall) {
|
|||
if call.arguments.len() > 1 || has_star_kwargs {
|
||||
checker.report_diagnostic(diagnostic);
|
||||
return;
|
||||
};
|
||||
}
|
||||
|
||||
diagnostic.try_set_fix(|| {
|
||||
let (import_edit, binding) = checker.importer().get_or_import_symbol(
|
||||
|
|
@ -94,7 +94,7 @@ pub(crate) fn sys_exit_alias(checker: &Checker, call: &ExprCall) {
|
|||
checker.source()[kwarg.value.range()].to_string(),
|
||||
kwarg.range,
|
||||
));
|
||||
};
|
||||
}
|
||||
Ok(Fix::unsafe_edits(import_edit, edits))
|
||||
});
|
||||
checker.report_diagnostic(diagnostic);
|
||||
|
|
|
|||
|
|
@ -54,6 +54,6 @@ pub(crate) fn too_many_locals(checker: &Checker, scope: &Scope) {
|
|||
},
|
||||
func.identifier(),
|
||||
));
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -208,7 +208,7 @@ pub(crate) fn unnecessary_dunder_call(checker: &Checker, call: &ast::ExprCall) {
|
|||
fixed,
|
||||
call.range(),
|
||||
)));
|
||||
};
|
||||
}
|
||||
|
||||
checker.report_diagnostic(diagnostic);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -85,7 +85,7 @@ pub(crate) fn useless_return(
|
|||
.is_none_or(|expr| expr.is_none_literal_expr())
|
||||
{
|
||||
return;
|
||||
};
|
||||
}
|
||||
|
||||
// Finally: verify that there are no _other_ return statements in the function.
|
||||
let mut visitor = ReturnStatementVisitor::default();
|
||||
|
|
|
|||
|
|
@ -527,6 +527,6 @@ pub(crate) fn f_strings(checker: &Checker, call: &ast::ExprCall, summary: &Forma
|
|||
call.range(),
|
||||
)));
|
||||
}
|
||||
};
|
||||
}
|
||||
checker.report_diagnostic(diagnostic);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
use std::borrow::Cow;
|
||||
use std::fmt::Write;
|
||||
use std::str::FromStr;
|
||||
|
||||
use ruff_diagnostics::{Diagnostic, Edit, Fix, FixAvailability, Violation};
|
||||
|
|
@ -501,7 +502,7 @@ pub(crate) fn printf_string_formatting(
|
|||
}
|
||||
|
||||
// Add the `.format` call.
|
||||
contents.push_str(&format!(".format{params_string}"));
|
||||
let _ = write!(&mut contents, ".format{params_string}");
|
||||
|
||||
let mut diagnostic = Diagnostic::new(PrintfStringFormatting, bin_op.range());
|
||||
diagnostic.set_fix(Fix::unsafe_edit(Edit::range_replacement(
|
||||
|
|
|
|||
|
|
@ -124,7 +124,7 @@ pub(crate) fn replace_str_enum(checker: &Checker, class_def: &ast::StmtClassDef)
|
|||
// If the class does not inherit both `str` and `enum.Enum`, exit early.
|
||||
if !inherits_str || !inherits_enum {
|
||||
return;
|
||||
};
|
||||
}
|
||||
|
||||
let mut diagnostic = Diagnostic::new(
|
||||
ReplaceStrEnum {
|
||||
|
|
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
use std::fmt::Write as _;
|
||||
|
||||
use ruff_diagnostics::{AlwaysFixableViolation, Diagnostic, Edit, Fix};
|
||||
use ruff_macros::{derive_message_formats, ViolationMetadata};
|
||||
use ruff_python_ast::{self as ast, Arguments, Expr, Keyword};
|
||||
|
|
@ -129,10 +131,11 @@ fn replace_with_bytes_literal(locator: &Locator, call: &ast::ExprCall, tokens: &
|
|||
TokenKind::String => {
|
||||
replacement.push_str(locator.slice(TextRange::new(prev, token.start())));
|
||||
let string = locator.slice(token);
|
||||
replacement.push_str(&format!(
|
||||
let _ = write!(
|
||||
&mut replacement,
|
||||
"b{}",
|
||||
&string.trim_start_matches('u').trim_start_matches('U')
|
||||
));
|
||||
);
|
||||
}
|
||||
_ => {
|
||||
replacement.push_str(locator.slice(TextRange::new(prev, token.end())));
|
||||
|
|
|
|||
|
|
@ -283,7 +283,7 @@ fn match_open_keywords(
|
|||
|
||||
// All other keywords cannot be directly forwarded.
|
||||
_ => return None,
|
||||
};
|
||||
}
|
||||
}
|
||||
Some((result, mode))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -74,7 +74,7 @@ pub(crate) fn bit_count(checker: &Checker, call: &ExprCall) {
|
|||
|
||||
if !call.arguments.keywords.is_empty() {
|
||||
return;
|
||||
};
|
||||
}
|
||||
let [arg] = &*call.arguments.args else {
|
||||
return;
|
||||
};
|
||||
|
|
@ -100,7 +100,7 @@ pub(crate) fn bit_count(checker: &Checker, call: &ExprCall) {
|
|||
|
||||
if !arguments.keywords.is_empty() {
|
||||
return;
|
||||
};
|
||||
}
|
||||
let [arg] = &*arguments.args else {
|
||||
return;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -102,7 +102,7 @@ pub(crate) fn check_and_remove_from_set(checker: &Checker, if_stmt: &ast::StmtIf
|
|||
.is_some_and(|binding| is_set(binding, checker.semantic()))
|
||||
{
|
||||
return;
|
||||
};
|
||||
}
|
||||
|
||||
let mut diagnostic = Diagnostic::new(
|
||||
CheckAndRemoveFromSet {
|
||||
|
|
|
|||
|
|
@ -160,7 +160,7 @@ impl<'a> ReplaceTimeZone<'a> {
|
|||
|
||||
if !arguments.keywords.is_empty() {
|
||||
return None;
|
||||
};
|
||||
}
|
||||
|
||||
let ExprAttribute { value, attr, .. } = call.func.as_attribute_expr()?;
|
||||
|
||||
|
|
|
|||
|
|
@ -182,7 +182,7 @@ fn extract_name_from_sliced_reversed(expr: &Expr) -> Option<&ExprName> {
|
|||
.is_none_or(|value| value != 1)
|
||||
{
|
||||
return None;
|
||||
};
|
||||
}
|
||||
value.as_name_expr()
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -273,7 +273,7 @@ fn itemgetter_op(expr: &ExprSubscript, params: &Parameters, locator: &Locator) -
|
|||
// The argument to the lambda must match the subscripted value, as in: `lambda x: x[1]`.
|
||||
if !is_same_expression(arg, &expr.value) {
|
||||
return None;
|
||||
};
|
||||
}
|
||||
|
||||
// The subscripted expression can't contain references to the argument, as in: `lambda x: x[x]`.
|
||||
if any_over_expr(expr.slice.as_ref(), &|expr| is_same_expression(arg, expr)) {
|
||||
|
|
|
|||
|
|
@ -184,7 +184,7 @@ fn affix_removal_data_stmt(if_stmt: &ast::StmtIf) -> Option<RemoveAffixData> {
|
|||
// ```
|
||||
if !elif_else_clauses.is_empty() {
|
||||
return None;
|
||||
};
|
||||
}
|
||||
|
||||
// Cannot safely transform, e.g.,
|
||||
// ```python
|
||||
|
|
@ -265,7 +265,7 @@ fn affix_removal_data<'a>(
|
|||
})
|
||||
{
|
||||
return None;
|
||||
};
|
||||
}
|
||||
|
||||
let compr_test_expr = ast::comparable::ComparableExpr::from(
|
||||
&test.as_call_expr()?.func.as_attribute_expr()?.value,
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue