mirror of
https://github.com/astral-sh/ruff.git
synced 2025-08-04 02:39:12 +00:00
Upgrade to Rust 1.80 (#12586)
This commit is contained in:
parent
ee103ffb25
commit
138e70bd5c
29 changed files with 57 additions and 48 deletions
|
@ -156,6 +156,7 @@ zip = { version = "0.6.6", default-features = false, features = ["zstd"] }
|
|||
[workspace.lints.rust]
|
||||
unsafe_code = "warn"
|
||||
unreachable_pub = "warn"
|
||||
unexpected_cfgs = { level = "warn", check-cfg = ['cfg(fuzzing)'] }
|
||||
|
||||
[workspace.lints.clippy]
|
||||
pedantic = { level = "warn", priority = -2 }
|
||||
|
|
|
@ -11,3 +11,11 @@ doc-valid-idents = [
|
|||
"SQLAlchemy",
|
||||
"StackOverflow",
|
||||
]
|
||||
|
||||
ignore-interior-mutability = [
|
||||
# Interned is read-only. The wrapped `Rc` never gets updated.
|
||||
"ruff_formatter::format_element::Interned",
|
||||
|
||||
# The expression is read-only.
|
||||
"ruff_python_ast::hashable::HashableExpr",
|
||||
]
|
||||
|
|
|
@ -330,7 +330,7 @@ where
|
|||
function_def.type_params.as_deref(),
|
||||
|builder| {
|
||||
builder.visit_parameters(&function_def.parameters);
|
||||
for expr in &function_def.returns {
|
||||
if let Some(expr) = &function_def.returns {
|
||||
builder.visit_annotation(expr);
|
||||
}
|
||||
|
||||
|
|
|
@ -7,10 +7,10 @@
|
|||
//!
|
||||
//! * [`Format`]: Implemented by objects that can be formatted.
|
||||
//! * [`FormatRule`]: Rule that knows how to format an object of another type. Useful in the situation where
|
||||
//! it's necessary to implement [Format] on an object from another crate. This module defines the
|
||||
//! [`FormatRefWithRule`] and [`FormatOwnedWithRule`] structs to pass an item with its corresponding rule.
|
||||
//! it's necessary to implement [Format] on an object from another crate. This module defines the
|
||||
//! [`FormatRefWithRule`] and [`FormatOwnedWithRule`] structs to pass an item with its corresponding rule.
|
||||
//! * [`FormatWithRule`] implemented by objects that know how to format another type. Useful for implementing
|
||||
//! some reusable formatting logic inside of this module if the type itself doesn't implement [Format]
|
||||
//! some reusable formatting logic inside of this module if the type itself doesn't implement [Format]
|
||||
//!
|
||||
//! ## Formatting Macros
|
||||
//!
|
||||
|
|
|
@ -982,7 +982,7 @@ impl Indentation {
|
|||
/// The behaviour depends on the [`indent_style`][IndentStyle] if this is an [`Indent::Align`]:
|
||||
/// - **Tabs**: `align` is converted into an indent. This results in `level` increasing by two: once for the align, once for the level increment
|
||||
/// - **Spaces**: Increments the `level` by one and keeps the `align` unchanged.
|
||||
/// Keeps any the current value is [`Indent::Align`] and increments the level by one.
|
||||
/// Keeps any the current value is [`Indent::Align`] and increments the level by one.
|
||||
fn increment_level(self, indent_style: IndentStyle) -> Self {
|
||||
match self {
|
||||
Indentation::Level(count) => Indentation::Level(count + 1),
|
||||
|
|
|
@ -719,7 +719,7 @@ impl<'a> Visitor<'a> for Checker<'a> {
|
|||
self.visit_expr(expr);
|
||||
}
|
||||
}
|
||||
for expr in returns {
|
||||
if let Some(expr) = returns {
|
||||
match annotation {
|
||||
AnnotationContext::RuntimeRequired => {
|
||||
self.visit_runtime_required_annotation(expr);
|
||||
|
@ -1240,7 +1240,7 @@ impl<'a> Visitor<'a> for Checker<'a> {
|
|||
for arg in args {
|
||||
self.visit_type_definition(arg);
|
||||
}
|
||||
for keyword in arguments.keywords.iter() {
|
||||
for keyword in &*arguments.keywords {
|
||||
let Keyword {
|
||||
arg,
|
||||
value,
|
||||
|
@ -1286,7 +1286,7 @@ impl<'a> Visitor<'a> for Checker<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
for keyword in arguments.keywords.iter() {
|
||||
for keyword in &*arguments.keywords {
|
||||
let Keyword { arg, value, .. } = keyword;
|
||||
match (arg.as_ref(), value) {
|
||||
// Ex) NamedTuple("a", **{"a": int})
|
||||
|
@ -1331,7 +1331,7 @@ impl<'a> Visitor<'a> for Checker<'a> {
|
|||
}
|
||||
|
||||
// Ex) TypedDict("a", a=int)
|
||||
for keyword in arguments.keywords.iter() {
|
||||
for keyword in &*arguments.keywords {
|
||||
let Keyword { value, .. } = keyword;
|
||||
self.visit_type_definition(value);
|
||||
}
|
||||
|
@ -1345,13 +1345,13 @@ impl<'a> Visitor<'a> for Checker<'a> {
|
|||
for arg in args {
|
||||
self.visit_non_type_definition(arg);
|
||||
}
|
||||
for keyword in arguments.keywords.iter() {
|
||||
for keyword in &*arguments.keywords {
|
||||
let Keyword { value, .. } = keyword;
|
||||
self.visit_non_type_definition(value);
|
||||
}
|
||||
} else {
|
||||
// Ex) DefaultNamedArg(type="bool", name="some_prop_name")
|
||||
for keyword in arguments.keywords.iter() {
|
||||
for keyword in &*arguments.keywords {
|
||||
let Keyword {
|
||||
value,
|
||||
arg,
|
||||
|
@ -1369,10 +1369,10 @@ impl<'a> Visitor<'a> for Checker<'a> {
|
|||
// If we're in a type definition, we need to treat the arguments to any
|
||||
// other callables as non-type definitions (i.e., we don't want to treat
|
||||
// any strings as deferred type definitions).
|
||||
for arg in arguments.args.iter() {
|
||||
for arg in &*arguments.args {
|
||||
self.visit_non_type_definition(arg);
|
||||
}
|
||||
for keyword in arguments.keywords.iter() {
|
||||
for keyword in &*arguments.keywords {
|
||||
let Keyword { value, .. } = keyword;
|
||||
self.visit_non_type_definition(value);
|
||||
}
|
||||
|
|
|
@ -13,10 +13,9 @@ impl Emitter for JsonLinesEmitter {
|
|||
messages: &[Message],
|
||||
context: &EmitterContext,
|
||||
) -> anyhow::Result<()> {
|
||||
let mut w = writer;
|
||||
for message in messages {
|
||||
serde_json::to_writer(&mut w, &message_to_json_value(message, context))?;
|
||||
w.write_all(b"\n")?;
|
||||
serde_json::to_writer(&mut *writer, &message_to_json_value(message, context))?;
|
||||
writer.write_all(b"\n")?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
@ -132,7 +132,7 @@ impl<'a> Visitor<'a> for SuspiciousVariablesVisitor<'a> {
|
|||
match func.as_ref() {
|
||||
Expr::Name(ast::ExprName { id, .. }) => {
|
||||
if matches!(id.as_str(), "filter" | "reduce" | "map") {
|
||||
for arg in arguments.args.iter() {
|
||||
for arg in &*arguments.args {
|
||||
if arg.is_lambda_expr() {
|
||||
self.safe_functions.push(arg);
|
||||
}
|
||||
|
@ -143,7 +143,7 @@ impl<'a> Visitor<'a> for SuspiciousVariablesVisitor<'a> {
|
|||
if attr == "reduce" {
|
||||
if let Expr::Name(ast::ExprName { id, .. }) = value.as_ref() {
|
||||
if id == "functools" {
|
||||
for arg in arguments.args.iter() {
|
||||
for arg in &*arguments.args {
|
||||
if arg.is_lambda_expr() {
|
||||
self.safe_functions.push(arg);
|
||||
}
|
||||
|
@ -155,7 +155,7 @@ impl<'a> Visitor<'a> for SuspiciousVariablesVisitor<'a> {
|
|||
_ => {}
|
||||
}
|
||||
|
||||
for keyword in arguments.keywords.iter() {
|
||||
for keyword in &*arguments.keywords {
|
||||
if keyword.arg.as_ref().is_some_and(|arg| arg == "key")
|
||||
&& keyword.value.is_lambda_expr()
|
||||
{
|
||||
|
|
|
@ -116,7 +116,7 @@ fn is_infinite_iterator(arg: &Expr, semantic: &SemanticModel) -> bool {
|
|||
}
|
||||
|
||||
// Ex) `iterools.repeat(1, times=None)`
|
||||
for keyword in keywords.iter() {
|
||||
for keyword in &**keywords {
|
||||
if keyword.arg.as_ref().is_some_and(|name| name == "times") {
|
||||
if keyword.value.is_none_literal_expr() {
|
||||
return true;
|
||||
|
|
|
@ -88,7 +88,7 @@ fn is_nullable_field<'a>(value: &'a Expr, semantic: &'a SemanticModel) -> Option
|
|||
let mut null_key = false;
|
||||
let mut blank_key = false;
|
||||
let mut unique_key = false;
|
||||
for keyword in call.arguments.keywords.iter() {
|
||||
for keyword in &*call.arguments.keywords {
|
||||
let Some(argument) = &keyword.arg else {
|
||||
continue;
|
||||
};
|
||||
|
|
|
@ -260,7 +260,7 @@ pub(crate) fn string_in_exception(checker: &mut Checker, stmt: &Stmt, exc: &Expr
|
|||
///
|
||||
/// The fix includes two edits:
|
||||
/// 1. Insert the exception argument into a variable assignment before the
|
||||
/// `raise` statement. The variable name is `msg`.
|
||||
/// `raise` statement. The variable name is `msg`.
|
||||
/// 2. Replace the exception argument with the variable name.
|
||||
fn generate_fix(
|
||||
stmt: &Stmt,
|
||||
|
|
|
@ -110,7 +110,7 @@ fn check_log_record_attr_clash(checker: &mut Checker, extra: &Keyword) {
|
|||
..
|
||||
}) => {
|
||||
if checker.semantic().match_builtin_expr(func, "dict") {
|
||||
for keyword in keywords.iter() {
|
||||
for keyword in &**keywords {
|
||||
if let Some(attr) = &keyword.arg {
|
||||
if is_reserved_attr(attr) {
|
||||
checker.diagnostics.push(Diagnostic::new(
|
||||
|
|
|
@ -58,7 +58,7 @@ impl Violation for UnnecessaryDictKwargs {
|
|||
/// PIE804
|
||||
pub(crate) fn unnecessary_dict_kwargs(checker: &mut Checker, call: &ast::ExprCall) {
|
||||
let mut duplicate_keywords = None;
|
||||
for keyword in call.arguments.keywords.iter() {
|
||||
for keyword in &*call.arguments.keywords {
|
||||
// keyword is a spread operator (indicated by None).
|
||||
if keyword.arg.is_some() {
|
||||
continue;
|
||||
|
@ -152,7 +152,7 @@ fn duplicates(call: &ast::ExprCall) -> FxHashSet<&str> {
|
|||
FxHashSet::with_capacity_and_hasher(call.arguments.keywords.len(), FxBuildHasher);
|
||||
let mut duplicates =
|
||||
FxHashSet::with_capacity_and_hasher(call.arguments.keywords.len(), FxBuildHasher);
|
||||
for keyword in call.arguments.keywords.iter() {
|
||||
for keyword in &*call.arguments.keywords {
|
||||
if let Some(name) = &keyword.arg {
|
||||
if !seen.insert(name.as_str()) {
|
||||
duplicates.insert(name.as_str());
|
||||
|
|
|
@ -180,8 +180,8 @@ fn is_type(expr: &Expr, semantic: &SemanticModel) -> bool {
|
|||
/// Returns `true` if the [`Expr`] appears to be a reference to a NumPy dtype, since:
|
||||
/// > `dtype` are a bit of a strange beast, but definitely best thought of as instances, not
|
||||
/// > classes, and they are meant to be comparable not just to their own class, but also to the
|
||||
/// corresponding scalar types (e.g., `x.dtype == np.float32`) and strings (e.g.,
|
||||
/// `x.dtype == ['i1,i4']`; basically, __eq__ always tries to do `dtype(other)`).
|
||||
/// > corresponding scalar types (e.g., `x.dtype == np.float32`) and strings (e.g.,
|
||||
/// > `x.dtype == ['i1,i4']`; basically, __eq__ always tries to do `dtype(other)`).
|
||||
fn is_dtype(expr: &Expr, semantic: &SemanticModel) -> bool {
|
||||
match expr {
|
||||
// Ex) `np.dtype(obj)`
|
||||
|
|
|
@ -64,7 +64,7 @@ pub(crate) fn duplicate_bases(checker: &mut Checker, name: &str, arguments: Opti
|
|||
let bases = &arguments.args;
|
||||
|
||||
let mut seen: FxHashSet<&str> = FxHashSet::with_capacity_and_hasher(bases.len(), FxBuildHasher);
|
||||
for base in bases.iter() {
|
||||
for base in &**bases {
|
||||
if let Expr::Name(ast::ExprName { id, .. }) = base {
|
||||
if !seen.insert(id) {
|
||||
let mut diagnostic = Diagnostic::new(
|
||||
|
|
|
@ -40,7 +40,7 @@ pub(crate) fn repeated_keyword_argument(checker: &mut Checker, call: &ExprCall)
|
|||
|
||||
let mut seen = FxHashSet::with_capacity_and_hasher(arguments.keywords.len(), FxBuildHasher);
|
||||
|
||||
for keyword in arguments.keywords.iter() {
|
||||
for keyword in &*arguments.keywords {
|
||||
if let Some(id) = &keyword.arg {
|
||||
// Ex) `func(a=1, a=2)`
|
||||
if !seen.insert(id.as_str()) {
|
||||
|
|
|
@ -71,7 +71,7 @@ impl<'a> FormatSummaryValues<'a> {
|
|||
let mut extracted_args: Vec<&Expr> = Vec::new();
|
||||
let mut extracted_kwargs: FxHashMap<&str, &Expr> = FxHashMap::default();
|
||||
|
||||
for arg in call.arguments.args.iter() {
|
||||
for arg in &*call.arguments.args {
|
||||
if matches!(arg, Expr::Starred(..))
|
||||
|| contains_quotes(locator.slice(arg))
|
||||
|| locator.contains_line_break(arg.range())
|
||||
|
@ -80,7 +80,7 @@ impl<'a> FormatSummaryValues<'a> {
|
|||
}
|
||||
extracted_args.push(arg);
|
||||
}
|
||||
for keyword in call.arguments.keywords.iter() {
|
||||
for keyword in &*call.arguments.keywords {
|
||||
let Keyword {
|
||||
arg,
|
||||
value,
|
||||
|
|
|
@ -108,7 +108,7 @@ pub(crate) fn replace_str_enum(checker: &mut Checker, class_def: &ast::StmtClass
|
|||
// Determine whether the class inherits from both `str` and `enum.Enum`.
|
||||
let mut inherits_str = false;
|
||||
let mut inherits_enum = false;
|
||||
for base in arguments.args.iter() {
|
||||
for base in &*arguments.args {
|
||||
if let Some(qualified_name) = checker.semantic().resolve_qualified_name(base) {
|
||||
match qualified_name.segments() {
|
||||
["" | "builtins", "str"] => inherits_str = true,
|
||||
|
|
|
@ -50,7 +50,7 @@ pub(crate) fn useless_object_inheritance(checker: &mut Checker, class_def: &ast:
|
|||
return;
|
||||
};
|
||||
|
||||
for base in arguments.args.iter() {
|
||||
for base in &*arguments.args {
|
||||
if !checker.semantic().match_builtin_expr(base, "object") {
|
||||
continue;
|
||||
}
|
||||
|
|
|
@ -138,7 +138,7 @@ pub(crate) fn sorted_min_max(checker: &mut Checker, subscript: &ast::ExprSubscri
|
|||
let mut key_keyword_expr = None;
|
||||
|
||||
// Check if the call to `sorted()` has the `reverse` and `key` keywords.
|
||||
for keyword in arguments.keywords.iter() {
|
||||
for keyword in &*arguments.keywords {
|
||||
// If the call contains `**kwargs`, return.
|
||||
let Some(arg) = keyword.arg.as_ref() else {
|
||||
return;
|
||||
|
|
|
@ -174,12 +174,12 @@ fn should_be_fstring(
|
|||
_ => {}
|
||||
}
|
||||
}
|
||||
for keyword in keywords.iter() {
|
||||
for keyword in &**keywords {
|
||||
if let Some(ident) = keyword.arg.as_ref() {
|
||||
arg_names.insert(ident.as_str());
|
||||
}
|
||||
}
|
||||
for arg in args.iter() {
|
||||
for arg in &**args {
|
||||
if let ast::Expr::Name(ast::ExprName { id, .. }) = arg {
|
||||
arg_names.insert(id.as_str());
|
||||
}
|
||||
|
|
|
@ -119,7 +119,7 @@ fn function_def_visit_preorder_except_body<'a, V>(
|
|||
|
||||
visitor.visit_parameters(parameters);
|
||||
|
||||
for expr in returns {
|
||||
if let Some(expr) = returns {
|
||||
visitor.visit_annotation(expr);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -785,7 +785,7 @@ impl AstNode for ast::StmtFunctionDef {
|
|||
|
||||
visitor.visit_parameters(parameters);
|
||||
|
||||
for expr in returns {
|
||||
if let Some(expr) = returns {
|
||||
visitor.visit_annotation(expr);
|
||||
}
|
||||
|
||||
|
|
|
@ -143,7 +143,7 @@ pub fn walk_stmt<'a, V: Visitor<'a> + ?Sized>(visitor: &mut V, stmt: &'a Stmt) {
|
|||
visitor.visit_type_params(type_params);
|
||||
}
|
||||
visitor.visit_parameters(parameters);
|
||||
for expr in returns {
|
||||
if let Some(expr) = returns {
|
||||
visitor.visit_annotation(expr);
|
||||
}
|
||||
visitor.visit_body(body);
|
||||
|
@ -593,10 +593,10 @@ pub fn walk_arguments<'a, V: Visitor<'a> + ?Sized>(visitor: &mut V, arguments: &
|
|||
// Note that the there might be keywords before the last arg, e.g. in
|
||||
// f(*args, a=2, *args2, **kwargs)`, but we follow Python in evaluating first `args` and then
|
||||
// `keywords`. See also [Arguments::arguments_source_order`].
|
||||
for arg in arguments.args.iter() {
|
||||
for arg in &*arguments.args {
|
||||
visitor.visit_expr(arg);
|
||||
}
|
||||
for keyword in arguments.keywords.iter() {
|
||||
for keyword in &*arguments.keywords {
|
||||
visitor.visit_keyword(keyword);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -130,7 +130,7 @@ pub fn walk_stmt<V: Transformer + ?Sized>(visitor: &V, stmt: &mut Stmt) {
|
|||
visitor.visit_type_params(type_params);
|
||||
}
|
||||
visitor.visit_parameters(parameters);
|
||||
for expr in returns {
|
||||
if let Some(expr) = returns {
|
||||
visitor.visit_annotation(expr);
|
||||
}
|
||||
visitor.visit_body(body);
|
||||
|
@ -579,10 +579,10 @@ pub fn walk_arguments<V: Transformer + ?Sized>(visitor: &V, arguments: &mut Argu
|
|||
// Note that the there might be keywords before the last arg, e.g. in
|
||||
// f(*args, a=2, *args2, **kwargs)`, but we follow Python in evaluating first `args` and then
|
||||
// `keywords`. See also [Arguments::arguments_source_order`].
|
||||
for arg in arguments.args.iter_mut() {
|
||||
for arg in &mut *arguments.args {
|
||||
visitor.visit_expr(arg);
|
||||
}
|
||||
for keyword in arguments.keywords.iter_mut() {
|
||||
for keyword in &mut *arguments.keywords {
|
||||
visitor.visit_keyword(keyword);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,6 +17,7 @@ use crate::{has_skip_comment, prelude::*};
|
|||
/// > A compound statement consists of one or more ‘clauses.’ A clause consists of a header and a ‘suite.’
|
||||
/// > The clause headers of a particular compound statement are all at the same indentation level.
|
||||
/// > Each clause header begins with a uniquely identifying keyword and ends with a colon.
|
||||
///
|
||||
/// [source](https://docs.python.org/3/reference/compound_stmts.html#compound-statements)
|
||||
#[derive(Copy, Clone)]
|
||||
pub(crate) enum ClauseHeader<'a> {
|
||||
|
|
|
@ -928,9 +928,9 @@ impl<'src> CodeExampleDoctest<'src> {
|
|||
/// the same with two main differences:
|
||||
///
|
||||
/// 1. Literal blocks are began with a line that ends with `::`. Code block
|
||||
/// directives are began with a line like `.. code-block:: python`.
|
||||
/// directives are began with a line like `.. code-block:: python`.
|
||||
/// 2. Code block directives permit a list of options as a "field list"
|
||||
/// immediately after the opening line. Literal blocks have no options.
|
||||
/// immediately after the opening line. Literal blocks have no options.
|
||||
///
|
||||
/// Otherwise, everything else, including the indentation structure, is the
|
||||
/// same.
|
||||
|
|
|
@ -2295,7 +2295,7 @@ impl<'src> Parser<'src> {
|
|||
}
|
||||
|
||||
if arguments.len() > 1 {
|
||||
for arg in arguments.args.iter() {
|
||||
for arg in &*arguments.args {
|
||||
if let Some(ast::ExprGenerator {
|
||||
range,
|
||||
parenthesized: false,
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
[toolchain]
|
||||
channel = "1.79"
|
||||
channel = "1.80"
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue