mirror of https://github.com/astral-sh/ruff
Merge remote-tracking branch 'origin/main' into dcreager/param-variance
* origin/main: (29 commits) Document range suppressions, reorganize suppression docs (#21884) Ignore ruff:isort like ruff:noqa in new suppressions (#21922) [ty] Handle `Definition`s in `SemanticModel::scope` (#21919) [ty] Attach salsa db when running ide tests for easier debugging (#21917) [ty] Don't show hover for expressions with no inferred type (#21924) [ty] avoid unions of generic aliases of the same class in fixpoint (#21909) [ty] Squash false positive logs for failing to find `builtins` as a real module [ty] Uniformly use "not supported" in diagnostics (#21916) [ty] Reduce size of ty-ide snapshots (#21915) [ty] Adjust scope completions to use all reachable symbols [ty] Rename `all_members_of_scope` to `all_end_of_scope_members` [ty] Remove `all_` prefix from some routines on UseDefMap Enable `--document-private-items` for `ruff_python_formatter` (#21903) Remove `BackwardsTokenizer` based `parenthesized_range` references in `ruff_linter` (#21836) [ty] Revert "Do not infer types for invalid binary expressions in annotations" (#21914) Skip over trivia tokens after re-lexing (#21895) [ty] Avoid inferring types for invalid binary expressions in string annotations (#21911) [ty] Improve overload call resolution tracing (#21913) [ty] fix missing heap_size on Salsa query (#21912) [ty] Support implicit type of `cls` in signatures (#21771) ...
This commit is contained in:
commit
93e71be357
|
|
@ -298,7 +298,7 @@ jobs:
|
||||||
# sync, not just public items. Eventually we should do this for all
|
# sync, not just public items. Eventually we should do this for all
|
||||||
# crates; for now add crates here as they are warning-clean to prevent
|
# crates; for now add crates here as they are warning-clean to prevent
|
||||||
# regression.
|
# regression.
|
||||||
- run: cargo doc --no-deps -p ty_python_semantic -p ty -p ty_test -p ruff_db --document-private-items
|
- run: cargo doc --no-deps -p ty_python_semantic -p ty -p ty_test -p ruff_db -p ruff_python_formatter --document-private-items
|
||||||
env:
|
env:
|
||||||
# Setting RUSTDOCFLAGS because `cargo doc --check` isn't yet implemented (https://github.com/rust-lang/cargo/issues/10025).
|
# Setting RUSTDOCFLAGS because `cargo doc --check` isn't yet implemented (https://github.com/rust-lang/cargo/issues/10025).
|
||||||
RUSTDOCFLAGS: "-D warnings"
|
RUSTDOCFLAGS: "-D warnings"
|
||||||
|
|
|
||||||
|
|
@ -47,6 +47,7 @@ jobs:
|
||||||
|
|
||||||
- uses: Swatinem/rust-cache@779680da715d629ac1d338a641029a2f4372abb5 # v2.8.2
|
- uses: Swatinem/rust-cache@779680da715d629ac1d338a641029a2f4372abb5 # v2.8.2
|
||||||
with:
|
with:
|
||||||
|
shared-key: "mypy-primer"
|
||||||
workspaces: "ruff"
|
workspaces: "ruff"
|
||||||
|
|
||||||
- name: Install Rust toolchain
|
- name: Install Rust toolchain
|
||||||
|
|
@ -86,6 +87,7 @@ jobs:
|
||||||
- uses: Swatinem/rust-cache@779680da715d629ac1d338a641029a2f4372abb5 # v2.8.2
|
- uses: Swatinem/rust-cache@779680da715d629ac1d338a641029a2f4372abb5 # v2.8.2
|
||||||
with:
|
with:
|
||||||
workspaces: "ruff"
|
workspaces: "ruff"
|
||||||
|
shared-key: "mypy-primer"
|
||||||
|
|
||||||
- name: Install Rust toolchain
|
- name: Install Rust toolchain
|
||||||
run: rustup show
|
run: rustup show
|
||||||
|
|
@ -105,3 +107,54 @@ jobs:
|
||||||
with:
|
with:
|
||||||
name: mypy_primer_memory_diff
|
name: mypy_primer_memory_diff
|
||||||
path: mypy_primer_memory.diff
|
path: mypy_primer_memory.diff
|
||||||
|
|
||||||
|
# Runs mypy twice against the same ty version to catch any non-deterministic behavior (ideally).
|
||||||
|
# The job is disabled for now because there are some non-deterministic diagnostics.
|
||||||
|
mypy_primer_same_revision:
|
||||||
|
name: Run mypy_primer on same revision
|
||||||
|
runs-on: ${{ github.repository == 'astral-sh/ruff' && 'depot-ubuntu-22.04-32' || 'ubuntu-latest' }}
|
||||||
|
timeout-minutes: 20
|
||||||
|
# TODO: Enable once we fixed the non-deterministic diagnostics
|
||||||
|
if: false
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
||||||
|
with:
|
||||||
|
path: ruff
|
||||||
|
fetch-depth: 0
|
||||||
|
persist-credentials: false
|
||||||
|
|
||||||
|
- name: Install the latest version of uv
|
||||||
|
uses: astral-sh/setup-uv@1e862dfacbd1d6d858c55d9b792c756523627244 # v7.1.4
|
||||||
|
|
||||||
|
- uses: Swatinem/rust-cache@779680da715d629ac1d338a641029a2f4372abb5 # v2.8.2
|
||||||
|
with:
|
||||||
|
workspaces: "ruff"
|
||||||
|
shared-key: "mypy-primer"
|
||||||
|
|
||||||
|
- name: Install Rust toolchain
|
||||||
|
run: rustup show
|
||||||
|
|
||||||
|
- name: Run determinism check
|
||||||
|
env:
|
||||||
|
BASE_REVISION: ${{ github.event.pull_request.head.sha }}
|
||||||
|
PRIMER_SELECTOR: crates/ty_python_semantic/resources/primer/good.txt
|
||||||
|
CLICOLOR_FORCE: "1"
|
||||||
|
DIFF_FILE: mypy_primer_determinism.diff
|
||||||
|
run: |
|
||||||
|
cd ruff
|
||||||
|
scripts/mypy_primer.sh
|
||||||
|
|
||||||
|
- name: Check for non-determinism
|
||||||
|
run: |
|
||||||
|
# Remove ANSI color codes for checking
|
||||||
|
sed -e 's/\x1b\[[0-9;]*m//g' mypy_primer_determinism.diff > mypy_primer_determinism_clean.diff
|
||||||
|
|
||||||
|
# Check if there are any differences (non-determinism)
|
||||||
|
if [ -s mypy_primer_determinism_clean.diff ]; then
|
||||||
|
echo "ERROR: Non-deterministic output detected!"
|
||||||
|
echo "The following differences were found when running ty twice on the same commit:"
|
||||||
|
cat mypy_primer_determinism_clean.diff
|
||||||
|
exit 1
|
||||||
|
else
|
||||||
|
echo "✓ Output is deterministic"
|
||||||
|
fi
|
||||||
|
|
|
||||||
|
|
@ -3349,6 +3349,7 @@ dependencies = [
|
||||||
"compact_str",
|
"compact_str",
|
||||||
"get-size2",
|
"get-size2",
|
||||||
"insta",
|
"insta",
|
||||||
|
"itertools 0.14.0",
|
||||||
"memchr",
|
"memchr",
|
||||||
"ruff_annotate_snippets",
|
"ruff_annotate_snippets",
|
||||||
"ruff_python_ast",
|
"ruff_python_ast",
|
||||||
|
|
|
||||||
|
|
@ -437,6 +437,15 @@ impl<'a> Checker<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns the [`Tokens`] for the parsed source file.
|
||||||
|
///
|
||||||
|
///
|
||||||
|
/// Unlike [`Self::tokens`], this method always returns
|
||||||
|
/// the tokens for the current file, even when within a parsed type annotation.
|
||||||
|
pub(crate) fn source_tokens(&self) -> &'a Tokens {
|
||||||
|
self.parsed.tokens()
|
||||||
|
}
|
||||||
|
|
||||||
/// The [`Locator`] for the current file, which enables extraction of source code from byte
|
/// The [`Locator`] for the current file, which enables extraction of source code from byte
|
||||||
/// offsets.
|
/// offsets.
|
||||||
pub(crate) const fn locator(&self) -> &'a Locator<'a> {
|
pub(crate) const fn locator(&self) -> &'a Locator<'a> {
|
||||||
|
|
|
||||||
|
|
@ -3,14 +3,13 @@
|
||||||
use anyhow::{Context, Result};
|
use anyhow::{Context, Result};
|
||||||
|
|
||||||
use ruff_python_ast::AnyNodeRef;
|
use ruff_python_ast::AnyNodeRef;
|
||||||
use ruff_python_ast::parenthesize::parenthesized_range;
|
use ruff_python_ast::token::{self, Tokens, parenthesized_range};
|
||||||
use ruff_python_ast::{self as ast, Arguments, ExceptHandler, Expr, ExprList, Parameters, Stmt};
|
use ruff_python_ast::{self as ast, Arguments, ExceptHandler, Expr, ExprList, Parameters, Stmt};
|
||||||
use ruff_python_codegen::Stylist;
|
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::{
|
||||||
CommentRanges, PythonWhitespace, SimpleTokenKind, SimpleTokenizer, has_leading_content,
|
PythonWhitespace, SimpleTokenKind, SimpleTokenizer, has_leading_content, is_python_whitespace,
|
||||||
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};
|
||||||
|
|
@ -209,7 +208,7 @@ pub(crate) fn remove_argument<T: Ranged>(
|
||||||
arguments: &Arguments,
|
arguments: &Arguments,
|
||||||
parentheses: Parentheses,
|
parentheses: Parentheses,
|
||||||
source: &str,
|
source: &str,
|
||||||
comment_ranges: &CommentRanges,
|
tokens: &Tokens,
|
||||||
) -> Result<Edit> {
|
) -> Result<Edit> {
|
||||||
// Partition into arguments before and after the argument to remove.
|
// Partition into arguments before and after the argument to remove.
|
||||||
let (before, after): (Vec<_>, Vec<_>) = arguments
|
let (before, after): (Vec<_>, Vec<_>) = arguments
|
||||||
|
|
@ -224,7 +223,7 @@ pub(crate) fn remove_argument<T: Ranged>(
|
||||||
.context("Unable to find argument")?;
|
.context("Unable to find argument")?;
|
||||||
|
|
||||||
let parenthesized_range =
|
let parenthesized_range =
|
||||||
parenthesized_range(arg.value().into(), arguments.into(), comment_ranges, source)
|
token::parenthesized_range(arg.value().into(), arguments.into(), tokens)
|
||||||
.unwrap_or(arg.range());
|
.unwrap_or(arg.range());
|
||||||
|
|
||||||
if !after.is_empty() {
|
if !after.is_empty() {
|
||||||
|
|
@ -270,25 +269,14 @@ pub(crate) fn remove_argument<T: Ranged>(
|
||||||
///
|
///
|
||||||
/// The new argument will be inserted before the first existing keyword argument in `arguments`, if
|
/// The new argument will be inserted before the first existing keyword argument in `arguments`, if
|
||||||
/// there are any present. Otherwise, the new argument is added to the end of the argument list.
|
/// there are any present. Otherwise, the new argument is added to the end of the argument list.
|
||||||
pub(crate) fn add_argument(
|
pub(crate) fn add_argument(argument: &str, arguments: &Arguments, tokens: &Tokens) -> Edit {
|
||||||
argument: &str,
|
|
||||||
arguments: &Arguments,
|
|
||||||
comment_ranges: &CommentRanges,
|
|
||||||
source: &str,
|
|
||||||
) -> Edit {
|
|
||||||
if let Some(ast::Keyword { range, value, .. }) = arguments.keywords.first() {
|
if let Some(ast::Keyword { range, value, .. }) = arguments.keywords.first() {
|
||||||
let keyword = parenthesized_range(value.into(), arguments.into(), comment_ranges, source)
|
let keyword = parenthesized_range(value.into(), arguments.into(), tokens).unwrap_or(*range);
|
||||||
.unwrap_or(*range);
|
|
||||||
Edit::insertion(format!("{argument}, "), keyword.start())
|
Edit::insertion(format!("{argument}, "), keyword.start())
|
||||||
} else if let Some(last) = arguments.arguments_source_order().last() {
|
} else if let Some(last) = arguments.arguments_source_order().last() {
|
||||||
// Case 1: existing arguments, so append after the last argument.
|
// Case 1: existing arguments, so append after the last argument.
|
||||||
let last = parenthesized_range(
|
let last = parenthesized_range(last.value().into(), arguments.into(), tokens)
|
||||||
last.value().into(),
|
.unwrap_or(last.range());
|
||||||
arguments.into(),
|
|
||||||
comment_ranges,
|
|
||||||
source,
|
|
||||||
)
|
|
||||||
.unwrap_or(last.range());
|
|
||||||
Edit::insertion(format!(", {argument}"), last.end())
|
Edit::insertion(format!(", {argument}"), last.end())
|
||||||
} else {
|
} else {
|
||||||
// Case 2: no arguments. Add argument, without any trailing comma.
|
// Case 2: no arguments. Add argument, without any trailing comma.
|
||||||
|
|
|
||||||
|
|
@ -91,8 +91,8 @@ pub(crate) fn fastapi_redundant_response_model(checker: &Checker, function_def:
|
||||||
response_model_arg,
|
response_model_arg,
|
||||||
&call.arguments,
|
&call.arguments,
|
||||||
Parentheses::Preserve,
|
Parentheses::Preserve,
|
||||||
checker.locator().contents(),
|
checker.source(),
|
||||||
checker.comment_ranges(),
|
checker.tokens(),
|
||||||
)
|
)
|
||||||
.map(Fix::unsafe_edit)
|
.map(Fix::unsafe_edit)
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -74,12 +74,7 @@ pub(crate) fn map_without_explicit_strict(checker: &Checker, call: &ast::ExprCal
|
||||||
checker
|
checker
|
||||||
.report_diagnostic(MapWithoutExplicitStrict, call.range())
|
.report_diagnostic(MapWithoutExplicitStrict, call.range())
|
||||||
.set_fix(Fix::applicable_edit(
|
.set_fix(Fix::applicable_edit(
|
||||||
add_argument(
|
add_argument("strict=False", &call.arguments, checker.tokens()),
|
||||||
"strict=False",
|
|
||||||
&call.arguments,
|
|
||||||
checker.comment_ranges(),
|
|
||||||
checker.locator().contents(),
|
|
||||||
),
|
|
||||||
Applicability::Unsafe,
|
Applicability::Unsafe,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@ use std::fmt::Write;
|
||||||
use ruff_macros::{ViolationMetadata, derive_message_formats};
|
use ruff_macros::{ViolationMetadata, derive_message_formats};
|
||||||
use ruff_python_ast::helpers::is_docstring_stmt;
|
use ruff_python_ast::helpers::is_docstring_stmt;
|
||||||
use ruff_python_ast::name::QualifiedName;
|
use ruff_python_ast::name::QualifiedName;
|
||||||
use ruff_python_ast::parenthesize::parenthesized_range;
|
use ruff_python_ast::token::parenthesized_range;
|
||||||
use ruff_python_ast::{self as ast, Expr, ParameterWithDefault};
|
use ruff_python_ast::{self as ast, Expr, ParameterWithDefault};
|
||||||
use ruff_python_semantic::SemanticModel;
|
use ruff_python_semantic::SemanticModel;
|
||||||
use ruff_python_semantic::analyze::function_type::is_stub;
|
use ruff_python_semantic::analyze::function_type::is_stub;
|
||||||
|
|
@ -166,12 +166,7 @@ fn move_initialization(
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
let range = match parenthesized_range(
|
let range = match parenthesized_range(default.into(), parameter.into(), checker.tokens()) {
|
||||||
default.into(),
|
|
||||||
parameter.into(),
|
|
||||||
checker.comment_ranges(),
|
|
||||||
checker.source(),
|
|
||||||
) {
|
|
||||||
Some(range) => range,
|
Some(range) => range,
|
||||||
None => default.range(),
|
None => default.range(),
|
||||||
};
|
};
|
||||||
|
|
@ -194,13 +189,8 @@ fn move_initialization(
|
||||||
"{} = {}",
|
"{} = {}",
|
||||||
parameter.parameter.name(),
|
parameter.parameter.name(),
|
||||||
locator.slice(
|
locator.slice(
|
||||||
parenthesized_range(
|
parenthesized_range(default.into(), parameter.into(), checker.tokens())
|
||||||
default.into(),
|
.unwrap_or(default.range())
|
||||||
parameter.into(),
|
|
||||||
checker.comment_ranges(),
|
|
||||||
checker.source()
|
|
||||||
)
|
|
||||||
.unwrap_or(default.range())
|
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
||||||
|
|
@ -92,12 +92,7 @@ pub(crate) fn no_explicit_stacklevel(checker: &Checker, call: &ast::ExprCall) {
|
||||||
}
|
}
|
||||||
let mut diagnostic = checker.report_diagnostic(NoExplicitStacklevel, call.func.range());
|
let mut diagnostic = checker.report_diagnostic(NoExplicitStacklevel, call.func.range());
|
||||||
|
|
||||||
let edit = add_argument(
|
let edit = add_argument("stacklevel=2", &call.arguments, checker.tokens());
|
||||||
"stacklevel=2",
|
|
||||||
&call.arguments,
|
|
||||||
checker.comment_ranges(),
|
|
||||||
checker.locator().contents(),
|
|
||||||
);
|
|
||||||
|
|
||||||
diagnostic.set_fix(Fix::unsafe_edit(edit));
|
diagnostic.set_fix(Fix::unsafe_edit(edit));
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -70,12 +70,7 @@ pub(crate) fn zip_without_explicit_strict(checker: &Checker, call: &ast::ExprCal
|
||||||
checker
|
checker
|
||||||
.report_diagnostic(ZipWithoutExplicitStrict, call.range())
|
.report_diagnostic(ZipWithoutExplicitStrict, call.range())
|
||||||
.set_fix(Fix::applicable_edit(
|
.set_fix(Fix::applicable_edit(
|
||||||
add_argument(
|
add_argument("strict=False", &call.arguments, checker.tokens()),
|
||||||
"strict=False",
|
|
||||||
&call.arguments,
|
|
||||||
checker.comment_ranges(),
|
|
||||||
checker.locator().contents(),
|
|
||||||
),
|
|
||||||
Applicability::Unsafe,
|
Applicability::Unsafe,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,8 +2,8 @@ use ruff_macros::{ViolationMetadata, derive_message_formats};
|
||||||
use ruff_python_ast as ast;
|
use ruff_python_ast as ast;
|
||||||
use ruff_python_ast::ExprGenerator;
|
use ruff_python_ast::ExprGenerator;
|
||||||
use ruff_python_ast::comparable::ComparableExpr;
|
use ruff_python_ast::comparable::ComparableExpr;
|
||||||
use ruff_python_ast::parenthesize::parenthesized_range;
|
|
||||||
use ruff_python_ast::token::TokenKind;
|
use ruff_python_ast::token::TokenKind;
|
||||||
|
use ruff_python_ast::token::parenthesized_range;
|
||||||
use ruff_text_size::{Ranged, TextRange, TextSize};
|
use ruff_text_size::{Ranged, TextRange, TextSize};
|
||||||
|
|
||||||
use crate::checkers::ast::Checker;
|
use crate::checkers::ast::Checker;
|
||||||
|
|
@ -142,13 +142,9 @@ pub(crate) fn unnecessary_generator_list(checker: &Checker, call: &ast::ExprCall
|
||||||
if *parenthesized {
|
if *parenthesized {
|
||||||
// The generator's range will include the innermost parentheses, but it could be
|
// The generator's range will include the innermost parentheses, but it could be
|
||||||
// surrounded by additional parentheses.
|
// surrounded by additional parentheses.
|
||||||
let range = parenthesized_range(
|
let range =
|
||||||
argument.into(),
|
parenthesized_range(argument.into(), (&call.arguments).into(), checker.tokens())
|
||||||
(&call.arguments).into(),
|
.unwrap_or(argument.range());
|
||||||
checker.comment_ranges(),
|
|
||||||
checker.locator().contents(),
|
|
||||||
)
|
|
||||||
.unwrap_or(argument.range());
|
|
||||||
|
|
||||||
// The generator always parenthesizes the expression; trim the parentheses.
|
// The generator always parenthesizes the expression; trim the parentheses.
|
||||||
let generator = checker.generator().expr(argument);
|
let generator = checker.generator().expr(argument);
|
||||||
|
|
|
||||||
|
|
@ -2,8 +2,8 @@ use ruff_macros::{ViolationMetadata, derive_message_formats};
|
||||||
use ruff_python_ast as ast;
|
use ruff_python_ast as ast;
|
||||||
use ruff_python_ast::ExprGenerator;
|
use ruff_python_ast::ExprGenerator;
|
||||||
use ruff_python_ast::comparable::ComparableExpr;
|
use ruff_python_ast::comparable::ComparableExpr;
|
||||||
use ruff_python_ast::parenthesize::parenthesized_range;
|
|
||||||
use ruff_python_ast::token::TokenKind;
|
use ruff_python_ast::token::TokenKind;
|
||||||
|
use ruff_python_ast::token::parenthesized_range;
|
||||||
use ruff_text_size::{Ranged, TextRange, TextSize};
|
use ruff_text_size::{Ranged, TextRange, TextSize};
|
||||||
|
|
||||||
use crate::checkers::ast::Checker;
|
use crate::checkers::ast::Checker;
|
||||||
|
|
@ -147,13 +147,9 @@ pub(crate) fn unnecessary_generator_set(checker: &Checker, call: &ast::ExprCall)
|
||||||
if *parenthesized {
|
if *parenthesized {
|
||||||
// The generator's range will include the innermost parentheses, but it could be
|
// The generator's range will include the innermost parentheses, but it could be
|
||||||
// surrounded by additional parentheses.
|
// surrounded by additional parentheses.
|
||||||
let range = parenthesized_range(
|
let range =
|
||||||
argument.into(),
|
parenthesized_range(argument.into(), (&call.arguments).into(), checker.tokens())
|
||||||
(&call.arguments).into(),
|
.unwrap_or(argument.range());
|
||||||
checker.comment_ranges(),
|
|
||||||
checker.locator().contents(),
|
|
||||||
)
|
|
||||||
.unwrap_or(argument.range());
|
|
||||||
|
|
||||||
// The generator always parenthesizes the expression; trim the parentheses.
|
// The generator always parenthesizes the expression; trim the parentheses.
|
||||||
let generator = checker.generator().expr(argument);
|
let generator = checker.generator().expr(argument);
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
use ruff_macros::{ViolationMetadata, derive_message_formats};
|
use ruff_macros::{ViolationMetadata, derive_message_formats};
|
||||||
use ruff_python_ast as ast;
|
use ruff_python_ast as ast;
|
||||||
use ruff_python_ast::parenthesize::parenthesized_range;
|
|
||||||
use ruff_python_ast::token::TokenKind;
|
use ruff_python_ast::token::TokenKind;
|
||||||
|
use ruff_python_ast::token::parenthesized_range;
|
||||||
use ruff_text_size::{Ranged, TextRange, TextSize};
|
use ruff_text_size::{Ranged, TextRange, TextSize};
|
||||||
|
|
||||||
use crate::checkers::ast::Checker;
|
use crate::checkers::ast::Checker;
|
||||||
|
|
@ -89,13 +89,9 @@ pub(crate) fn unnecessary_list_comprehension_set(checker: &Checker, call: &ast::
|
||||||
|
|
||||||
// If the list comprehension is parenthesized, remove the parentheses in addition to
|
// If the list comprehension is parenthesized, remove the parentheses in addition to
|
||||||
// removing the brackets.
|
// removing the brackets.
|
||||||
let replacement_range = parenthesized_range(
|
let replacement_range =
|
||||||
argument.into(),
|
parenthesized_range(argument.into(), (&call.arguments).into(), checker.tokens())
|
||||||
(&call.arguments).into(),
|
.unwrap_or_else(|| argument.range());
|
||||||
checker.comment_ranges(),
|
|
||||||
checker.locator().contents(),
|
|
||||||
)
|
|
||||||
.unwrap_or_else(|| argument.range());
|
|
||||||
|
|
||||||
let span = argument.range().add_start(one).sub_end(one);
|
let span = argument.range().add_start(one).sub_end(one);
|
||||||
let replacement =
|
let replacement =
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
use ruff_macros::{ViolationMetadata, derive_message_formats};
|
use ruff_macros::{ViolationMetadata, derive_message_formats};
|
||||||
use ruff_python_ast::parenthesize::parenthesized_range;
|
use ruff_python_ast::token::parenthesized_range;
|
||||||
use ruff_python_ast::{self as ast, Expr, Operator};
|
use ruff_python_ast::{self as ast, Expr, Operator};
|
||||||
use ruff_python_trivia::is_python_whitespace;
|
use ruff_python_trivia::is_python_whitespace;
|
||||||
use ruff_source_file::LineRanges;
|
use ruff_source_file::LineRanges;
|
||||||
|
|
@ -88,13 +88,7 @@ pub(crate) fn explicit(checker: &Checker, expr: &Expr) {
|
||||||
checker.report_diagnostic(ExplicitStringConcatenation, expr.range());
|
checker.report_diagnostic(ExplicitStringConcatenation, expr.range());
|
||||||
|
|
||||||
let is_parenthesized = |expr: &Expr| {
|
let is_parenthesized = |expr: &Expr| {
|
||||||
parenthesized_range(
|
parenthesized_range(expr.into(), bin_op.into(), checker.tokens()).is_some()
|
||||||
expr.into(),
|
|
||||||
bin_op.into(),
|
|
||||||
checker.comment_ranges(),
|
|
||||||
checker.source(),
|
|
||||||
)
|
|
||||||
.is_some()
|
|
||||||
};
|
};
|
||||||
// If either `left` or `right` is parenthesized, generating
|
// If either `left` or `right` is parenthesized, generating
|
||||||
// a fix would be too involved. Just report the diagnostic.
|
// a fix would be too involved. Just report the diagnostic.
|
||||||
|
|
|
||||||
|
|
@ -111,7 +111,6 @@ pub(crate) fn exc_info_outside_except_handler(checker: &Checker, call: &ExprCall
|
||||||
}
|
}
|
||||||
|
|
||||||
let arguments = &call.arguments;
|
let arguments = &call.arguments;
|
||||||
let source = checker.source();
|
|
||||||
|
|
||||||
let mut diagnostic = checker.report_diagnostic(ExcInfoOutsideExceptHandler, exc_info.range);
|
let mut diagnostic = checker.report_diagnostic(ExcInfoOutsideExceptHandler, exc_info.range);
|
||||||
|
|
||||||
|
|
@ -120,8 +119,8 @@ pub(crate) fn exc_info_outside_except_handler(checker: &Checker, call: &ExprCall
|
||||||
exc_info,
|
exc_info,
|
||||||
arguments,
|
arguments,
|
||||||
Parentheses::Preserve,
|
Parentheses::Preserve,
|
||||||
source,
|
checker.source(),
|
||||||
checker.comment_ranges(),
|
checker.tokens(),
|
||||||
)?;
|
)?;
|
||||||
Ok(Fix::unsafe_edit(edit))
|
Ok(Fix::unsafe_edit(edit))
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ use itertools::Itertools;
|
||||||
use rustc_hash::{FxBuildHasher, FxHashSet};
|
use rustc_hash::{FxBuildHasher, FxHashSet};
|
||||||
|
|
||||||
use ruff_macros::{ViolationMetadata, derive_message_formats};
|
use ruff_macros::{ViolationMetadata, derive_message_formats};
|
||||||
use ruff_python_ast::parenthesize::parenthesized_range;
|
use ruff_python_ast::token::parenthesized_range;
|
||||||
use ruff_python_ast::{self as ast, Expr};
|
use ruff_python_ast::{self as ast, Expr};
|
||||||
use ruff_python_stdlib::identifiers::is_identifier;
|
use ruff_python_stdlib::identifiers::is_identifier;
|
||||||
use ruff_text_size::Ranged;
|
use ruff_text_size::Ranged;
|
||||||
|
|
@ -129,8 +129,8 @@ pub(crate) fn unnecessary_dict_kwargs(checker: &Checker, call: &ast::ExprCall) {
|
||||||
keyword,
|
keyword,
|
||||||
&call.arguments,
|
&call.arguments,
|
||||||
Parentheses::Preserve,
|
Parentheses::Preserve,
|
||||||
checker.locator().contents(),
|
checker.source(),
|
||||||
checker.comment_ranges(),
|
checker.tokens(),
|
||||||
)
|
)
|
||||||
.map(Fix::safe_edit)
|
.map(Fix::safe_edit)
|
||||||
});
|
});
|
||||||
|
|
@ -158,8 +158,7 @@ pub(crate) fn unnecessary_dict_kwargs(checker: &Checker, call: &ast::ExprCall) {
|
||||||
parenthesized_range(
|
parenthesized_range(
|
||||||
value.into(),
|
value.into(),
|
||||||
dict.into(),
|
dict.into(),
|
||||||
checker.comment_ranges(),
|
checker.tokens()
|
||||||
checker.locator().contents(),
|
|
||||||
)
|
)
|
||||||
.unwrap_or(value.range())
|
.unwrap_or(value.range())
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -73,11 +73,11 @@ pub(crate) fn unnecessary_range_start(checker: &Checker, call: &ast::ExprCall) {
|
||||||
let mut diagnostic = checker.report_diagnostic(UnnecessaryRangeStart, start.range());
|
let mut diagnostic = checker.report_diagnostic(UnnecessaryRangeStart, start.range());
|
||||||
diagnostic.try_set_fix(|| {
|
diagnostic.try_set_fix(|| {
|
||||||
remove_argument(
|
remove_argument(
|
||||||
&start,
|
start,
|
||||||
&call.arguments,
|
&call.arguments,
|
||||||
Parentheses::Preserve,
|
Parentheses::Preserve,
|
||||||
checker.locator().contents(),
|
checker.source(),
|
||||||
checker.comment_ranges(),
|
checker.tokens(),
|
||||||
)
|
)
|
||||||
.map(Fix::safe_edit)
|
.map(Fix::safe_edit)
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -160,20 +160,16 @@ fn generate_fix(
|
||||||
) -> anyhow::Result<Fix> {
|
) -> anyhow::Result<Fix> {
|
||||||
let locator = checker.locator();
|
let locator = checker.locator();
|
||||||
let source = locator.contents();
|
let source = locator.contents();
|
||||||
|
let tokens = checker.tokens();
|
||||||
|
|
||||||
let deletion = remove_argument(
|
let deletion = remove_argument(
|
||||||
generic_base,
|
generic_base,
|
||||||
arguments,
|
arguments,
|
||||||
Parentheses::Preserve,
|
Parentheses::Preserve,
|
||||||
source,
|
source,
|
||||||
checker.comment_ranges(),
|
tokens,
|
||||||
)?;
|
)?;
|
||||||
let insertion = add_argument(
|
let insertion = add_argument(locator.slice(generic_base), arguments, tokens);
|
||||||
locator.slice(generic_base),
|
|
||||||
arguments,
|
|
||||||
checker.comment_ranges(),
|
|
||||||
source,
|
|
||||||
);
|
|
||||||
|
|
||||||
Ok(Fix::unsafe_edits(deletion, [insertion]))
|
Ok(Fix::unsafe_edits(deletion, [insertion]))
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ use ruff_python_ast::{
|
||||||
helpers::{pep_604_union, typing_optional},
|
helpers::{pep_604_union, typing_optional},
|
||||||
name::Name,
|
name::Name,
|
||||||
operator_precedence::OperatorPrecedence,
|
operator_precedence::OperatorPrecedence,
|
||||||
parenthesize::parenthesized_range,
|
token::{Tokens, parenthesized_range},
|
||||||
};
|
};
|
||||||
use ruff_python_semantic::analyze::typing::{traverse_literal, traverse_union};
|
use ruff_python_semantic::analyze::typing::{traverse_literal, traverse_union};
|
||||||
use ruff_text_size::{Ranged, TextRange};
|
use ruff_text_size::{Ranged, TextRange};
|
||||||
|
|
@ -243,16 +243,12 @@ fn create_fix(
|
||||||
let union_expr = pep_604_union(&[new_literal_expr, none_expr]);
|
let union_expr = pep_604_union(&[new_literal_expr, none_expr]);
|
||||||
|
|
||||||
// Check if we need parentheses to preserve operator precedence
|
// Check if we need parentheses to preserve operator precedence
|
||||||
let content = if needs_parentheses_for_precedence(
|
let content =
|
||||||
semantic,
|
if needs_parentheses_for_precedence(semantic, literal_expr, checker.tokens()) {
|
||||||
literal_expr,
|
format!("({})", checker.generator().expr(&union_expr))
|
||||||
checker.comment_ranges(),
|
} else {
|
||||||
checker.source(),
|
checker.generator().expr(&union_expr)
|
||||||
) {
|
};
|
||||||
format!("({})", checker.generator().expr(&union_expr))
|
|
||||||
} else {
|
|
||||||
checker.generator().expr(&union_expr)
|
|
||||||
};
|
|
||||||
|
|
||||||
let union_edit = Edit::range_replacement(content, literal_expr.range());
|
let union_edit = Edit::range_replacement(content, literal_expr.range());
|
||||||
Fix::applicable_edit(union_edit, applicability)
|
Fix::applicable_edit(union_edit, applicability)
|
||||||
|
|
@ -278,8 +274,7 @@ enum UnionKind {
|
||||||
fn needs_parentheses_for_precedence(
|
fn needs_parentheses_for_precedence(
|
||||||
semantic: &ruff_python_semantic::SemanticModel,
|
semantic: &ruff_python_semantic::SemanticModel,
|
||||||
literal_expr: &Expr,
|
literal_expr: &Expr,
|
||||||
comment_ranges: &ruff_python_trivia::CommentRanges,
|
tokens: &Tokens,
|
||||||
source: &str,
|
|
||||||
) -> bool {
|
) -> bool {
|
||||||
// Get the parent expression to check if we're in a context that needs parentheses
|
// Get the parent expression to check if we're in a context that needs parentheses
|
||||||
let Some(parent_expr) = semantic.current_expression_parent() else {
|
let Some(parent_expr) = semantic.current_expression_parent() else {
|
||||||
|
|
@ -287,14 +282,7 @@ fn needs_parentheses_for_precedence(
|
||||||
};
|
};
|
||||||
|
|
||||||
// Check if the literal expression is already parenthesized
|
// Check if the literal expression is already parenthesized
|
||||||
if parenthesized_range(
|
if parenthesized_range(literal_expr.into(), parent_expr.into(), tokens).is_some() {
|
||||||
literal_expr.into(),
|
|
||||||
parent_expr.into(),
|
|
||||||
comment_ranges,
|
|
||||||
source,
|
|
||||||
)
|
|
||||||
.is_some()
|
|
||||||
{
|
|
||||||
return false; // Already parenthesized, don't add more
|
return false; // Already parenthesized, don't add more
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@ use libcst_native::{
|
||||||
|
|
||||||
use ruff_macros::{ViolationMetadata, derive_message_formats};
|
use ruff_macros::{ViolationMetadata, derive_message_formats};
|
||||||
use ruff_python_ast::helpers::Truthiness;
|
use ruff_python_ast::helpers::Truthiness;
|
||||||
use ruff_python_ast::parenthesize::parenthesized_range;
|
use ruff_python_ast::token::parenthesized_range;
|
||||||
use ruff_python_ast::visitor::Visitor;
|
use ruff_python_ast::visitor::Visitor;
|
||||||
use ruff_python_ast::{
|
use ruff_python_ast::{
|
||||||
self as ast, AnyNodeRef, Arguments, BoolOp, ExceptHandler, Expr, Keyword, Stmt, UnaryOp,
|
self as ast, AnyNodeRef, Arguments, BoolOp, ExceptHandler, Expr, Keyword, Stmt, UnaryOp,
|
||||||
|
|
@ -303,8 +303,7 @@ pub(crate) fn unittest_assertion(
|
||||||
parenthesized_range(
|
parenthesized_range(
|
||||||
expr.into(),
|
expr.into(),
|
||||||
checker.semantic().current_statement().into(),
|
checker.semantic().current_statement().into(),
|
||||||
checker.comment_ranges(),
|
checker.tokens(),
|
||||||
checker.locator().contents(),
|
|
||||||
)
|
)
|
||||||
.unwrap_or(expr.range()),
|
.unwrap_or(expr.range()),
|
||||||
)));
|
)));
|
||||||
|
|
|
||||||
|
|
@ -768,8 +768,8 @@ fn check_fixture_decorator(checker: &Checker, func_name: &str, decorator: &Decor
|
||||||
keyword,
|
keyword,
|
||||||
arguments,
|
arguments,
|
||||||
edits::Parentheses::Preserve,
|
edits::Parentheses::Preserve,
|
||||||
checker.locator().contents(),
|
checker.source(),
|
||||||
checker.comment_ranges(),
|
checker.tokens(),
|
||||||
)
|
)
|
||||||
.map(Fix::unsafe_edit)
|
.map(Fix::unsafe_edit)
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -2,10 +2,9 @@ use rustc_hash::{FxBuildHasher, FxHashMap};
|
||||||
|
|
||||||
use ruff_macros::{ViolationMetadata, derive_message_formats};
|
use ruff_macros::{ViolationMetadata, derive_message_formats};
|
||||||
use ruff_python_ast::comparable::ComparableExpr;
|
use ruff_python_ast::comparable::ComparableExpr;
|
||||||
use ruff_python_ast::parenthesize::parenthesized_range;
|
use ruff_python_ast::token::{Tokens, parenthesized_range};
|
||||||
use ruff_python_ast::{self as ast, Expr, ExprCall, ExprContext, StringLiteralFlags};
|
use ruff_python_ast::{self as ast, Expr, ExprCall, ExprContext, StringLiteralFlags};
|
||||||
use ruff_python_codegen::Generator;
|
use ruff_python_codegen::Generator;
|
||||||
use ruff_python_trivia::CommentRanges;
|
|
||||||
use ruff_python_trivia::{SimpleTokenKind, SimpleTokenizer};
|
use ruff_python_trivia::{SimpleTokenKind, SimpleTokenizer};
|
||||||
use ruff_text_size::{Ranged, TextRange, TextSize};
|
use ruff_text_size::{Ranged, TextRange, TextSize};
|
||||||
|
|
||||||
|
|
@ -322,18 +321,8 @@ fn elts_to_csv(elts: &[Expr], generator: Generator, flags: StringLiteralFlags) -
|
||||||
/// ```
|
/// ```
|
||||||
///
|
///
|
||||||
/// This method assumes that the first argument is a string.
|
/// This method assumes that the first argument is a string.
|
||||||
fn get_parametrize_name_range(
|
fn get_parametrize_name_range(call: &ExprCall, expr: &Expr, tokens: &Tokens) -> Option<TextRange> {
|
||||||
call: &ExprCall,
|
parenthesized_range(expr.into(), (&call.arguments).into(), tokens)
|
||||||
expr: &Expr,
|
|
||||||
comment_ranges: &CommentRanges,
|
|
||||||
source: &str,
|
|
||||||
) -> Option<TextRange> {
|
|
||||||
parenthesized_range(
|
|
||||||
expr.into(),
|
|
||||||
(&call.arguments).into(),
|
|
||||||
comment_ranges,
|
|
||||||
source,
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// PT006
|
/// PT006
|
||||||
|
|
@ -349,13 +338,8 @@ fn check_names(checker: &Checker, call: &ExprCall, expr: &Expr, argvalues: &Expr
|
||||||
if names.len() > 1 {
|
if names.len() > 1 {
|
||||||
match names_type {
|
match names_type {
|
||||||
types::ParametrizeNameType::Tuple => {
|
types::ParametrizeNameType::Tuple => {
|
||||||
let name_range = get_parametrize_name_range(
|
let name_range = get_parametrize_name_range(call, expr, checker.tokens())
|
||||||
call,
|
.unwrap_or(expr.range());
|
||||||
expr,
|
|
||||||
checker.comment_ranges(),
|
|
||||||
checker.locator().contents(),
|
|
||||||
)
|
|
||||||
.unwrap_or(expr.range());
|
|
||||||
let mut diagnostic = checker.report_diagnostic(
|
let mut diagnostic = checker.report_diagnostic(
|
||||||
PytestParametrizeNamesWrongType {
|
PytestParametrizeNamesWrongType {
|
||||||
single_argument: false,
|
single_argument: false,
|
||||||
|
|
@ -386,13 +370,8 @@ fn check_names(checker: &Checker, call: &ExprCall, expr: &Expr, argvalues: &Expr
|
||||||
)));
|
)));
|
||||||
}
|
}
|
||||||
types::ParametrizeNameType::List => {
|
types::ParametrizeNameType::List => {
|
||||||
let name_range = get_parametrize_name_range(
|
let name_range = get_parametrize_name_range(call, expr, checker.tokens())
|
||||||
call,
|
.unwrap_or(expr.range());
|
||||||
expr,
|
|
||||||
checker.comment_ranges(),
|
|
||||||
checker.locator().contents(),
|
|
||||||
)
|
|
||||||
.unwrap_or(expr.range());
|
|
||||||
let mut diagnostic = checker.report_diagnostic(
|
let mut diagnostic = checker.report_diagnostic(
|
||||||
PytestParametrizeNamesWrongType {
|
PytestParametrizeNamesWrongType {
|
||||||
single_argument: false,
|
single_argument: false,
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@ use ruff_macros::{ViolationMetadata, derive_message_formats};
|
||||||
use ruff_python_ast::comparable::ComparableExpr;
|
use ruff_python_ast::comparable::ComparableExpr;
|
||||||
use ruff_python_ast::helpers::{Truthiness, contains_effect};
|
use ruff_python_ast::helpers::{Truthiness, contains_effect};
|
||||||
use ruff_python_ast::name::Name;
|
use ruff_python_ast::name::Name;
|
||||||
use ruff_python_ast::parenthesize::parenthesized_range;
|
use ruff_python_ast::token::parenthesized_range;
|
||||||
use ruff_python_codegen::Generator;
|
use ruff_python_codegen::Generator;
|
||||||
use ruff_python_semantic::SemanticModel;
|
use ruff_python_semantic::SemanticModel;
|
||||||
|
|
||||||
|
|
@ -800,14 +800,9 @@ fn is_short_circuit(
|
||||||
edit = Some(get_short_circuit_edit(
|
edit = Some(get_short_circuit_edit(
|
||||||
value,
|
value,
|
||||||
TextRange::new(
|
TextRange::new(
|
||||||
parenthesized_range(
|
parenthesized_range(furthest.into(), expr.into(), checker.tokens())
|
||||||
furthest.into(),
|
.unwrap_or(furthest.range())
|
||||||
expr.into(),
|
.start(),
|
||||||
checker.comment_ranges(),
|
|
||||||
checker.locator().contents(),
|
|
||||||
)
|
|
||||||
.unwrap_or(furthest.range())
|
|
||||||
.start(),
|
|
||||||
expr.end(),
|
expr.end(),
|
||||||
),
|
),
|
||||||
short_circuit_truthiness,
|
short_circuit_truthiness,
|
||||||
|
|
@ -828,14 +823,9 @@ fn is_short_circuit(
|
||||||
edit = Some(get_short_circuit_edit(
|
edit = Some(get_short_circuit_edit(
|
||||||
next_value,
|
next_value,
|
||||||
TextRange::new(
|
TextRange::new(
|
||||||
parenthesized_range(
|
parenthesized_range(furthest.into(), expr.into(), checker.tokens())
|
||||||
furthest.into(),
|
.unwrap_or(furthest.range())
|
||||||
expr.into(),
|
.start(),
|
||||||
checker.comment_ranges(),
|
|
||||||
checker.locator().contents(),
|
|
||||||
)
|
|
||||||
.unwrap_or(furthest.range())
|
|
||||||
.start(),
|
|
||||||
expr.end(),
|
expr.end(),
|
||||||
),
|
),
|
||||||
short_circuit_truthiness,
|
short_circuit_truthiness,
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ use ruff_text_size::{Ranged, TextRange};
|
||||||
use ruff_macros::{ViolationMetadata, derive_message_formats};
|
use ruff_macros::{ViolationMetadata, derive_message_formats};
|
||||||
use ruff_python_ast::helpers::{is_const_false, is_const_true};
|
use ruff_python_ast::helpers::{is_const_false, is_const_true};
|
||||||
use ruff_python_ast::name::Name;
|
use ruff_python_ast::name::Name;
|
||||||
use ruff_python_ast::parenthesize::parenthesized_range;
|
use ruff_python_ast::token::parenthesized_range;
|
||||||
|
|
||||||
use crate::checkers::ast::Checker;
|
use crate::checkers::ast::Checker;
|
||||||
use crate::{AlwaysFixableViolation, Edit, Fix, FixAvailability, Violation};
|
use crate::{AlwaysFixableViolation, Edit, Fix, FixAvailability, Violation};
|
||||||
|
|
@ -171,13 +171,8 @@ pub(crate) fn if_expr_with_true_false(
|
||||||
checker
|
checker
|
||||||
.locator()
|
.locator()
|
||||||
.slice(
|
.slice(
|
||||||
parenthesized_range(
|
parenthesized_range(test.into(), expr.into(), checker.tokens())
|
||||||
test.into(),
|
.unwrap_or(test.range()),
|
||||||
expr.into(),
|
|
||||||
checker.comment_ranges(),
|
|
||||||
checker.locator().contents(),
|
|
||||||
)
|
|
||||||
.unwrap_or(test.range()),
|
|
||||||
)
|
)
|
||||||
.to_string(),
|
.to_string(),
|
||||||
expr.range(),
|
expr.range(),
|
||||||
|
|
|
||||||
|
|
@ -4,10 +4,10 @@ use anyhow::Result;
|
||||||
|
|
||||||
use ruff_macros::{ViolationMetadata, derive_message_formats};
|
use ruff_macros::{ViolationMetadata, derive_message_formats};
|
||||||
use ruff_python_ast::comparable::ComparableStmt;
|
use ruff_python_ast::comparable::ComparableStmt;
|
||||||
use ruff_python_ast::parenthesize::parenthesized_range;
|
|
||||||
use ruff_python_ast::stmt_if::{IfElifBranch, if_elif_branches};
|
use ruff_python_ast::stmt_if::{IfElifBranch, if_elif_branches};
|
||||||
|
use ruff_python_ast::token::parenthesized_range;
|
||||||
use ruff_python_ast::{self as ast, Expr};
|
use ruff_python_ast::{self as ast, Expr};
|
||||||
use ruff_python_trivia::{CommentRanges, SimpleTokenKind, SimpleTokenizer};
|
use ruff_python_trivia::{SimpleTokenKind, SimpleTokenizer};
|
||||||
use ruff_source_file::LineRanges;
|
use ruff_source_file::LineRanges;
|
||||||
use ruff_text_size::{Ranged, TextRange};
|
use ruff_text_size::{Ranged, TextRange};
|
||||||
|
|
||||||
|
|
@ -99,7 +99,7 @@ pub(crate) fn if_with_same_arms(checker: &Checker, stmt_if: &ast::StmtIf) {
|
||||||
¤t_branch,
|
¤t_branch,
|
||||||
following_branch,
|
following_branch,
|
||||||
checker.locator(),
|
checker.locator(),
|
||||||
checker.comment_ranges(),
|
checker.tokens(),
|
||||||
)
|
)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
@ -111,7 +111,7 @@ fn merge_branches(
|
||||||
current_branch: &IfElifBranch,
|
current_branch: &IfElifBranch,
|
||||||
following_branch: &IfElifBranch,
|
following_branch: &IfElifBranch,
|
||||||
locator: &Locator,
|
locator: &Locator,
|
||||||
comment_ranges: &CommentRanges,
|
tokens: &ruff_python_ast::token::Tokens,
|
||||||
) -> Result<Fix> {
|
) -> Result<Fix> {
|
||||||
// Identify the colon (`:`) at the end of the current branch's test.
|
// Identify the colon (`:`) at the end of the current branch's test.
|
||||||
let Some(current_branch_colon) =
|
let Some(current_branch_colon) =
|
||||||
|
|
@ -127,12 +127,9 @@ fn merge_branches(
|
||||||
);
|
);
|
||||||
|
|
||||||
// If the following test isn't parenthesized, consider parenthesizing it.
|
// If the following test isn't parenthesized, consider parenthesizing it.
|
||||||
let following_branch_test = if let Some(range) = parenthesized_range(
|
let following_branch_test = if let Some(range) =
|
||||||
following_branch.test.into(),
|
parenthesized_range(following_branch.test.into(), stmt_if.into(), tokens)
|
||||||
stmt_if.into(),
|
{
|
||||||
comment_ranges,
|
|
||||||
locator.contents(),
|
|
||||||
) {
|
|
||||||
Cow::Borrowed(locator.slice(range))
|
Cow::Borrowed(locator.slice(range))
|
||||||
} else if matches!(
|
} else if matches!(
|
||||||
following_branch.test,
|
following_branch.test,
|
||||||
|
|
@ -153,24 +150,19 @@ fn merge_branches(
|
||||||
//
|
//
|
||||||
// For example, if the current test is `x if x else y`, we should parenthesize it to
|
// For example, if the current test is `x if x else y`, we should parenthesize it to
|
||||||
// `(x if x else y) or ...`.
|
// `(x if x else y) or ...`.
|
||||||
let parenthesize_edit = if matches!(
|
let parenthesize_edit =
|
||||||
current_branch.test,
|
if matches!(
|
||||||
Expr::Lambda(_) | Expr::Named(_) | Expr::If(_)
|
current_branch.test,
|
||||||
) && parenthesized_range(
|
Expr::Lambda(_) | Expr::Named(_) | Expr::If(_)
|
||||||
current_branch.test.into(),
|
) && parenthesized_range(current_branch.test.into(), stmt_if.into(), tokens).is_none()
|
||||||
stmt_if.into(),
|
{
|
||||||
comment_ranges,
|
Some(Edit::range_replacement(
|
||||||
locator.contents(),
|
format!("({})", locator.slice(current_branch.test)),
|
||||||
)
|
current_branch.test.range(),
|
||||||
.is_none()
|
))
|
||||||
{
|
} else {
|
||||||
Some(Edit::range_replacement(
|
None
|
||||||
format!("({})", locator.slice(current_branch.test)),
|
};
|
||||||
current_branch.test.range(),
|
|
||||||
))
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
};
|
|
||||||
|
|
||||||
Ok(Fix::safe_edits(
|
Ok(Fix::safe_edits(
|
||||||
deletion_edit,
|
deletion_edit,
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
use ruff_macros::{ViolationMetadata, derive_message_formats};
|
use ruff_macros::{ViolationMetadata, derive_message_formats};
|
||||||
use ruff_python_ast::AnyNodeRef;
|
use ruff_python_ast::AnyNodeRef;
|
||||||
use ruff_python_ast::parenthesize::parenthesized_range;
|
use ruff_python_ast::token::parenthesized_range;
|
||||||
use ruff_python_ast::{self as ast, Arguments, CmpOp, Comprehension, Expr};
|
use ruff_python_ast::{self as ast, Arguments, CmpOp, Comprehension, Expr};
|
||||||
use ruff_python_semantic::analyze::typing;
|
use ruff_python_semantic::analyze::typing;
|
||||||
use ruff_python_trivia::{SimpleTokenKind, SimpleTokenizer};
|
use ruff_python_trivia::{SimpleTokenKind, SimpleTokenizer};
|
||||||
|
|
@ -90,20 +90,10 @@ fn key_in_dict(checker: &Checker, left: &Expr, right: &Expr, operator: CmpOp, pa
|
||||||
}
|
}
|
||||||
|
|
||||||
// Extract the exact range of the left and right expressions.
|
// Extract the exact range of the left and right expressions.
|
||||||
let left_range = parenthesized_range(
|
let left_range =
|
||||||
left.into(),
|
parenthesized_range(left.into(), parent, checker.tokens()).unwrap_or(left.range());
|
||||||
parent,
|
let right_range =
|
||||||
checker.comment_ranges(),
|
parenthesized_range(right.into(), parent, checker.tokens()).unwrap_or(right.range());
|
||||||
checker.locator().contents(),
|
|
||||||
)
|
|
||||||
.unwrap_or(left.range());
|
|
||||||
let right_range = parenthesized_range(
|
|
||||||
right.into(),
|
|
||||||
parent,
|
|
||||||
checker.comment_ranges(),
|
|
||||||
checker.locator().contents(),
|
|
||||||
)
|
|
||||||
.unwrap_or(right.range());
|
|
||||||
|
|
||||||
let mut diagnostic = checker.report_diagnostic(
|
let mut diagnostic = checker.report_diagnostic(
|
||||||
InDictKeys {
|
InDictKeys {
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@ use crate::registry::Rule;
|
||||||
use crate::rules::flake8_type_checking::helpers::quote_type_expression;
|
use crate::rules::flake8_type_checking::helpers::quote_type_expression;
|
||||||
use crate::{AlwaysFixableViolation, Edit, Fix, FixAvailability, Violation};
|
use crate::{AlwaysFixableViolation, Edit, Fix, FixAvailability, Violation};
|
||||||
use ruff_python_ast::PythonVersion;
|
use ruff_python_ast::PythonVersion;
|
||||||
use ruff_python_ast::parenthesize::parenthesized_range;
|
use ruff_python_ast::token::parenthesized_range;
|
||||||
|
|
||||||
/// ## What it does
|
/// ## What it does
|
||||||
/// Checks if [PEP 613] explicit type aliases contain references to
|
/// Checks if [PEP 613] explicit type aliases contain references to
|
||||||
|
|
@ -295,21 +295,20 @@ pub(crate) fn quoted_type_alias(
|
||||||
let range = annotation_expr.range();
|
let range = annotation_expr.range();
|
||||||
let mut diagnostic = checker.report_diagnostic(QuotedTypeAlias, range);
|
let mut diagnostic = checker.report_diagnostic(QuotedTypeAlias, range);
|
||||||
let fix_string = annotation_expr.value.to_string();
|
let fix_string = annotation_expr.value.to_string();
|
||||||
|
|
||||||
let fix_string = if (fix_string.contains('\n') || fix_string.contains('\r'))
|
let fix_string = if (fix_string.contains('\n') || fix_string.contains('\r'))
|
||||||
&& parenthesized_range(
|
&& parenthesized_range(
|
||||||
// Check for parenthesis outside string ("""...""")
|
// Check for parentheses outside the string ("""...""")
|
||||||
annotation_expr.into(),
|
annotation_expr.into(),
|
||||||
checker.semantic().current_statement().into(),
|
checker.semantic().current_statement().into(),
|
||||||
checker.comment_ranges(),
|
checker.source_tokens(),
|
||||||
checker.locator().contents(),
|
|
||||||
)
|
)
|
||||||
.is_none()
|
.is_none()
|
||||||
&& parenthesized_range(
|
&& parenthesized_range(
|
||||||
// Check for parenthesis inside string """(...)"""
|
// Check for parentheses inside the string """(...)"""
|
||||||
expr.into(),
|
expr.into(),
|
||||||
annotation_expr.into(),
|
annotation_expr.into(),
|
||||||
checker.comment_ranges(),
|
checker.tokens(),
|
||||||
checker.locator().contents(),
|
|
||||||
)
|
)
|
||||||
.is_none()
|
.is_none()
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,9 @@
|
||||||
use std::ops::Range;
|
use std::ops::Range;
|
||||||
|
|
||||||
use ruff_macros::{ViolationMetadata, derive_message_formats};
|
use ruff_macros::{ViolationMetadata, derive_message_formats};
|
||||||
use ruff_python_ast::parenthesize::parenthesized_range;
|
use ruff_python_ast::token::parenthesized_range;
|
||||||
use ruff_python_ast::{Expr, ExprBinOp, ExprCall, Operator};
|
use ruff_python_ast::{Expr, ExprBinOp, ExprCall, Operator};
|
||||||
use ruff_python_semantic::SemanticModel;
|
use ruff_python_semantic::SemanticModel;
|
||||||
use ruff_python_trivia::CommentRanges;
|
|
||||||
use ruff_text_size::{Ranged, TextRange};
|
use ruff_text_size::{Ranged, TextRange};
|
||||||
|
|
||||||
use crate::checkers::ast::Checker;
|
use crate::checkers::ast::Checker;
|
||||||
|
|
@ -89,11 +88,7 @@ pub(crate) fn path_constructor_current_directory(
|
||||||
|
|
||||||
let mut diagnostic = checker.report_diagnostic(PathConstructorCurrentDirectory, arg.range());
|
let mut diagnostic = checker.report_diagnostic(PathConstructorCurrentDirectory, arg.range());
|
||||||
|
|
||||||
match parent_and_next_path_fragment_range(
|
match parent_and_next_path_fragment_range(checker.semantic(), checker.tokens()) {
|
||||||
checker.semantic(),
|
|
||||||
checker.comment_ranges(),
|
|
||||||
checker.source(),
|
|
||||||
) {
|
|
||||||
Some((parent_range, next_fragment_range)) => {
|
Some((parent_range, next_fragment_range)) => {
|
||||||
let next_fragment_expr = checker.locator().slice(next_fragment_range);
|
let next_fragment_expr = checker.locator().slice(next_fragment_range);
|
||||||
let call_expr = checker.locator().slice(call.range());
|
let call_expr = checker.locator().slice(call.range());
|
||||||
|
|
@ -116,7 +111,7 @@ pub(crate) fn path_constructor_current_directory(
|
||||||
arguments,
|
arguments,
|
||||||
Parentheses::Preserve,
|
Parentheses::Preserve,
|
||||||
checker.source(),
|
checker.source(),
|
||||||
checker.comment_ranges(),
|
checker.tokens(),
|
||||||
)?;
|
)?;
|
||||||
Ok(Fix::applicable_edit(edit, applicability(call.range())))
|
Ok(Fix::applicable_edit(edit, applicability(call.range())))
|
||||||
}),
|
}),
|
||||||
|
|
@ -125,8 +120,7 @@ pub(crate) fn path_constructor_current_directory(
|
||||||
|
|
||||||
fn parent_and_next_path_fragment_range(
|
fn parent_and_next_path_fragment_range(
|
||||||
semantic: &SemanticModel,
|
semantic: &SemanticModel,
|
||||||
comment_ranges: &CommentRanges,
|
tokens: &ruff_python_ast::token::Tokens,
|
||||||
source: &str,
|
|
||||||
) -> Option<(TextRange, TextRange)> {
|
) -> Option<(TextRange, TextRange)> {
|
||||||
let parent = semantic.current_expression_parent()?;
|
let parent = semantic.current_expression_parent()?;
|
||||||
|
|
||||||
|
|
@ -142,6 +136,6 @@ fn parent_and_next_path_fragment_range(
|
||||||
|
|
||||||
Some((
|
Some((
|
||||||
parent.range(),
|
parent.range(),
|
||||||
parenthesized_range(right.into(), parent.into(), comment_ranges, source).unwrap_or(range),
|
parenthesized_range(right.into(), parent.into(), tokens).unwrap_or(range),
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,7 @@
|
||||||
use ruff_macros::{ViolationMetadata, derive_message_formats};
|
use ruff_macros::{ViolationMetadata, derive_message_formats};
|
||||||
use ruff_python_ast::helpers::is_const_true;
|
use ruff_python_ast::helpers::is_const_true;
|
||||||
use ruff_python_ast::parenthesize::parenthesized_range;
|
use ruff_python_ast::token::{Tokens, parenthesized_range};
|
||||||
use ruff_python_ast::{self as ast, Keyword, Stmt};
|
use ruff_python_ast::{self as ast, Keyword, Stmt};
|
||||||
use ruff_python_trivia::CommentRanges;
|
|
||||||
use ruff_text_size::Ranged;
|
use ruff_text_size::Ranged;
|
||||||
|
|
||||||
use crate::Locator;
|
use crate::Locator;
|
||||||
|
|
@ -91,7 +90,7 @@ pub(crate) fn inplace_argument(checker: &Checker, call: &ast::ExprCall) {
|
||||||
call,
|
call,
|
||||||
keyword,
|
keyword,
|
||||||
statement,
|
statement,
|
||||||
checker.comment_ranges(),
|
checker.tokens(),
|
||||||
checker.locator(),
|
checker.locator(),
|
||||||
) {
|
) {
|
||||||
diagnostic.set_fix(fix);
|
diagnostic.set_fix(fix);
|
||||||
|
|
@ -111,21 +110,16 @@ fn convert_inplace_argument_to_assignment(
|
||||||
call: &ast::ExprCall,
|
call: &ast::ExprCall,
|
||||||
keyword: &Keyword,
|
keyword: &Keyword,
|
||||||
statement: &Stmt,
|
statement: &Stmt,
|
||||||
comment_ranges: &CommentRanges,
|
tokens: &Tokens,
|
||||||
locator: &Locator,
|
locator: &Locator,
|
||||||
) -> Option<Fix> {
|
) -> Option<Fix> {
|
||||||
// Add the assignment.
|
// Add the assignment.
|
||||||
let attr = call.func.as_attribute_expr()?;
|
let attr = call.func.as_attribute_expr()?;
|
||||||
let insert_assignment = Edit::insertion(
|
let insert_assignment = Edit::insertion(
|
||||||
format!("{name} = ", name = locator.slice(attr.value.range())),
|
format!("{name} = ", name = locator.slice(attr.value.range())),
|
||||||
parenthesized_range(
|
parenthesized_range(call.into(), statement.into(), tokens)
|
||||||
call.into(),
|
.unwrap_or(call.range())
|
||||||
statement.into(),
|
.start(),
|
||||||
comment_ranges,
|
|
||||||
locator.contents(),
|
|
||||||
)
|
|
||||||
.unwrap_or(call.range())
|
|
||||||
.start(),
|
|
||||||
);
|
);
|
||||||
|
|
||||||
// Remove the `inplace` argument.
|
// Remove the `inplace` argument.
|
||||||
|
|
@ -134,7 +128,7 @@ fn convert_inplace_argument_to_assignment(
|
||||||
&call.arguments,
|
&call.arguments,
|
||||||
Parentheses::Preserve,
|
Parentheses::Preserve,
|
||||||
locator.contents(),
|
locator.contents(),
|
||||||
comment_ranges,
|
tokens,
|
||||||
)
|
)
|
||||||
.ok()?;
|
.ok()?;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
use ruff_macros::{ViolationMetadata, derive_message_formats};
|
use ruff_macros::{ViolationMetadata, derive_message_formats};
|
||||||
use ruff_python_ast::parenthesize::parenthesized_range;
|
use ruff_python_ast::token::parenthesized_range;
|
||||||
use ruff_python_ast::{
|
use ruff_python_ast::{
|
||||||
self as ast, Expr, ExprEllipsisLiteral, ExprLambda, Identifier, Parameter,
|
self as ast, Expr, ExprEllipsisLiteral, ExprLambda, Identifier, Parameter,
|
||||||
ParameterWithDefault, Parameters, Stmt,
|
ParameterWithDefault, Parameters, Stmt,
|
||||||
|
|
@ -265,29 +265,19 @@ fn replace_trailing_ellipsis_with_original_expr(
|
||||||
stmt: &Stmt,
|
stmt: &Stmt,
|
||||||
checker: &Checker,
|
checker: &Checker,
|
||||||
) -> String {
|
) -> String {
|
||||||
let original_expr_range = parenthesized_range(
|
let original_expr_range =
|
||||||
(&lambda.body).into(),
|
parenthesized_range((&lambda.body).into(), lambda.into(), checker.tokens())
|
||||||
lambda.into(),
|
.unwrap_or(lambda.body.range());
|
||||||
checker.comment_ranges(),
|
|
||||||
checker.source(),
|
|
||||||
)
|
|
||||||
.unwrap_or(lambda.body.range());
|
|
||||||
|
|
||||||
// This prevents the autofix of introducing a syntax error if the lambda's body is an
|
// This prevents the autofix of introducing a syntax error if the lambda's body is an
|
||||||
// expression spanned across multiple lines. To avoid the syntax error we preserve
|
// expression spanned across multiple lines. To avoid the syntax error we preserve
|
||||||
// the parenthesis around the body.
|
// the parenthesis around the body.
|
||||||
let original_expr_in_source = if parenthesized_range(
|
let original_expr_in_source =
|
||||||
lambda.into(),
|
if parenthesized_range(lambda.into(), stmt.into(), checker.tokens()).is_some() {
|
||||||
stmt.into(),
|
format!("({})", checker.locator().slice(original_expr_range))
|
||||||
checker.comment_ranges(),
|
} else {
|
||||||
checker.source(),
|
checker.locator().slice(original_expr_range).to_string()
|
||||||
)
|
};
|
||||||
.is_some()
|
|
||||||
{
|
|
||||||
format!("({})", checker.locator().slice(original_expr_range))
|
|
||||||
} else {
|
|
||||||
checker.locator().slice(original_expr_range).to_string()
|
|
||||||
};
|
|
||||||
|
|
||||||
let placeholder_ellipsis_start = generated.rfind("...").unwrap();
|
let placeholder_ellipsis_start = generated.rfind("...").unwrap();
|
||||||
let placeholder_ellipsis_end = placeholder_ellipsis_start + "...".len();
|
let placeholder_ellipsis_end = placeholder_ellipsis_start + "...".len();
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
use ruff_python_ast::parenthesize::parenthesized_range;
|
use ruff_python_ast::token::{Tokens, parenthesized_range};
|
||||||
use rustc_hash::FxHashMap;
|
use rustc_hash::FxHashMap;
|
||||||
|
|
||||||
use ruff_macros::{ViolationMetadata, derive_message_formats};
|
use ruff_macros::{ViolationMetadata, derive_message_formats};
|
||||||
|
|
@ -179,15 +179,14 @@ fn is_redundant_boolean_comparison(op: CmpOp, comparator: &Expr) -> Option<bool>
|
||||||
|
|
||||||
fn generate_redundant_comparison(
|
fn generate_redundant_comparison(
|
||||||
compare: &ast::ExprCompare,
|
compare: &ast::ExprCompare,
|
||||||
comment_ranges: &ruff_python_trivia::CommentRanges,
|
tokens: &Tokens,
|
||||||
source: &str,
|
source: &str,
|
||||||
comparator: &Expr,
|
comparator: &Expr,
|
||||||
kind: bool,
|
kind: bool,
|
||||||
needs_wrap: bool,
|
needs_wrap: bool,
|
||||||
) -> String {
|
) -> String {
|
||||||
let comparator_range =
|
let comparator_range = parenthesized_range(comparator.into(), compare.into(), tokens)
|
||||||
parenthesized_range(comparator.into(), compare.into(), comment_ranges, source)
|
.unwrap_or(comparator.range());
|
||||||
.unwrap_or(comparator.range());
|
|
||||||
|
|
||||||
let comparator_str = &source[comparator_range];
|
let comparator_str = &source[comparator_range];
|
||||||
|
|
||||||
|
|
@ -379,7 +378,7 @@ pub(crate) fn literal_comparisons(checker: &Checker, compare: &ast::ExprCompare)
|
||||||
.copied()
|
.copied()
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
let comment_ranges = checker.comment_ranges();
|
let tokens = checker.tokens();
|
||||||
let source = checker.source();
|
let source = checker.source();
|
||||||
|
|
||||||
let content = match (&*compare.ops, &*compare.comparators) {
|
let content = match (&*compare.ops, &*compare.comparators) {
|
||||||
|
|
@ -387,18 +386,13 @@ pub(crate) fn literal_comparisons(checker: &Checker, compare: &ast::ExprCompare)
|
||||||
if let Some(kind) = is_redundant_boolean_comparison(*op, &compare.left) {
|
if let Some(kind) = is_redundant_boolean_comparison(*op, &compare.left) {
|
||||||
let needs_wrap = compare.left.range().start() != compare.range().start();
|
let needs_wrap = compare.left.range().start() != compare.range().start();
|
||||||
generate_redundant_comparison(
|
generate_redundant_comparison(
|
||||||
compare,
|
compare, tokens, source, comparator, kind, needs_wrap,
|
||||||
comment_ranges,
|
|
||||||
source,
|
|
||||||
comparator,
|
|
||||||
kind,
|
|
||||||
needs_wrap,
|
|
||||||
)
|
)
|
||||||
} else if let Some(kind) = is_redundant_boolean_comparison(*op, comparator) {
|
} else if let Some(kind) = is_redundant_boolean_comparison(*op, comparator) {
|
||||||
let needs_wrap = comparator.range().end() != compare.range().end();
|
let needs_wrap = comparator.range().end() != compare.range().end();
|
||||||
generate_redundant_comparison(
|
generate_redundant_comparison(
|
||||||
compare,
|
compare,
|
||||||
comment_ranges,
|
tokens,
|
||||||
source,
|
source,
|
||||||
&compare.left,
|
&compare.left,
|
||||||
kind,
|
kind,
|
||||||
|
|
@ -410,7 +404,7 @@ pub(crate) fn literal_comparisons(checker: &Checker, compare: &ast::ExprCompare)
|
||||||
&ops,
|
&ops,
|
||||||
&compare.comparators,
|
&compare.comparators,
|
||||||
compare.into(),
|
compare.into(),
|
||||||
comment_ranges,
|
tokens,
|
||||||
source,
|
source,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
@ -420,7 +414,7 @@ pub(crate) fn literal_comparisons(checker: &Checker, compare: &ast::ExprCompare)
|
||||||
&ops,
|
&ops,
|
||||||
&compare.comparators,
|
&compare.comparators,
|
||||||
compare.into(),
|
compare.into(),
|
||||||
comment_ranges,
|
tokens,
|
||||||
source,
|
source,
|
||||||
),
|
),
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -107,7 +107,7 @@ pub(crate) fn not_tests(checker: &Checker, unary_op: &ast::ExprUnaryOp) {
|
||||||
&[CmpOp::NotIn],
|
&[CmpOp::NotIn],
|
||||||
comparators,
|
comparators,
|
||||||
unary_op.into(),
|
unary_op.into(),
|
||||||
checker.comment_ranges(),
|
checker.tokens(),
|
||||||
checker.source(),
|
checker.source(),
|
||||||
),
|
),
|
||||||
unary_op.range(),
|
unary_op.range(),
|
||||||
|
|
@ -127,7 +127,7 @@ pub(crate) fn not_tests(checker: &Checker, unary_op: &ast::ExprUnaryOp) {
|
||||||
&[CmpOp::IsNot],
|
&[CmpOp::IsNot],
|
||||||
comparators,
|
comparators,
|
||||||
unary_op.into(),
|
unary_op.into(),
|
||||||
checker.comment_ranges(),
|
checker.tokens(),
|
||||||
checker.source(),
|
checker.source(),
|
||||||
),
|
),
|
||||||
unary_op.range(),
|
unary_op.range(),
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@ use std::collections::hash_map::Entry;
|
||||||
|
|
||||||
use ruff_macros::{ViolationMetadata, derive_message_formats};
|
use ruff_macros::{ViolationMetadata, derive_message_formats};
|
||||||
use ruff_python_ast::comparable::{ComparableExpr, HashableExpr};
|
use ruff_python_ast::comparable::{ComparableExpr, HashableExpr};
|
||||||
use ruff_python_ast::parenthesize::parenthesized_range;
|
use ruff_python_ast::token::parenthesized_range;
|
||||||
use ruff_python_ast::{self as ast, Expr};
|
use ruff_python_ast::{self as ast, Expr};
|
||||||
use ruff_text_size::Ranged;
|
use ruff_text_size::Ranged;
|
||||||
|
|
||||||
|
|
@ -193,16 +193,14 @@ pub(crate) fn repeated_keys(checker: &Checker, dict: &ast::ExprDict) {
|
||||||
parenthesized_range(
|
parenthesized_range(
|
||||||
dict.value(i - 1).into(),
|
dict.value(i - 1).into(),
|
||||||
dict.into(),
|
dict.into(),
|
||||||
checker.comment_ranges(),
|
checker.tokens(),
|
||||||
checker.locator().contents(),
|
|
||||||
)
|
)
|
||||||
.unwrap_or_else(|| dict.value(i - 1).range())
|
.unwrap_or_else(|| dict.value(i - 1).range())
|
||||||
.end(),
|
.end(),
|
||||||
parenthesized_range(
|
parenthesized_range(
|
||||||
dict.value(i).into(),
|
dict.value(i).into(),
|
||||||
dict.into(),
|
dict.into(),
|
||||||
checker.comment_ranges(),
|
checker.tokens(),
|
||||||
checker.locator().contents(),
|
|
||||||
)
|
)
|
||||||
.unwrap_or_else(|| dict.value(i).range())
|
.unwrap_or_else(|| dict.value(i).range())
|
||||||
.end(),
|
.end(),
|
||||||
|
|
@ -224,16 +222,14 @@ pub(crate) fn repeated_keys(checker: &Checker, dict: &ast::ExprDict) {
|
||||||
parenthesized_range(
|
parenthesized_range(
|
||||||
dict.value(i - 1).into(),
|
dict.value(i - 1).into(),
|
||||||
dict.into(),
|
dict.into(),
|
||||||
checker.comment_ranges(),
|
checker.tokens(),
|
||||||
checker.locator().contents(),
|
|
||||||
)
|
)
|
||||||
.unwrap_or_else(|| dict.value(i - 1).range())
|
.unwrap_or_else(|| dict.value(i - 1).range())
|
||||||
.end(),
|
.end(),
|
||||||
parenthesized_range(
|
parenthesized_range(
|
||||||
dict.value(i).into(),
|
dict.value(i).into(),
|
||||||
dict.into(),
|
dict.into(),
|
||||||
checker.comment_ranges(),
|
checker.tokens(),
|
||||||
checker.locator().contents(),
|
|
||||||
)
|
)
|
||||||
.unwrap_or_else(|| dict.value(i).range())
|
.unwrap_or_else(|| dict.value(i).range())
|
||||||
.end(),
|
.end(),
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ use itertools::Itertools;
|
||||||
|
|
||||||
use ruff_macros::{ViolationMetadata, derive_message_formats};
|
use ruff_macros::{ViolationMetadata, derive_message_formats};
|
||||||
use ruff_python_ast::helpers::contains_effect;
|
use ruff_python_ast::helpers::contains_effect;
|
||||||
use ruff_python_ast::parenthesize::parenthesized_range;
|
use ruff_python_ast::token::parenthesized_range;
|
||||||
use ruff_python_ast::token::{TokenKind, Tokens};
|
use ruff_python_ast::token::{TokenKind, Tokens};
|
||||||
use ruff_python_ast::{self as ast, Stmt};
|
use ruff_python_ast::{self as ast, Stmt};
|
||||||
use ruff_python_semantic::Binding;
|
use ruff_python_semantic::Binding;
|
||||||
|
|
@ -172,14 +172,10 @@ fn remove_unused_variable(binding: &Binding, checker: &Checker) -> Option<Fix> {
|
||||||
{
|
{
|
||||||
// If the expression is complex (`x = foo()`), remove the assignment,
|
// If the expression is complex (`x = foo()`), remove the assignment,
|
||||||
// but preserve the right-hand side.
|
// but preserve the right-hand side.
|
||||||
let start = parenthesized_range(
|
let start =
|
||||||
target.into(),
|
parenthesized_range(target.into(), statement.into(), checker.tokens())
|
||||||
statement.into(),
|
.unwrap_or(target.range())
|
||||||
checker.comment_ranges(),
|
.start();
|
||||||
checker.locator().contents(),
|
|
||||||
)
|
|
||||||
.unwrap_or(target.range())
|
|
||||||
.start();
|
|
||||||
let end = match_token_after(checker.tokens(), target.end(), |token| {
|
let end = match_token_after(checker.tokens(), target.end(), |token| {
|
||||||
token == TokenKind::Equal
|
token == TokenKind::Equal
|
||||||
})?
|
})?
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ use itertools::Itertools;
|
||||||
use ruff_macros::{ViolationMetadata, derive_message_formats};
|
use ruff_macros::{ViolationMetadata, derive_message_formats};
|
||||||
use ruff_python_ast::{
|
use ruff_python_ast::{
|
||||||
BoolOp, CmpOp, Expr, ExprBoolOp, ExprCompare,
|
BoolOp, CmpOp, Expr, ExprBoolOp, ExprCompare,
|
||||||
parenthesize::{parentheses_iterator, parenthesized_range},
|
token::{parentheses_iterator, parenthesized_range},
|
||||||
};
|
};
|
||||||
use ruff_text_size::{Ranged, TextRange};
|
use ruff_text_size::{Ranged, TextRange};
|
||||||
|
|
||||||
|
|
@ -62,7 +62,7 @@ pub(crate) fn boolean_chained_comparison(checker: &Checker, expr_bool_op: &ExprB
|
||||||
}
|
}
|
||||||
|
|
||||||
let locator = checker.locator();
|
let locator = checker.locator();
|
||||||
let comment_ranges = checker.comment_ranges();
|
let tokens = checker.tokens();
|
||||||
|
|
||||||
// retrieve all compare expressions from boolean expression
|
// retrieve all compare expressions from boolean expression
|
||||||
let compare_expressions = expr_bool_op
|
let compare_expressions = expr_bool_op
|
||||||
|
|
@ -89,40 +89,22 @@ pub(crate) fn boolean_chained_comparison(checker: &Checker, expr_bool_op: &ExprB
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
let left_paren_count = parentheses_iterator(
|
let left_paren_count =
|
||||||
left_compare.into(),
|
parentheses_iterator(left_compare.into(), Some(expr_bool_op.into()), tokens).count();
|
||||||
Some(expr_bool_op.into()),
|
|
||||||
comment_ranges,
|
|
||||||
locator.contents(),
|
|
||||||
)
|
|
||||||
.count();
|
|
||||||
|
|
||||||
let right_paren_count = parentheses_iterator(
|
let right_paren_count =
|
||||||
right_compare.into(),
|
parentheses_iterator(right_compare.into(), Some(expr_bool_op.into()), tokens).count();
|
||||||
Some(expr_bool_op.into()),
|
|
||||||
comment_ranges,
|
|
||||||
locator.contents(),
|
|
||||||
)
|
|
||||||
.count();
|
|
||||||
|
|
||||||
// Create the edit that removes the comparison operator
|
// Create the edit that removes the comparison operator
|
||||||
|
|
||||||
// In `a<(b) and ((b))<c`, we need to handle the
|
// In `a<(b) and ((b))<c`, we need to handle the
|
||||||
// parentheses when specifying the fix range.
|
// parentheses when specifying the fix range.
|
||||||
let left_compare_right_range = parenthesized_range(
|
let left_compare_right_range =
|
||||||
left_compare_right.into(),
|
parenthesized_range(left_compare_right.into(), left_compare.into(), tokens)
|
||||||
left_compare.into(),
|
.unwrap_or(left_compare_right.range());
|
||||||
comment_ranges,
|
let right_compare_left_range =
|
||||||
locator.contents(),
|
parenthesized_range(right_compare_left.into(), right_compare.into(), tokens)
|
||||||
)
|
.unwrap_or(right_compare_left.range());
|
||||||
.unwrap_or(left_compare_right.range());
|
|
||||||
let right_compare_left_range = parenthesized_range(
|
|
||||||
right_compare_left.into(),
|
|
||||||
right_compare.into(),
|
|
||||||
comment_ranges,
|
|
||||||
locator.contents(),
|
|
||||||
)
|
|
||||||
.unwrap_or(right_compare_left.range());
|
|
||||||
let edit = Edit::range_replacement(
|
let edit = Edit::range_replacement(
|
||||||
locator.slice(left_compare_right_range).to_string(),
|
locator.slice(left_compare_right_range).to_string(),
|
||||||
TextRange::new(
|
TextRange::new(
|
||||||
|
|
|
||||||
|
|
@ -99,7 +99,7 @@ pub(crate) fn duplicate_bases(checker: &Checker, name: &str, arguments: Option<&
|
||||||
arguments,
|
arguments,
|
||||||
Parentheses::Remove,
|
Parentheses::Remove,
|
||||||
checker.locator().contents(),
|
checker.locator().contents(),
|
||||||
checker.comment_ranges(),
|
checker.tokens(),
|
||||||
)
|
)
|
||||||
.map(|edit| {
|
.map(|edit| {
|
||||||
Fix::applicable_edit(
|
Fix::applicable_edit(
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
use ruff_macros::{ViolationMetadata, derive_message_formats};
|
use ruff_macros::{ViolationMetadata, derive_message_formats};
|
||||||
use ruff_python_ast::comparable::ComparableExpr;
|
use ruff_python_ast::comparable::ComparableExpr;
|
||||||
use ruff_python_ast::parenthesize::parenthesized_range;
|
use ruff_python_ast::token::parenthesized_range;
|
||||||
use ruff_python_ast::{self as ast, CmpOp, Stmt};
|
use ruff_python_ast::{self as ast, CmpOp, Stmt};
|
||||||
use ruff_text_size::Ranged;
|
use ruff_text_size::Ranged;
|
||||||
|
|
||||||
|
|
@ -166,13 +166,8 @@ pub(crate) fn if_stmt_min_max(checker: &Checker, stmt_if: &ast::StmtIf) {
|
||||||
let replacement = format!(
|
let replacement = format!(
|
||||||
"{} = {min_max}({}, {})",
|
"{} = {min_max}({}, {})",
|
||||||
checker.locator().slice(
|
checker.locator().slice(
|
||||||
parenthesized_range(
|
parenthesized_range(body_target.into(), body.into(), checker.tokens())
|
||||||
body_target.into(),
|
.unwrap_or(body_target.range())
|
||||||
body.into(),
|
|
||||||
checker.comment_ranges(),
|
|
||||||
checker.locator().contents()
|
|
||||||
)
|
|
||||||
.unwrap_or(body_target.range())
|
|
||||||
),
|
),
|
||||||
checker.locator().slice(arg1),
|
checker.locator().slice(arg1),
|
||||||
checker.locator().slice(arg2),
|
checker.locator().slice(arg2),
|
||||||
|
|
|
||||||
|
|
@ -174,12 +174,8 @@ pub(crate) fn missing_maxsplit_arg(checker: &Checker, value: &Expr, slice: &Expr
|
||||||
SliceBoundary::Last => "rsplit",
|
SliceBoundary::Last => "rsplit",
|
||||||
};
|
};
|
||||||
|
|
||||||
let maxsplit_argument_edit = fix::edits::add_argument(
|
let maxsplit_argument_edit =
|
||||||
"maxsplit=1",
|
fix::edits::add_argument("maxsplit=1", arguments, checker.tokens());
|
||||||
arguments,
|
|
||||||
checker.comment_ranges(),
|
|
||||||
checker.locator().contents(),
|
|
||||||
);
|
|
||||||
|
|
||||||
// Only change `actual_split_type` if it doesn't match `suggested_split_type`
|
// Only change `actual_split_type` if it doesn't match `suggested_split_type`
|
||||||
let split_type_edit: Option<Edit> = if actual_split_type == suggested_split_type {
|
let split_type_edit: Option<Edit> = if actual_split_type == suggested_split_type {
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ use ast::Expr;
|
||||||
use ruff_macros::{ViolationMetadata, derive_message_formats};
|
use ruff_macros::{ViolationMetadata, derive_message_formats};
|
||||||
use ruff_python_ast as ast;
|
use ruff_python_ast as ast;
|
||||||
use ruff_python_ast::comparable::ComparableExpr;
|
use ruff_python_ast::comparable::ComparableExpr;
|
||||||
use ruff_python_ast::parenthesize::parenthesized_range;
|
use ruff_python_ast::token::parenthesized_range;
|
||||||
use ruff_python_ast::{ExprBinOp, ExprRef, Operator};
|
use ruff_python_ast::{ExprBinOp, ExprRef, Operator};
|
||||||
use ruff_text_size::{Ranged, TextRange};
|
use ruff_text_size::{Ranged, TextRange};
|
||||||
|
|
||||||
|
|
@ -150,12 +150,10 @@ fn augmented_assignment(
|
||||||
|
|
||||||
let right_operand_ref = ExprRef::from(right_operand);
|
let right_operand_ref = ExprRef::from(right_operand);
|
||||||
let parent = original_expr.into();
|
let parent = original_expr.into();
|
||||||
let comment_ranges = checker.comment_ranges();
|
let tokens = checker.tokens();
|
||||||
let source = checker.source();
|
|
||||||
|
|
||||||
let right_operand_range =
|
let right_operand_range =
|
||||||
parenthesized_range(right_operand_ref, parent, comment_ranges, source)
|
parenthesized_range(right_operand_ref, parent, tokens).unwrap_or(right_operand.range());
|
||||||
.unwrap_or(right_operand.range());
|
|
||||||
let right_operand_expr = locator.slice(right_operand_range);
|
let right_operand_expr = locator.slice(right_operand_range);
|
||||||
|
|
||||||
let target_expr = locator.slice(target);
|
let target_expr = locator.slice(target);
|
||||||
|
|
|
||||||
|
|
@ -75,12 +75,7 @@ pub(crate) fn subprocess_run_without_check(checker: &Checker, call: &ast::ExprCa
|
||||||
let mut diagnostic =
|
let mut diagnostic =
|
||||||
checker.report_diagnostic(SubprocessRunWithoutCheck, call.func.range());
|
checker.report_diagnostic(SubprocessRunWithoutCheck, call.func.range());
|
||||||
diagnostic.set_fix(Fix::applicable_edit(
|
diagnostic.set_fix(Fix::applicable_edit(
|
||||||
add_argument(
|
add_argument("check=False", &call.arguments, checker.tokens()),
|
||||||
"check=False",
|
|
||||||
&call.arguments,
|
|
||||||
checker.comment_ranges(),
|
|
||||||
checker.locator().contents(),
|
|
||||||
),
|
|
||||||
// If the function call contains `**kwargs`, mark the fix as unsafe.
|
// If the function call contains `**kwargs`, mark the fix as unsafe.
|
||||||
if call
|
if call
|
||||||
.arguments
|
.arguments
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,7 @@
|
||||||
use std::fmt::{Display, Formatter};
|
use std::fmt::{Display, Formatter};
|
||||||
|
|
||||||
use ruff_macros::{ViolationMetadata, derive_message_formats};
|
use ruff_macros::{ViolationMetadata, derive_message_formats};
|
||||||
use ruff_python_ast::name::QualifiedName;
|
use ruff_python_ast::{self as ast, Expr, name::QualifiedName};
|
||||||
use ruff_python_ast::{self as ast, Expr};
|
|
||||||
use ruff_python_semantic::SemanticModel;
|
use ruff_python_semantic::SemanticModel;
|
||||||
use ruff_python_semantic::analyze::typing;
|
use ruff_python_semantic::analyze::typing;
|
||||||
use ruff_text_size::{Ranged, TextRange};
|
use ruff_text_size::{Ranged, TextRange};
|
||||||
|
|
@ -193,8 +192,7 @@ fn generate_keyword_fix(checker: &Checker, call: &ast::ExprCall) -> Fix {
|
||||||
}))
|
}))
|
||||||
),
|
),
|
||||||
&call.arguments,
|
&call.arguments,
|
||||||
checker.comment_ranges(),
|
checker.tokens(),
|
||||||
checker.locator().contents(),
|
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -204,7 +204,7 @@ pub(crate) fn non_pep695_generic_class(checker: &Checker, class_def: &StmtClassD
|
||||||
arguments,
|
arguments,
|
||||||
Parentheses::Remove,
|
Parentheses::Remove,
|
||||||
checker.source(),
|
checker.source(),
|
||||||
checker.comment_ranges(),
|
checker.tokens(),
|
||||||
)?;
|
)?;
|
||||||
Ok(Fix::unsafe_edits(
|
Ok(Fix::unsafe_edits(
|
||||||
Edit::insertion(type_params.to_string(), name.end()),
|
Edit::insertion(type_params.to_string(), name.end()),
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ use itertools::Itertools;
|
||||||
|
|
||||||
use ruff_macros::{ViolationMetadata, derive_message_formats};
|
use ruff_macros::{ViolationMetadata, derive_message_formats};
|
||||||
use ruff_python_ast::name::Name;
|
use ruff_python_ast::name::Name;
|
||||||
use ruff_python_ast::parenthesize::parenthesized_range;
|
use ruff_python_ast::token::parenthesized_range;
|
||||||
use ruff_python_ast::visitor::Visitor;
|
use ruff_python_ast::visitor::Visitor;
|
||||||
use ruff_python_ast::{Expr, ExprCall, ExprName, Keyword, StmtAnnAssign, StmtAssign, StmtRef};
|
use ruff_python_ast::{Expr, ExprCall, ExprName, Keyword, StmtAnnAssign, StmtAssign, StmtRef};
|
||||||
use ruff_text_size::{Ranged, TextRange};
|
use ruff_text_size::{Ranged, TextRange};
|
||||||
|
|
@ -261,11 +261,11 @@ fn create_diagnostic(
|
||||||
type_alias_kind: TypeAliasKind,
|
type_alias_kind: TypeAliasKind,
|
||||||
) {
|
) {
|
||||||
let source = checker.source();
|
let source = checker.source();
|
||||||
|
let tokens = checker.tokens();
|
||||||
let comment_ranges = checker.comment_ranges();
|
let comment_ranges = checker.comment_ranges();
|
||||||
|
|
||||||
let range_with_parentheses =
|
let range_with_parentheses =
|
||||||
parenthesized_range(value.into(), stmt.into(), comment_ranges, source)
|
parenthesized_range(value.into(), stmt.into(), tokens).unwrap_or(value.range());
|
||||||
.unwrap_or(value.range());
|
|
||||||
|
|
||||||
let content = format!(
|
let content = format!(
|
||||||
"type {name}{type_params} = {value}",
|
"type {name}{type_params} = {value}",
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,8 @@
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
|
|
||||||
use ruff_macros::{ViolationMetadata, derive_message_formats};
|
use ruff_macros::{ViolationMetadata, derive_message_formats};
|
||||||
use ruff_python_ast::{self as ast, Keyword};
|
use ruff_python_ast::{self as ast, Keyword, token::Tokens};
|
||||||
use ruff_python_semantic::Modules;
|
use ruff_python_semantic::Modules;
|
||||||
use ruff_python_trivia::CommentRanges;
|
|
||||||
use ruff_text_size::Ranged;
|
use ruff_text_size::Ranged;
|
||||||
|
|
||||||
use crate::checkers::ast::Checker;
|
use crate::checkers::ast::Checker;
|
||||||
|
|
@ -104,7 +103,7 @@ pub(crate) fn replace_stdout_stderr(checker: &Checker, call: &ast::ExprCall) {
|
||||||
stderr,
|
stderr,
|
||||||
call,
|
call,
|
||||||
checker.locator().contents(),
|
checker.locator().contents(),
|
||||||
checker.comment_ranges(),
|
checker.tokens(),
|
||||||
)
|
)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
@ -117,7 +116,7 @@ fn generate_fix(
|
||||||
stderr: &Keyword,
|
stderr: &Keyword,
|
||||||
call: &ast::ExprCall,
|
call: &ast::ExprCall,
|
||||||
source: &str,
|
source: &str,
|
||||||
comment_ranges: &CommentRanges,
|
tokens: &Tokens,
|
||||||
) -> Result<Fix> {
|
) -> Result<Fix> {
|
||||||
let (first, second) = if stdout.start() < stderr.start() {
|
let (first, second) = if stdout.start() < stderr.start() {
|
||||||
(stdout, stderr)
|
(stdout, stderr)
|
||||||
|
|
@ -132,7 +131,7 @@ fn generate_fix(
|
||||||
&call.arguments,
|
&call.arguments,
|
||||||
Parentheses::Preserve,
|
Parentheses::Preserve,
|
||||||
source,
|
source,
|
||||||
comment_ranges,
|
tokens,
|
||||||
)?],
|
)?],
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -78,7 +78,7 @@ pub(crate) fn replace_universal_newlines(checker: &Checker, call: &ast::ExprCall
|
||||||
&call.arguments,
|
&call.arguments,
|
||||||
Parentheses::Preserve,
|
Parentheses::Preserve,
|
||||||
checker.locator().contents(),
|
checker.locator().contents(),
|
||||||
checker.comment_ranges(),
|
checker.tokens(),
|
||||||
)
|
)
|
||||||
.map(Fix::safe_edit)
|
.map(Fix::safe_edit)
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -188,7 +188,7 @@ pub(crate) fn unnecessary_encode_utf8(checker: &Checker, call: &ast::ExprCall) {
|
||||||
&call.arguments,
|
&call.arguments,
|
||||||
Parentheses::Preserve,
|
Parentheses::Preserve,
|
||||||
checker.locator().contents(),
|
checker.locator().contents(),
|
||||||
checker.comment_ranges(),
|
checker.tokens(),
|
||||||
)
|
)
|
||||||
.map(Fix::safe_edit)
|
.map(Fix::safe_edit)
|
||||||
});
|
});
|
||||||
|
|
@ -206,7 +206,7 @@ pub(crate) fn unnecessary_encode_utf8(checker: &Checker, call: &ast::ExprCall) {
|
||||||
&call.arguments,
|
&call.arguments,
|
||||||
Parentheses::Preserve,
|
Parentheses::Preserve,
|
||||||
checker.locator().contents(),
|
checker.locator().contents(),
|
||||||
checker.comment_ranges(),
|
checker.tokens(),
|
||||||
)
|
)
|
||||||
.map(Fix::safe_edit)
|
.map(Fix::safe_edit)
|
||||||
});
|
});
|
||||||
|
|
@ -231,7 +231,7 @@ pub(crate) fn unnecessary_encode_utf8(checker: &Checker, call: &ast::ExprCall) {
|
||||||
&call.arguments,
|
&call.arguments,
|
||||||
Parentheses::Preserve,
|
Parentheses::Preserve,
|
||||||
checker.locator().contents(),
|
checker.locator().contents(),
|
||||||
checker.comment_ranges(),
|
checker.tokens(),
|
||||||
)
|
)
|
||||||
.map(Fix::safe_edit)
|
.map(Fix::safe_edit)
|
||||||
});
|
});
|
||||||
|
|
@ -249,7 +249,7 @@ pub(crate) fn unnecessary_encode_utf8(checker: &Checker, call: &ast::ExprCall) {
|
||||||
&call.arguments,
|
&call.arguments,
|
||||||
Parentheses::Preserve,
|
Parentheses::Preserve,
|
||||||
checker.locator().contents(),
|
checker.locator().contents(),
|
||||||
checker.comment_ranges(),
|
checker.tokens(),
|
||||||
)
|
)
|
||||||
.map(Fix::safe_edit)
|
.map(Fix::safe_edit)
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -70,7 +70,7 @@ pub(crate) fn useless_class_metaclass_type(checker: &Checker, class_def: &StmtCl
|
||||||
arguments,
|
arguments,
|
||||||
Parentheses::Remove,
|
Parentheses::Remove,
|
||||||
checker.locator().contents(),
|
checker.locator().contents(),
|
||||||
checker.comment_ranges(),
|
checker.tokens(),
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
let range = edit.range();
|
let range = edit.range();
|
||||||
|
|
|
||||||
|
|
@ -73,7 +73,7 @@ pub(crate) fn useless_object_inheritance(checker: &Checker, class_def: &ast::Stm
|
||||||
arguments,
|
arguments,
|
||||||
Parentheses::Remove,
|
Parentheses::Remove,
|
||||||
checker.locator().contents(),
|
checker.locator().contents(),
|
||||||
checker.comment_ranges(),
|
checker.tokens(),
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
let range = edit.range();
|
let range = edit.range();
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
use ruff_macros::{ViolationMetadata, derive_message_formats};
|
use ruff_macros::{ViolationMetadata, derive_message_formats};
|
||||||
use ruff_python_ast::parenthesize::parenthesized_range;
|
use ruff_python_ast::token::parenthesized_range;
|
||||||
use ruff_python_ast::{self as ast, Expr, Stmt};
|
use ruff_python_ast::{self as ast, Expr, Stmt};
|
||||||
use ruff_text_size::Ranged;
|
use ruff_text_size::Ranged;
|
||||||
|
|
||||||
|
|
@ -139,13 +139,8 @@ pub(crate) fn yield_in_for_loop(checker: &Checker, stmt_for: &ast::StmtFor) {
|
||||||
let mut diagnostic = checker.report_diagnostic(YieldInForLoop, stmt_for.range());
|
let mut diagnostic = checker.report_diagnostic(YieldInForLoop, stmt_for.range());
|
||||||
|
|
||||||
let contents = checker.locator().slice(
|
let contents = checker.locator().slice(
|
||||||
parenthesized_range(
|
parenthesized_range(iter.as_ref().into(), stmt_for.into(), checker.tokens())
|
||||||
iter.as_ref().into(),
|
.unwrap_or(iter.range()),
|
||||||
stmt_for.into(),
|
|
||||||
checker.comment_ranges(),
|
|
||||||
checker.locator().contents(),
|
|
||||||
)
|
|
||||||
.unwrap_or(iter.range()),
|
|
||||||
);
|
);
|
||||||
let contents = if iter.as_tuple_expr().is_some_and(|it| !it.parenthesized) {
|
let contents = if iter.as_tuple_expr().is_some_and(|it| !it.parenthesized) {
|
||||||
format!("yield from ({contents})")
|
format!("yield from ({contents})")
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
use std::borrow::Cow;
|
use std::borrow::Cow;
|
||||||
|
|
||||||
use ruff_python_ast::PythonVersion;
|
use ruff_python_ast::PythonVersion;
|
||||||
use ruff_python_ast::{self as ast, Expr, name::Name, parenthesize::parenthesized_range};
|
use ruff_python_ast::{self as ast, Expr, name::Name, token::parenthesized_range};
|
||||||
use ruff_python_codegen::Generator;
|
use ruff_python_codegen::Generator;
|
||||||
use ruff_python_semantic::{BindingId, ResolvedReference, SemanticModel};
|
use ruff_python_semantic::{BindingId, ResolvedReference, SemanticModel};
|
||||||
use ruff_text_size::{Ranged, TextRange};
|
use ruff_text_size::{Ranged, TextRange};
|
||||||
|
|
@ -330,12 +330,8 @@ pub(super) fn parenthesize_loop_iter_if_necessary<'a>(
|
||||||
let locator = checker.locator();
|
let locator = checker.locator();
|
||||||
let iter = for_stmt.iter.as_ref();
|
let iter = for_stmt.iter.as_ref();
|
||||||
|
|
||||||
let original_parenthesized_range = parenthesized_range(
|
let original_parenthesized_range =
|
||||||
iter.into(),
|
parenthesized_range(iter.into(), for_stmt.into(), checker.tokens());
|
||||||
for_stmt.into(),
|
|
||||||
checker.comment_ranges(),
|
|
||||||
checker.source(),
|
|
||||||
);
|
|
||||||
|
|
||||||
if let Some(range) = original_parenthesized_range {
|
if let Some(range) = original_parenthesized_range {
|
||||||
return Cow::Borrowed(locator.slice(range));
|
return Cow::Borrowed(locator.slice(range));
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
use ruff_macros::{ViolationMetadata, derive_message_formats};
|
use ruff_macros::{ViolationMetadata, derive_message_formats};
|
||||||
use ruff_python_ast::parenthesize::parenthesized_range;
|
use ruff_python_ast::token::parenthesized_range;
|
||||||
use ruff_python_ast::{
|
use ruff_python_ast::{
|
||||||
Expr, ExprAttribute, ExprBinOp, ExprCall, ExprStringLiteral, ExprSubscript, ExprUnaryOp,
|
Expr, ExprAttribute, ExprBinOp, ExprCall, ExprStringLiteral, ExprSubscript, ExprUnaryOp,
|
||||||
Number, Operator, PythonVersion, UnaryOp,
|
Number, Operator, PythonVersion, UnaryOp,
|
||||||
|
|
@ -112,8 +112,7 @@ pub(crate) fn fromisoformat_replace_z(checker: &Checker, call: &ExprCall) {
|
||||||
let value_full_range = parenthesized_range(
|
let value_full_range = parenthesized_range(
|
||||||
replace_time_zone.date.into(),
|
replace_time_zone.date.into(),
|
||||||
replace_time_zone.parent.into(),
|
replace_time_zone.parent.into(),
|
||||||
checker.comment_ranges(),
|
checker.tokens(),
|
||||||
checker.source(),
|
|
||||||
)
|
)
|
||||||
.unwrap_or(replace_time_zone.date.range());
|
.unwrap_or(replace_time_zone.date.range());
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -5,8 +5,7 @@ use ruff_python_ast as ast;
|
||||||
use ruff_python_ast::Expr;
|
use ruff_python_ast::Expr;
|
||||||
use ruff_python_ast::comparable::ComparableExpr;
|
use ruff_python_ast::comparable::ComparableExpr;
|
||||||
use ruff_python_ast::helpers::contains_effect;
|
use ruff_python_ast::helpers::contains_effect;
|
||||||
use ruff_python_ast::parenthesize::parenthesized_range;
|
use ruff_python_ast::token::{Tokens, parenthesized_range};
|
||||||
use ruff_python_trivia::CommentRanges;
|
|
||||||
use ruff_text_size::Ranged;
|
use ruff_text_size::Ranged;
|
||||||
|
|
||||||
use crate::Locator;
|
use crate::Locator;
|
||||||
|
|
@ -76,8 +75,8 @@ pub(crate) fn if_exp_instead_of_or_operator(checker: &Checker, if_expr: &ast::Ex
|
||||||
Edit::range_replacement(
|
Edit::range_replacement(
|
||||||
format!(
|
format!(
|
||||||
"{} or {}",
|
"{} or {}",
|
||||||
parenthesize_test(test, if_expr, checker.comment_ranges(), checker.locator()),
|
parenthesize_test(test, if_expr, checker.tokens(), checker.locator()),
|
||||||
parenthesize_test(orelse, if_expr, checker.comment_ranges(), checker.locator()),
|
parenthesize_test(orelse, if_expr, checker.tokens(), checker.locator()),
|
||||||
),
|
),
|
||||||
if_expr.range(),
|
if_expr.range(),
|
||||||
),
|
),
|
||||||
|
|
@ -99,15 +98,10 @@ pub(crate) fn if_exp_instead_of_or_operator(checker: &Checker, if_expr: &ast::Ex
|
||||||
fn parenthesize_test<'a>(
|
fn parenthesize_test<'a>(
|
||||||
expr: &Expr,
|
expr: &Expr,
|
||||||
if_expr: &ast::ExprIf,
|
if_expr: &ast::ExprIf,
|
||||||
comment_ranges: &CommentRanges,
|
tokens: &Tokens,
|
||||||
locator: &Locator<'a>,
|
locator: &Locator<'a>,
|
||||||
) -> Cow<'a, str> {
|
) -> Cow<'a, str> {
|
||||||
if let Some(range) = parenthesized_range(
|
if let Some(range) = parenthesized_range(expr.into(), if_expr.into(), tokens) {
|
||||||
expr.into(),
|
|
||||||
if_expr.into(),
|
|
||||||
comment_ranges,
|
|
||||||
locator.contents(),
|
|
||||||
) {
|
|
||||||
Cow::Borrowed(locator.slice(range))
|
Cow::Borrowed(locator.slice(range))
|
||||||
} else if matches!(expr, Expr::If(_) | Expr::Lambda(_) | Expr::Named(_)) {
|
} else if matches!(expr, Expr::If(_) | Expr::Lambda(_) | Expr::Named(_)) {
|
||||||
Cow::Owned(format!("({})", locator.slice(expr.range())))
|
Cow::Owned(format!("({})", locator.slice(expr.range())))
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
use ruff_diagnostics::Applicability;
|
use ruff_diagnostics::Applicability;
|
||||||
use ruff_macros::{ViolationMetadata, derive_message_formats};
|
use ruff_macros::{ViolationMetadata, derive_message_formats};
|
||||||
use ruff_python_ast::parenthesize::parenthesized_range;
|
use ruff_python_ast::token::parenthesized_range;
|
||||||
use ruff_python_ast::{Comprehension, Expr, StmtFor};
|
use ruff_python_ast::{Comprehension, Expr, StmtFor};
|
||||||
use ruff_python_semantic::analyze::typing;
|
use ruff_python_semantic::analyze::typing;
|
||||||
use ruff_python_semantic::analyze::typing::is_io_base_expr;
|
use ruff_python_semantic::analyze::typing::is_io_base_expr;
|
||||||
|
|
@ -104,8 +104,7 @@ fn readlines_in_iter(checker: &Checker, iter_expr: &Expr) {
|
||||||
let deletion_range = if let Some(parenthesized_range) = parenthesized_range(
|
let deletion_range = if let Some(parenthesized_range) = parenthesized_range(
|
||||||
expr_attr.value.as_ref().into(),
|
expr_attr.value.as_ref().into(),
|
||||||
expr_attr.into(),
|
expr_attr.into(),
|
||||||
checker.comment_ranges(),
|
checker.tokens(),
|
||||||
checker.source(),
|
|
||||||
) {
|
) {
|
||||||
expr_call.range().add_start(parenthesized_range.len())
|
expr_call.range().add_start(parenthesized_range.len())
|
||||||
} else {
|
} else {
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use ruff_diagnostics::Applicability;
|
use ruff_diagnostics::Applicability;
|
||||||
use ruff_macros::{ViolationMetadata, derive_message_formats};
|
use ruff_macros::{ViolationMetadata, derive_message_formats};
|
||||||
use ruff_python_ast::parenthesize::parenthesized_range;
|
use ruff_python_ast::token::parenthesized_range;
|
||||||
use ruff_python_ast::{self as ast, Expr, Number};
|
use ruff_python_ast::{self as ast, Expr, Number};
|
||||||
use ruff_text_size::Ranged;
|
use ruff_text_size::Ranged;
|
||||||
|
|
||||||
|
|
@ -152,13 +152,8 @@ fn generate_fix(checker: &Checker, call: &ast::ExprCall, base: Base, arg: &Expr)
|
||||||
checker.semantic(),
|
checker.semantic(),
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
let arg_range = parenthesized_range(
|
let arg_range =
|
||||||
arg.into(),
|
parenthesized_range(arg.into(), call.into(), checker.tokens()).unwrap_or(arg.range());
|
||||||
call.into(),
|
|
||||||
checker.comment_ranges(),
|
|
||||||
checker.source(),
|
|
||||||
)
|
|
||||||
.unwrap_or(arg.range());
|
|
||||||
let arg_str = checker.locator().slice(arg_range);
|
let arg_str = checker.locator().slice(arg_range);
|
||||||
|
|
||||||
Ok(Fix::applicable_edits(
|
Ok(Fix::applicable_edits(
|
||||||
|
|
|
||||||
|
|
@ -95,7 +95,7 @@ pub(crate) fn single_item_membership_test(
|
||||||
&[membership_test.replacement_op()],
|
&[membership_test.replacement_op()],
|
||||||
std::slice::from_ref(item),
|
std::slice::from_ref(item),
|
||||||
expr.into(),
|
expr.into(),
|
||||||
checker.comment_ranges(),
|
checker.tokens(),
|
||||||
checker.source(),
|
checker.source(),
|
||||||
),
|
),
|
||||||
expr.range(),
|
expr.range(),
|
||||||
|
|
|
||||||
|
|
@ -163,7 +163,7 @@ fn convert_type_vars(
|
||||||
class_arguments,
|
class_arguments,
|
||||||
Parentheses::Remove,
|
Parentheses::Remove,
|
||||||
source,
|
source,
|
||||||
checker.comment_ranges(),
|
checker.tokens(),
|
||||||
)?;
|
)?;
|
||||||
let replace_type_params =
|
let replace_type_params =
|
||||||
Edit::range_replacement(new_type_params.to_string(), type_params.range);
|
Edit::range_replacement(new_type_params.to_string(), type_params.range);
|
||||||
|
|
|
||||||
|
|
@ -3,8 +3,8 @@ use anyhow::Result;
|
||||||
use ast::Keyword;
|
use ast::Keyword;
|
||||||
use ruff_macros::{ViolationMetadata, derive_message_formats};
|
use ruff_macros::{ViolationMetadata, derive_message_formats};
|
||||||
use ruff_python_ast::helpers::is_constant;
|
use ruff_python_ast::helpers::is_constant;
|
||||||
|
use ruff_python_ast::token::Tokens;
|
||||||
use ruff_python_ast::{self as ast, Expr};
|
use ruff_python_ast::{self as ast, Expr};
|
||||||
use ruff_python_trivia::CommentRanges;
|
|
||||||
use ruff_text_size::Ranged;
|
use ruff_text_size::Ranged;
|
||||||
|
|
||||||
use crate::Locator;
|
use crate::Locator;
|
||||||
|
|
@ -108,9 +108,8 @@ pub(crate) fn default_factory_kwarg(checker: &Checker, call: &ast::ExprCall) {
|
||||||
},
|
},
|
||||||
call.range(),
|
call.range(),
|
||||||
);
|
);
|
||||||
diagnostic.try_set_fix(|| {
|
diagnostic
|
||||||
convert_to_positional(call, keyword, checker.locator(), checker.comment_ranges())
|
.try_set_fix(|| convert_to_positional(call, keyword, checker.locator(), checker.tokens()));
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns `true` if a value is definitively not callable (e.g., `1` or `[]`).
|
/// Returns `true` if a value is definitively not callable (e.g., `1` or `[]`).
|
||||||
|
|
@ -136,7 +135,7 @@ fn convert_to_positional(
|
||||||
call: &ast::ExprCall,
|
call: &ast::ExprCall,
|
||||||
default_factory: &Keyword,
|
default_factory: &Keyword,
|
||||||
locator: &Locator,
|
locator: &Locator,
|
||||||
comment_ranges: &CommentRanges,
|
tokens: &Tokens,
|
||||||
) -> Result<Fix> {
|
) -> Result<Fix> {
|
||||||
if call.arguments.len() == 1 {
|
if call.arguments.len() == 1 {
|
||||||
// Ex) `defaultdict(default_factory=list)`
|
// Ex) `defaultdict(default_factory=list)`
|
||||||
|
|
@ -153,7 +152,7 @@ fn convert_to_positional(
|
||||||
&call.arguments,
|
&call.arguments,
|
||||||
Parentheses::Preserve,
|
Parentheses::Preserve,
|
||||||
locator.contents(),
|
locator.contents(),
|
||||||
comment_ranges,
|
tokens,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
// Second, insert the value as the first positional argument.
|
// Second, insert the value as the first positional argument.
|
||||||
|
|
|
||||||
|
|
@ -128,7 +128,7 @@ pub(crate) fn falsy_dict_get_fallback(checker: &Checker, expr: &Expr) {
|
||||||
&call.arguments,
|
&call.arguments,
|
||||||
Parentheses::Preserve,
|
Parentheses::Preserve,
|
||||||
checker.locator().contents(),
|
checker.locator().contents(),
|
||||||
checker.comment_ranges(),
|
checker.tokens(),
|
||||||
)
|
)
|
||||||
.map(|edit| Fix::applicable_edit(edit, applicability))
|
.map(|edit| Fix::applicable_edit(edit, applicability))
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
use ruff_macros::{ViolationMetadata, derive_message_formats};
|
use ruff_macros::{ViolationMetadata, derive_message_formats};
|
||||||
use ruff_python_ast as ast;
|
use ruff_python_ast as ast;
|
||||||
use ruff_python_ast::parenthesize::parenthesized_range;
|
use ruff_python_ast::token::parenthesized_range;
|
||||||
use ruff_text_size::Ranged;
|
use ruff_text_size::Ranged;
|
||||||
|
|
||||||
use crate::checkers::ast::Checker;
|
use crate::checkers::ast::Checker;
|
||||||
|
|
@ -77,14 +77,7 @@ pub(crate) fn parenthesize_chained_logical_operators(checker: &Checker, expr: &a
|
||||||
) => {
|
) => {
|
||||||
let locator = checker.locator();
|
let locator = checker.locator();
|
||||||
let source_range = bool_op.range();
|
let source_range = bool_op.range();
|
||||||
if parenthesized_range(
|
if parenthesized_range(bool_op.into(), expr.into(), checker.tokens()).is_none() {
|
||||||
bool_op.into(),
|
|
||||||
expr.into(),
|
|
||||||
checker.comment_ranges(),
|
|
||||||
locator.contents(),
|
|
||||||
)
|
|
||||||
.is_none()
|
|
||||||
{
|
|
||||||
let new_source = format!("({})", locator.slice(source_range));
|
let new_source = format!("({})", locator.slice(source_range));
|
||||||
let edit = Edit::range_replacement(new_source, source_range);
|
let edit = Edit::range_replacement(new_source, source_range);
|
||||||
checker
|
checker
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ use anyhow::Context;
|
||||||
|
|
||||||
use ruff_macros::{ViolationMetadata, derive_message_formats};
|
use ruff_macros::{ViolationMetadata, derive_message_formats};
|
||||||
use ruff_python_ast as ast;
|
use ruff_python_ast as ast;
|
||||||
use ruff_python_ast::parenthesize::parenthesized_range;
|
use ruff_python_ast::token::parenthesized_range;
|
||||||
use ruff_python_semantic::{Scope, ScopeKind};
|
use ruff_python_semantic::{Scope, ScopeKind};
|
||||||
use ruff_python_trivia::{indentation_at_offset, textwrap};
|
use ruff_python_trivia::{indentation_at_offset, textwrap};
|
||||||
use ruff_source_file::LineRanges;
|
use ruff_source_file::LineRanges;
|
||||||
|
|
@ -159,8 +159,7 @@ fn use_initvar(
|
||||||
let default_loc = parenthesized_range(
|
let default_loc = parenthesized_range(
|
||||||
default.into(),
|
default.into(),
|
||||||
parameter_with_default.into(),
|
parameter_with_default.into(),
|
||||||
checker.comment_ranges(),
|
checker.tokens(),
|
||||||
checker.source(),
|
|
||||||
)
|
)
|
||||||
.unwrap_or(default.range());
|
.unwrap_or(default.range());
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ use anyhow::Result;
|
||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
|
|
||||||
use ruff_macros::{ViolationMetadata, derive_message_formats};
|
use ruff_macros::{ViolationMetadata, derive_message_formats};
|
||||||
use ruff_python_ast::parenthesize::parenthesized_range;
|
use ruff_python_ast::token::parenthesized_range;
|
||||||
use ruff_python_ast::{self as ast, Arguments, Expr};
|
use ruff_python_ast::{self as ast, Arguments, Expr};
|
||||||
use ruff_python_semantic::SemanticModel;
|
use ruff_python_semantic::SemanticModel;
|
||||||
use ruff_text_size::Ranged;
|
use ruff_text_size::Ranged;
|
||||||
|
|
@ -116,13 +116,8 @@ fn convert_to_reduce(iterable: &Expr, call: &ast::ExprCall, checker: &Checker) -
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
let iterable = checker.locator().slice(
|
let iterable = checker.locator().slice(
|
||||||
parenthesized_range(
|
parenthesized_range(iterable.into(), (&call.arguments).into(), checker.tokens())
|
||||||
iterable.into(),
|
.unwrap_or(iterable.range()),
|
||||||
(&call.arguments).into(),
|
|
||||||
checker.comment_ranges(),
|
|
||||||
checker.locator().contents(),
|
|
||||||
)
|
|
||||||
.unwrap_or(iterable.range()),
|
|
||||||
);
|
);
|
||||||
|
|
||||||
Ok(Fix::unsafe_edits(
|
Ok(Fix::unsafe_edits(
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
use ruff_macros::{ViolationMetadata, derive_message_formats};
|
use ruff_macros::{ViolationMetadata, derive_message_formats};
|
||||||
use ruff_python_ast::PythonVersion;
|
use ruff_python_ast::PythonVersion;
|
||||||
use ruff_python_ast::token::TokenKind;
|
use ruff_python_ast::token::TokenKind;
|
||||||
use ruff_python_ast::{Expr, ExprCall, parenthesize::parenthesized_range};
|
use ruff_python_ast::{Expr, ExprCall, token::parenthesized_range};
|
||||||
use ruff_text_size::{Ranged, TextRange};
|
use ruff_text_size::{Ranged, TextRange};
|
||||||
|
|
||||||
use crate::checkers::ast::Checker;
|
use crate::checkers::ast::Checker;
|
||||||
|
|
@ -124,13 +124,8 @@ fn replace_with_map(starmap: &ExprCall, zip: &ExprCall, checker: &Checker) -> Op
|
||||||
|
|
||||||
let mut remove_zip = vec![];
|
let mut remove_zip = vec![];
|
||||||
|
|
||||||
let full_zip_range = parenthesized_range(
|
let full_zip_range =
|
||||||
zip.into(),
|
parenthesized_range(zip.into(), starmap.into(), checker.tokens()).unwrap_or(zip.range());
|
||||||
starmap.into(),
|
|
||||||
checker.comment_ranges(),
|
|
||||||
checker.source(),
|
|
||||||
)
|
|
||||||
.unwrap_or(zip.range());
|
|
||||||
|
|
||||||
// Delete any parentheses around the `zip` call to prevent that the argument turns into a tuple.
|
// Delete any parentheses around the `zip` call to prevent that the argument turns into a tuple.
|
||||||
remove_zip.push(Edit::range_deletion(TextRange::new(
|
remove_zip.push(Edit::range_deletion(TextRange::new(
|
||||||
|
|
@ -138,13 +133,8 @@ fn replace_with_map(starmap: &ExprCall, zip: &ExprCall, checker: &Checker) -> Op
|
||||||
zip.start(),
|
zip.start(),
|
||||||
)));
|
)));
|
||||||
|
|
||||||
let full_zip_func_range = parenthesized_range(
|
let full_zip_func_range = parenthesized_range((&zip.func).into(), zip.into(), checker.tokens())
|
||||||
(&zip.func).into(),
|
.unwrap_or(zip.func.range());
|
||||||
zip.into(),
|
|
||||||
checker.comment_ranges(),
|
|
||||||
checker.source(),
|
|
||||||
)
|
|
||||||
.unwrap_or(zip.func.range());
|
|
||||||
|
|
||||||
// Delete the `zip` callee
|
// Delete the `zip` callee
|
||||||
remove_zip.push(Edit::range_deletion(full_zip_func_range));
|
remove_zip.push(Edit::range_deletion(full_zip_func_range));
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
use ruff_macros::{ViolationMetadata, derive_message_formats};
|
use ruff_macros::{ViolationMetadata, derive_message_formats};
|
||||||
use ruff_python_ast::parenthesize::parenthesized_range;
|
use ruff_python_ast::token::{Tokens, parenthesized_range};
|
||||||
use ruff_python_ast::{Arguments, Expr, ExprCall};
|
use ruff_python_ast::{Arguments, Expr, ExprCall};
|
||||||
use ruff_python_semantic::SemanticModel;
|
use ruff_python_semantic::SemanticModel;
|
||||||
use ruff_python_semantic::analyze::type_inference::{NumberLike, PythonType, ResolvedPythonType};
|
use ruff_python_semantic::analyze::type_inference::{NumberLike, PythonType, ResolvedPythonType};
|
||||||
|
|
@ -86,6 +86,7 @@ pub(crate) fn unnecessary_cast_to_int(checker: &Checker, call: &ExprCall) {
|
||||||
applicability,
|
applicability,
|
||||||
checker.semantic(),
|
checker.semantic(),
|
||||||
checker.locator(),
|
checker.locator(),
|
||||||
|
checker.tokens(),
|
||||||
checker.comment_ranges(),
|
checker.comment_ranges(),
|
||||||
checker.source(),
|
checker.source(),
|
||||||
);
|
);
|
||||||
|
|
@ -95,27 +96,26 @@ pub(crate) fn unnecessary_cast_to_int(checker: &Checker, call: &ExprCall) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates a fix that replaces `int(expression)` with `expression`.
|
/// Creates a fix that replaces `int(expression)` with `expression`.
|
||||||
|
#[allow(clippy::too_many_arguments)]
|
||||||
fn unwrap_int_expression(
|
fn unwrap_int_expression(
|
||||||
call: &ExprCall,
|
call: &ExprCall,
|
||||||
argument: &Expr,
|
argument: &Expr,
|
||||||
applicability: Applicability,
|
applicability: Applicability,
|
||||||
semantic: &SemanticModel,
|
semantic: &SemanticModel,
|
||||||
locator: &Locator,
|
locator: &Locator,
|
||||||
|
tokens: &Tokens,
|
||||||
comment_ranges: &CommentRanges,
|
comment_ranges: &CommentRanges,
|
||||||
source: &str,
|
source: &str,
|
||||||
) -> Fix {
|
) -> Fix {
|
||||||
let content = if let Some(range) = parenthesized_range(
|
let content = if let Some(range) =
|
||||||
argument.into(),
|
parenthesized_range(argument.into(), (&call.arguments).into(), tokens)
|
||||||
(&call.arguments).into(),
|
{
|
||||||
comment_ranges,
|
|
||||||
source,
|
|
||||||
) {
|
|
||||||
locator.slice(range).to_string()
|
locator.slice(range).to_string()
|
||||||
} else {
|
} else {
|
||||||
let parenthesize = semantic.current_expression_parent().is_some()
|
let parenthesize = semantic.current_expression_parent().is_some()
|
||||||
|| argument.is_named_expr()
|
|| argument.is_named_expr()
|
||||||
|| locator.count_lines(argument.range()) > 0;
|
|| locator.count_lines(argument.range()) > 0;
|
||||||
if parenthesize && !has_own_parentheses(argument, comment_ranges, source) {
|
if parenthesize && !has_own_parentheses(argument, tokens, source) {
|
||||||
format!("({})", locator.slice(argument.range()))
|
format!("({})", locator.slice(argument.range()))
|
||||||
} else {
|
} else {
|
||||||
locator.slice(argument.range()).to_string()
|
locator.slice(argument.range()).to_string()
|
||||||
|
|
@ -255,7 +255,7 @@ fn round_applicability(arguments: &Arguments, semantic: &SemanticModel) -> Optio
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns `true` if the given [`Expr`] has its own parentheses (e.g., `()`, `[]`, `{}`).
|
/// Returns `true` if the given [`Expr`] has its own parentheses (e.g., `()`, `[]`, `{}`).
|
||||||
fn has_own_parentheses(expr: &Expr, comment_ranges: &CommentRanges, source: &str) -> bool {
|
fn has_own_parentheses(expr: &Expr, tokens: &Tokens, source: &str) -> bool {
|
||||||
match expr {
|
match expr {
|
||||||
Expr::ListComp(_)
|
Expr::ListComp(_)
|
||||||
| Expr::SetComp(_)
|
| Expr::SetComp(_)
|
||||||
|
|
@ -276,14 +276,10 @@ fn has_own_parentheses(expr: &Expr, comment_ranges: &CommentRanges, source: &str
|
||||||
// f
|
// f
|
||||||
// (10)
|
// (10)
|
||||||
// ```
|
// ```
|
||||||
let func_end = parenthesized_range(
|
let func_end =
|
||||||
call_expr.func.as_ref().into(),
|
parenthesized_range(call_expr.func.as_ref().into(), call_expr.into(), tokens)
|
||||||
call_expr.into(),
|
.unwrap_or(call_expr.func.range())
|
||||||
comment_ranges,
|
.end();
|
||||||
source,
|
|
||||||
)
|
|
||||||
.unwrap_or(call_expr.func.range())
|
|
||||||
.end();
|
|
||||||
lines_after_ignoring_trivia(func_end, source) == 0
|
lines_after_ignoring_trivia(func_end, source) == 0
|
||||||
}
|
}
|
||||||
Expr::Subscript(subscript_expr) => {
|
Expr::Subscript(subscript_expr) => {
|
||||||
|
|
@ -291,8 +287,7 @@ fn has_own_parentheses(expr: &Expr, comment_ranges: &CommentRanges, source: &str
|
||||||
let subscript_end = parenthesized_range(
|
let subscript_end = parenthesized_range(
|
||||||
subscript_expr.value.as_ref().into(),
|
subscript_expr.value.as_ref().into(),
|
||||||
subscript_expr.into(),
|
subscript_expr.into(),
|
||||||
comment_ranges,
|
tokens,
|
||||||
source,
|
|
||||||
)
|
)
|
||||||
.unwrap_or(subscript_expr.value.range())
|
.unwrap_or(subscript_expr.value.range())
|
||||||
.end();
|
.end();
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@ use ruff_python_ast::{self as ast, BoolOp, CmpOp, Expr};
|
||||||
|
|
||||||
use ruff_macros::{ViolationMetadata, derive_message_formats};
|
use ruff_macros::{ViolationMetadata, derive_message_formats};
|
||||||
use ruff_python_ast::helpers::contains_effect;
|
use ruff_python_ast::helpers::contains_effect;
|
||||||
use ruff_python_ast::parenthesize::parenthesized_range;
|
use ruff_python_ast::token::parenthesized_range;
|
||||||
use ruff_text_size::Ranged;
|
use ruff_text_size::Ranged;
|
||||||
|
|
||||||
use crate::checkers::ast::Checker;
|
use crate::checkers::ast::Checker;
|
||||||
|
|
@ -108,22 +108,12 @@ pub(crate) fn unnecessary_key_check(checker: &Checker, expr: &Expr) {
|
||||||
format!(
|
format!(
|
||||||
"{}.get({})",
|
"{}.get({})",
|
||||||
checker.locator().slice(
|
checker.locator().slice(
|
||||||
parenthesized_range(
|
parenthesized_range(obj_right.into(), right.into(), checker.tokens(),)
|
||||||
obj_right.into(),
|
.unwrap_or(obj_right.range())
|
||||||
right.into(),
|
|
||||||
checker.comment_ranges(),
|
|
||||||
checker.locator().contents(),
|
|
||||||
)
|
|
||||||
.unwrap_or(obj_right.range())
|
|
||||||
),
|
),
|
||||||
checker.locator().slice(
|
checker.locator().slice(
|
||||||
parenthesized_range(
|
parenthesized_range(key_right.into(), right.into(), checker.tokens(),)
|
||||||
key_right.into(),
|
.unwrap_or(key_right.range())
|
||||||
right.into(),
|
|
||||||
checker.comment_ranges(),
|
|
||||||
checker.locator().contents(),
|
|
||||||
)
|
|
||||||
.unwrap_or(key_right.range())
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
expr.range(),
|
expr.range(),
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ use ruff_diagnostics::{Applicability, Edit};
|
||||||
use ruff_macros::{ViolationMetadata, derive_message_formats};
|
use ruff_macros::{ViolationMetadata, derive_message_formats};
|
||||||
|
|
||||||
use ruff_python_ast::helpers::is_empty_f_string;
|
use ruff_python_ast::helpers::is_empty_f_string;
|
||||||
use ruff_python_ast::parenthesize::parenthesized_range;
|
use ruff_python_ast::token::parenthesized_range;
|
||||||
use ruff_python_ast::{self as ast, Expr};
|
use ruff_python_ast::{self as ast, Expr};
|
||||||
use ruff_text_size::Ranged;
|
use ruff_text_size::Ranged;
|
||||||
|
|
||||||
|
|
@ -140,31 +140,19 @@ fn fix_unnecessary_literal_in_deque(
|
||||||
// call. otherwise, we only delete the `iterable` argument and leave the others untouched.
|
// call. otherwise, we only delete the `iterable` argument and leave the others untouched.
|
||||||
let edit = if let Some(maxlen) = maxlen {
|
let edit = if let Some(maxlen) = maxlen {
|
||||||
let deque_name = checker.locator().slice(
|
let deque_name = checker.locator().slice(
|
||||||
parenthesized_range(
|
parenthesized_range(deque.func.as_ref().into(), deque.into(), checker.tokens())
|
||||||
deque.func.as_ref().into(),
|
.unwrap_or(deque.func.range()),
|
||||||
deque.into(),
|
|
||||||
checker.comment_ranges(),
|
|
||||||
checker.source(),
|
|
||||||
)
|
|
||||||
.unwrap_or(deque.func.range()),
|
|
||||||
);
|
);
|
||||||
let len_str = checker.locator().slice(maxlen);
|
let len_str = checker.locator().slice(maxlen);
|
||||||
let deque_str = format!("{deque_name}(maxlen={len_str})");
|
let deque_str = format!("{deque_name}(maxlen={len_str})");
|
||||||
Edit::range_replacement(deque_str, deque.range)
|
Edit::range_replacement(deque_str, deque.range)
|
||||||
} else {
|
} else {
|
||||||
let range = parenthesized_range(
|
|
||||||
iterable.value().into(),
|
|
||||||
(&deque.arguments).into(),
|
|
||||||
checker.comment_ranges(),
|
|
||||||
checker.source(),
|
|
||||||
)
|
|
||||||
.unwrap_or(iterable.range());
|
|
||||||
remove_argument(
|
remove_argument(
|
||||||
&range,
|
&iterable,
|
||||||
&deque.arguments,
|
&deque.arguments,
|
||||||
Parentheses::Preserve,
|
Parentheses::Preserve,
|
||||||
checker.source(),
|
checker.source(),
|
||||||
checker.comment_ranges(),
|
checker.tokens(),
|
||||||
)?
|
)?
|
||||||
};
|
};
|
||||||
let has_comments = checker.comment_ranges().intersects(edit.range());
|
let has_comments = checker.comment_ranges().intersects(edit.range());
|
||||||
|
|
|
||||||
|
|
@ -490,8 +490,10 @@ impl<'src> SuppressionParser<'src> {
|
||||||
} else if self.cursor.as_str().starts_with("enable") {
|
} else if self.cursor.as_str().starts_with("enable") {
|
||||||
self.cursor.skip_bytes("enable".len());
|
self.cursor.skip_bytes("enable".len());
|
||||||
Ok(SuppressionAction::Enable)
|
Ok(SuppressionAction::Enable)
|
||||||
} else if self.cursor.as_str().starts_with("noqa") {
|
} else if self.cursor.as_str().starts_with("noqa")
|
||||||
// file-level "noqa" variant, ignore for now
|
|| self.cursor.as_str().starts_with("isort")
|
||||||
|
{
|
||||||
|
// alternate suppression variants, ignore for now
|
||||||
self.error(ParseErrorKind::NotASuppression)
|
self.error(ParseErrorKind::NotASuppression)
|
||||||
} else {
|
} else {
|
||||||
self.error(ParseErrorKind::UnknownAction)
|
self.error(ParseErrorKind::UnknownAction)
|
||||||
|
|
|
||||||
|
|
@ -3,13 +3,14 @@ use std::path::Path;
|
||||||
|
|
||||||
use rustc_hash::FxHashMap;
|
use rustc_hash::FxHashMap;
|
||||||
|
|
||||||
use ruff_python_trivia::{CommentRanges, SimpleTokenKind, SimpleTokenizer, indentation_at_offset};
|
use ruff_python_trivia::{SimpleTokenKind, SimpleTokenizer, indentation_at_offset};
|
||||||
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::name::{Name, QualifiedName, QualifiedNameBuilder};
|
use crate::name::{Name, QualifiedName, QualifiedNameBuilder};
|
||||||
use crate::parenthesize::parenthesized_range;
|
|
||||||
use crate::statement_visitor::StatementVisitor;
|
use crate::statement_visitor::StatementVisitor;
|
||||||
|
use crate::token::Tokens;
|
||||||
|
use crate::token::parenthesized_range;
|
||||||
use crate::visitor::Visitor;
|
use crate::visitor::Visitor;
|
||||||
use crate::{
|
use crate::{
|
||||||
self as ast, Arguments, AtomicNodeIndex, CmpOp, DictItem, ExceptHandler, Expr, ExprNoneLiteral,
|
self as ast, Arguments, AtomicNodeIndex, CmpOp, DictItem, ExceptHandler, Expr, ExprNoneLiteral,
|
||||||
|
|
@ -1474,7 +1475,7 @@ pub fn generate_comparison(
|
||||||
ops: &[CmpOp],
|
ops: &[CmpOp],
|
||||||
comparators: &[Expr],
|
comparators: &[Expr],
|
||||||
parent: AnyNodeRef,
|
parent: AnyNodeRef,
|
||||||
comment_ranges: &CommentRanges,
|
tokens: &Tokens,
|
||||||
source: &str,
|
source: &str,
|
||||||
) -> String {
|
) -> String {
|
||||||
let start = left.start();
|
let start = left.start();
|
||||||
|
|
@ -1483,8 +1484,7 @@ pub fn generate_comparison(
|
||||||
|
|
||||||
// Add the left side of the comparison.
|
// Add the left side of the comparison.
|
||||||
contents.push_str(
|
contents.push_str(
|
||||||
&source[parenthesized_range(left.into(), parent, comment_ranges, source)
|
&source[parenthesized_range(left.into(), parent, tokens).unwrap_or(left.range())],
|
||||||
.unwrap_or(left.range())],
|
|
||||||
);
|
);
|
||||||
|
|
||||||
for (op, comparator) in ops.iter().zip(comparators) {
|
for (op, comparator) in ops.iter().zip(comparators) {
|
||||||
|
|
@ -1504,7 +1504,7 @@ pub fn generate_comparison(
|
||||||
|
|
||||||
// Add the right side of the comparison.
|
// Add the right side of the comparison.
|
||||||
contents.push_str(
|
contents.push_str(
|
||||||
&source[parenthesized_range(comparator.into(), parent, comment_ranges, source)
|
&source[parenthesized_range(comparator.into(), parent, tokens)
|
||||||
.unwrap_or(comparator.range())],
|
.unwrap_or(comparator.range())],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -36,7 +36,7 @@ impl Debug for DebugComment<'_> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Pretty-printed debug representation of [`Comments`].
|
/// Pretty-printed debug representation of [`Comments`](super::Comments).
|
||||||
pub(crate) struct DebugComments<'a> {
|
pub(crate) struct DebugComments<'a> {
|
||||||
comments: &'a CommentsMap<'a>,
|
comments: &'a CommentsMap<'a>,
|
||||||
source_code: SourceCode<'a>,
|
source_code: SourceCode<'a>,
|
||||||
|
|
|
||||||
|
|
@ -504,7 +504,7 @@ impl InOrderEntry {
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
struct OutOfOrderEntry {
|
struct OutOfOrderEntry {
|
||||||
/// Index into the [`MultiMap::out_of_order`] vector at which offset the leading vec is stored.
|
/// Index into the [`MultiMap::out_of_order_parts`] vector at which offset the leading vec is stored.
|
||||||
leading_index: usize,
|
leading_index: usize,
|
||||||
_count: Count<OutOfOrderEntry>,
|
_count: Count<OutOfOrderEntry>,
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,8 @@ use ruff_python_ast::AnyNodeRef;
|
||||||
use std::fmt::{Debug, Formatter};
|
use std::fmt::{Debug, Formatter};
|
||||||
use std::hash::{Hash, Hasher};
|
use std::hash::{Hash, Hasher};
|
||||||
|
|
||||||
/// Used as key into the [`MultiMap`] storing the comments per node by [`Comments`].
|
/// Used as key into the [`MultiMap`](super::MultiMap) storing the comments per node by
|
||||||
|
/// [`Comments`](super::Comments).
|
||||||
///
|
///
|
||||||
/// Implements equality and hashing based on the address of the [`AnyNodeRef`] to get fast and cheap
|
/// Implements equality and hashing based on the address of the [`AnyNodeRef`] to get fast and cheap
|
||||||
/// hashing/equality comparison.
|
/// hashing/equality comparison.
|
||||||
|
|
|
||||||
|
|
@ -1974,8 +1974,8 @@ fn handle_unary_op_comment<'a>(
|
||||||
/// )
|
/// )
|
||||||
/// ```
|
/// ```
|
||||||
///
|
///
|
||||||
/// The comment will be attached to the [`Arguments`] node as a dangling comment, to ensure
|
/// The comment will be attached to the [`Arguments`](ast::Arguments) node as a dangling comment, to
|
||||||
/// that it remains on the same line as open parenthesis.
|
/// ensure that it remains on the same line as open parenthesis.
|
||||||
///
|
///
|
||||||
/// Similarly, given:
|
/// Similarly, given:
|
||||||
/// ```python
|
/// ```python
|
||||||
|
|
@ -1984,8 +1984,8 @@ fn handle_unary_op_comment<'a>(
|
||||||
/// ] = ...
|
/// ] = ...
|
||||||
/// ```
|
/// ```
|
||||||
///
|
///
|
||||||
/// The comment will be attached to the [`TypeParams`] node as a dangling comment, to ensure
|
/// The comment will be attached to the [`TypeParams`](ast::TypeParams) node as a dangling comment,
|
||||||
/// that it remains on the same line as open bracket.
|
/// to ensure that it remains on the same line as open bracket.
|
||||||
fn handle_bracketed_end_of_line_comment<'a>(
|
fn handle_bracketed_end_of_line_comment<'a>(
|
||||||
comment: DecoratedComment<'a>,
|
comment: DecoratedComment<'a>,
|
||||||
source: &str,
|
source: &str,
|
||||||
|
|
|
||||||
|
|
@ -174,7 +174,8 @@ impl<'ast> SourceOrderVisitor<'ast> for CommentsVisitor<'ast, '_> {
|
||||||
|
|
||||||
/// A comment decorated with additional information about its surrounding context in the source document.
|
/// A comment decorated with additional information about its surrounding context in the source document.
|
||||||
///
|
///
|
||||||
/// Used by [`CommentStyle::place_comment`] to determine if this should become a [leading](self#leading-comments), [dangling](self#dangling-comments), or [trailing](self#trailing-comments) comment.
|
/// Used by [`place_comment`] to determine if this should become a [leading](self#leading-comments),
|
||||||
|
/// [dangling](self#dangling-comments), or [trailing](self#trailing-comments) comment.
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub(crate) struct DecoratedComment<'a> {
|
pub(crate) struct DecoratedComment<'a> {
|
||||||
enclosing: AnyNodeRef<'a>,
|
enclosing: AnyNodeRef<'a>,
|
||||||
|
|
@ -465,7 +466,7 @@ pub(super) enum CommentPlacement<'a> {
|
||||||
///
|
///
|
||||||
/// [`preceding_node`]: DecoratedComment::preceding_node
|
/// [`preceding_node`]: DecoratedComment::preceding_node
|
||||||
/// [`following_node`]: DecoratedComment::following_node
|
/// [`following_node`]: DecoratedComment::following_node
|
||||||
/// [`enclosing_node`]: DecoratedComment::enclosing_node_id
|
/// [`enclosing_node`]: DecoratedComment::enclosing_node
|
||||||
/// [trailing comment]: self#trailing-comments
|
/// [trailing comment]: self#trailing-comments
|
||||||
/// [leading comment]: self#leading-comments
|
/// [leading comment]: self#leading-comments
|
||||||
/// [dangling comment]: self#dangling-comments
|
/// [dangling comment]: self#dangling-comments
|
||||||
|
|
|
||||||
|
|
@ -166,7 +166,7 @@ impl InterpolatedStringState {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns `true` if the interpolated string state is [`NestedInterpolatedElement`].
|
/// Returns `true` if the interpolated string state is [`Self::NestedInterpolatedElement`].
|
||||||
pub(crate) fn is_nested(self) -> bool {
|
pub(crate) fn is_nested(self) -> bool {
|
||||||
matches!(self, Self::NestedInterpolatedElement(..))
|
matches!(self, Self::NestedInterpolatedElement(..))
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1095,9 +1095,9 @@ impl OperandIndex {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the index of the operand's right operator. The method always returns an index
|
/// Returns the index of the operand's right operator. The method always returns an index even
|
||||||
/// even if the operand has no right operator. Use [`BinaryCallChain::get_operator`] to test if
|
/// if the operand has no right operator. Use [`FlatBinaryExpressionSlice::get_operator`] to
|
||||||
/// the operand has a right operator.
|
/// test if the operand has a right operator.
|
||||||
fn right_operator(self) -> OperatorIndex {
|
fn right_operator(self) -> OperatorIndex {
|
||||||
OperatorIndex::new(self.0 + 1)
|
OperatorIndex::new(self.0 + 1)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -56,18 +56,20 @@ pub(crate) enum Parenthesize {
|
||||||
/// Adding parentheses is desired to prevent the comments from wandering.
|
/// Adding parentheses is desired to prevent the comments from wandering.
|
||||||
IfRequired,
|
IfRequired,
|
||||||
|
|
||||||
/// Same as [`Self::IfBreaks`] except that it uses [`parenthesize_if_expands`] for expressions
|
/// Same as [`Self::IfBreaks`] except that it uses
|
||||||
/// with the layout [`NeedsParentheses::BestFit`] which is used by non-splittable
|
/// [`parenthesize_if_expands`](crate::builders::parenthesize_if_expands) for expressions with
|
||||||
/// expressions like literals, name, and strings.
|
/// the layout [`OptionalParentheses::BestFit`] which is used by non-splittable expressions like
|
||||||
|
/// literals, name, and strings.
|
||||||
///
|
///
|
||||||
/// Use this layout over `IfBreaks` when there's a sequence of `maybe_parenthesize_expression`
|
/// Use this layout over `IfBreaks` when there's a sequence of `maybe_parenthesize_expression`
|
||||||
/// in a single logical-line and you want to break from right-to-left. Use `IfBreaks` for the
|
/// in a single logical-line and you want to break from right-to-left. Use `IfBreaks` for the
|
||||||
/// first expression and `IfBreaksParenthesized` for the rest.
|
/// first expression and `IfBreaksParenthesized` for the rest.
|
||||||
IfBreaksParenthesized,
|
IfBreaksParenthesized,
|
||||||
|
|
||||||
/// Same as [`Self::IfBreaksParenthesized`] but uses [`parenthesize_if_expands`] for nested
|
/// Same as [`Self::IfBreaksParenthesized`] but uses
|
||||||
/// [`maybe_parenthesized_expression`] calls unlike other layouts that always omit parentheses
|
/// [`parenthesize_if_expands`](crate::builders::parenthesize_if_expands) for nested
|
||||||
/// when outer parentheses are present.
|
/// [`maybe_parenthesized_expression`](crate::expression::maybe_parenthesize_expression) calls
|
||||||
|
/// unlike other layouts that always omit parentheses when outer parentheses are present.
|
||||||
IfBreaksParenthesizedNested,
|
IfBreaksParenthesizedNested,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -214,8 +214,9 @@ impl Format<PyFormatContext<'_>> for MaybeParenthesizePattern<'_> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// This function is very similar to [`can_omit_optional_parentheses`] with the only difference that it is for patterns
|
/// This function is very similar to
|
||||||
/// and not expressions.
|
/// [`can_omit_optional_parentheses`](crate::expression::can_omit_optional_parentheses)
|
||||||
|
/// with the only difference that it is for patterns and not expressions.
|
||||||
///
|
///
|
||||||
/// The base idea of the omit optional parentheses layout is to prefer using parentheses of sub-patterns
|
/// The base idea of the omit optional parentheses layout is to prefer using parentheses of sub-patterns
|
||||||
/// when splitting the pattern over introducing new patterns. For example, prefer splitting the sequence pattern in
|
/// when splitting the pattern over introducing new patterns. For example, prefer splitting the sequence pattern in
|
||||||
|
|
|
||||||
|
|
@ -72,8 +72,9 @@ impl FormatNodeRule<PatternArguments> for FormatPatternArguments {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns `true` if the pattern (which is the only argument to a [`PatternMatchClass`]) is
|
/// Returns `true` if the pattern (which is the only argument to a
|
||||||
/// parenthesized. Used to avoid falsely assuming that `x` is parenthesized in cases like:
|
/// [`PatternMatchClass`](ruff_python_ast::PatternMatchClass)) is parenthesized.
|
||||||
|
/// Used to avoid falsely assuming that `x` is parenthesized in cases like:
|
||||||
/// ```python
|
/// ```python
|
||||||
/// case Point2D(x): ...
|
/// case Point2D(x): ...
|
||||||
/// ```
|
/// ```
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,8 @@ use crate::{FormatModuleError, PyFormatOptions, format_module_source};
|
||||||
///
|
///
|
||||||
/// The returned formatted range guarantees to cover at least `range` (excluding whitespace), but the range might be larger.
|
/// The returned formatted range guarantees to cover at least `range` (excluding whitespace), but the range might be larger.
|
||||||
/// Some cases in which the returned range is larger than `range` are:
|
/// Some cases in which the returned range is larger than `range` are:
|
||||||
/// * The logical lines in `range` use a indentation different from the configured [`IndentStyle`] and [`IndentWidth`].
|
/// * The logical lines in `range` use a indentation different from the configured [`IndentStyle`]
|
||||||
|
/// and [`IndentWidth`](ruff_formatter::IndentWidth).
|
||||||
/// * `range` is smaller than a logical lines and the formatter needs to format the entire logical line.
|
/// * `range` is smaller than a logical lines and the formatter needs to format the entire logical line.
|
||||||
/// * `range` falls on a single line body.
|
/// * `range` falls on a single line body.
|
||||||
///
|
///
|
||||||
|
|
@ -129,16 +130,19 @@ pub fn format_range(
|
||||||
/// b) formatting a sub-expression has fewer split points than formatting the entire expressions.
|
/// b) formatting a sub-expression has fewer split points than formatting the entire expressions.
|
||||||
///
|
///
|
||||||
/// ### Possible docstrings
|
/// ### Possible docstrings
|
||||||
/// Strings that are suspected to be docstrings are excluded from the search to format the enclosing suite instead
|
/// Strings that are suspected to be docstrings are excluded from the search to format the enclosing
|
||||||
/// so that the formatter's docstring detection in [`FormatSuite`] correctly detects and formats the docstrings.
|
/// suite instead so that the formatter's docstring detection in
|
||||||
|
/// [`FormatSuite`](crate::statement::suite::FormatSuite) correctly detects and formats the
|
||||||
|
/// docstrings.
|
||||||
///
|
///
|
||||||
/// ### Compound statements with a simple statement body
|
/// ### Compound statements with a simple statement body
|
||||||
/// Don't include simple-statement bodies of compound statements `if True: pass` because the formatter
|
/// Don't include simple-statement bodies of compound statements `if True: pass` because the formatter
|
||||||
/// must run [`FormatClauseBody`] to determine if the body should be collapsed or not.
|
/// must run `FormatClauseBody` to determine if the body should be collapsed or not.
|
||||||
///
|
///
|
||||||
/// ### Incorrectly indented code
|
/// ### Incorrectly indented code
|
||||||
/// Code that uses indentations that don't match the configured [`IndentStyle`] and [`IndentWidth`] are excluded from the search,
|
/// Code that uses indentations that don't match the configured [`IndentStyle`] and
|
||||||
/// because formatting such nodes on their own can lead to indentation mismatch with its sibling nodes.
|
/// [`IndentWidth`](ruff_formatter::IndentWidth) are excluded from the search, because formatting
|
||||||
|
/// such nodes on their own can lead to indentation mismatch with its sibling nodes.
|
||||||
///
|
///
|
||||||
/// ## Suppression comments
|
/// ## Suppression comments
|
||||||
/// The search ends when `range` falls into a suppressed range because there's nothing to format. It also avoids that the
|
/// The search ends when `range` falls into a suppressed range because there's nothing to format. It also avoids that the
|
||||||
|
|
@ -279,13 +283,15 @@ enum EnclosingNode<'a> {
|
||||||
///
|
///
|
||||||
/// ## Compound statements with simple statement bodies
|
/// ## Compound statements with simple statement bodies
|
||||||
/// Similar to [`find_enclosing_node`], exclude the compound statement's body if it is a simple statement (not a suite) from the search to format the entire clause header
|
/// Similar to [`find_enclosing_node`], exclude the compound statement's body if it is a simple statement (not a suite) from the search to format the entire clause header
|
||||||
/// with the body. This ensures that the formatter runs [`FormatClauseBody`] that determines if the body should be indented.s
|
/// with the body. This ensures that the formatter runs `FormatClauseBody` that determines if the body should be indented.
|
||||||
///
|
///
|
||||||
/// ## Non-standard indentation
|
/// ## Non-standard indentation
|
||||||
/// Node's that use an indentation that doesn't match the configured [`IndentStyle`] and [`IndentWidth`] are excluded from the search.
|
/// Nodes that use an indentation that doesn't match the configured [`IndentStyle`] and
|
||||||
/// This is because the formatter always uses the configured [`IndentStyle`] and [`IndentWidth`], resulting in the
|
/// [`IndentWidth`](ruff_formatter::IndentWidth) are excluded from the search. This is because the
|
||||||
/// formatted nodes using a different indentation than the unformatted sibling nodes. This would be tolerable
|
/// formatter always uses the configured [`IndentStyle`] and
|
||||||
/// in non whitespace sensitive languages like JavaScript but results in lexical errors in Python.
|
/// [`IndentWidth`](ruff_formatter::IndentWidth), resulting in the formatted nodes using a different
|
||||||
|
/// indentation than the unformatted sibling nodes. This would be tolerable in non whitespace
|
||||||
|
/// sensitive languages like JavaScript but results in lexical errors in Python.
|
||||||
///
|
///
|
||||||
/// ## Implementation
|
/// ## Implementation
|
||||||
/// It would probably be possible to merge this visitor with [`FindEnclosingNode`] but they are separate because
|
/// It would probably be possible to merge this visitor with [`FindEnclosingNode`] but they are separate because
|
||||||
|
|
@ -713,9 +719,11 @@ impl Format<PyFormatContext<'_>> for FormatEnclosingNode<'_> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Computes the level of indentation for `indentation` when using the configured [`IndentStyle`] and [`IndentWidth`].
|
/// Computes the level of indentation for `indentation` when using the configured [`IndentStyle`]
|
||||||
|
/// and [`IndentWidth`](ruff_formatter::IndentWidth).
|
||||||
///
|
///
|
||||||
/// Returns `None` if the indentation doesn't conform to the configured [`IndentStyle`] and [`IndentWidth`].
|
/// Returns `None` if the indentation doesn't conform to the configured [`IndentStyle`] and
|
||||||
|
/// [`IndentWidth`](ruff_formatter::IndentWidth).
|
||||||
///
|
///
|
||||||
/// # Panics
|
/// # Panics
|
||||||
/// If `offset` is outside of `source`.
|
/// If `offset` is outside of `source`.
|
||||||
|
|
|
||||||
|
|
@ -184,7 +184,7 @@ impl Format<PyFormatContext<'_>> for FormatTargetWithEqualOperator<'_> {
|
||||||
/// No parentheses are added for `short` because it fits into the configured line length, regardless of whether
|
/// No parentheses are added for `short` because it fits into the configured line length, regardless of whether
|
||||||
/// the comment exceeds the line width or not.
|
/// the comment exceeds the line width or not.
|
||||||
///
|
///
|
||||||
/// This logic isn't implemented in [`place_comment`] by associating trailing statement comments to the expression because
|
/// This logic isn't implemented in `place_comment` by associating trailing statement comments to the expression because
|
||||||
/// doing so breaks the suite empty lines formatting that relies on trailing comments to be stored on the statement.
|
/// doing so breaks the suite empty lines formatting that relies on trailing comments to be stored on the statement.
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub(super) enum FormatStatementsLastExpression<'a> {
|
pub(super) enum FormatStatementsLastExpression<'a> {
|
||||||
|
|
@ -202,8 +202,8 @@ pub(super) enum FormatStatementsLastExpression<'a> {
|
||||||
/// ] = some_long_value
|
/// ] = some_long_value
|
||||||
/// ```
|
/// ```
|
||||||
///
|
///
|
||||||
/// This layout is preferred over [`RightToLeft`] if the left is unsplittable (single keyword like `return` or a Name)
|
/// This layout is preferred over [`Self::RightToLeft`] if the left is unsplittable (single
|
||||||
/// because it has better performance characteristics.
|
/// keyword like `return` or a Name) because it has better performance characteristics.
|
||||||
LeftToRight {
|
LeftToRight {
|
||||||
/// The right side of an assignment or the value returned in a return statement.
|
/// The right side of an assignment or the value returned in a return statement.
|
||||||
value: &'a Expr,
|
value: &'a Expr,
|
||||||
|
|
@ -1083,11 +1083,10 @@ impl Format<PyFormatContext<'_>> for InterpolatedString<'_> {
|
||||||
/// For legibility, we discuss only the case of f-strings below, but the
|
/// For legibility, we discuss only the case of f-strings below, but the
|
||||||
/// same comments apply to t-strings.
|
/// same comments apply to t-strings.
|
||||||
///
|
///
|
||||||
/// This is just a wrapper around [`FormatFString`] while considering a special
|
/// This is just a wrapper around [`FormatFString`](crate::other::f_string::FormatFString) while
|
||||||
/// case when the f-string is at an assignment statement's value position.
|
/// considering a special case when the f-string is at an assignment statement's value position.
|
||||||
/// This is necessary to prevent an instability where an f-string contains a
|
/// This is necessary to prevent an instability where an f-string contains a multiline expression
|
||||||
/// multiline expression and the f-string fits on the line, but only when it's
|
/// and the f-string fits on the line, but only when it's surrounded by parentheses.
|
||||||
/// surrounded by parentheses.
|
|
||||||
///
|
///
|
||||||
/// ```python
|
/// ```python
|
||||||
/// aaaaaaaaaaaaaaaaaa = f"testeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee{
|
/// aaaaaaaaaaaaaaaaaa = f"testeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee{
|
||||||
|
|
|
||||||
|
|
@ -177,8 +177,10 @@ enum WithItemsLayout<'a> {
|
||||||
/// ...
|
/// ...
|
||||||
/// ```
|
/// ```
|
||||||
///
|
///
|
||||||
/// In this case, use [`maybe_parenthesize_expression`] to format the context expression
|
/// In this case, use
|
||||||
/// to get the exact same formatting as when formatting an expression in any other clause header.
|
/// [`maybe_parenthesize_expression`](crate::expression::maybe_parenthesize_expression) to
|
||||||
|
/// format the context expression to get the exact same formatting as when formatting an
|
||||||
|
/// expression in any other clause header.
|
||||||
///
|
///
|
||||||
/// Only used for Python 3.9+
|
/// Only used for Python 3.9+
|
||||||
///
|
///
|
||||||
|
|
|
||||||
|
|
@ -783,7 +783,7 @@ enum CodeExampleKind<'src> {
|
||||||
///
|
///
|
||||||
/// Documentation describing doctests and how they're recognized can be
|
/// Documentation describing doctests and how they're recognized can be
|
||||||
/// found as part of the Python standard library:
|
/// found as part of the Python standard library:
|
||||||
/// https://docs.python.org/3/library/doctest.html.
|
/// <https://docs.python.org/3/library/doctest.html>.
|
||||||
///
|
///
|
||||||
/// (You'll likely need to read the [regex matching] used internally by the
|
/// (You'll likely need to read the [regex matching] used internally by the
|
||||||
/// doctest module to determine more precisely how it works.)
|
/// doctest module to determine more precisely how it works.)
|
||||||
|
|
|
||||||
|
|
@ -38,8 +38,9 @@ impl<'a, 'src> StringNormalizer<'a, 'src> {
|
||||||
/// it can't because the string contains the preferred quotes OR
|
/// it can't because the string contains the preferred quotes OR
|
||||||
/// it leads to more escaping.
|
/// it leads to more escaping.
|
||||||
///
|
///
|
||||||
/// Note: If you add more cases here where we return `QuoteStyle::Preserve`,
|
/// Note: If you add more cases here where we return `QuoteStyle::Preserve`, make sure to also
|
||||||
/// make sure to also add them to [`FormatImplicitConcatenatedStringFlat::new`].
|
/// add them to
|
||||||
|
/// [`FormatImplicitConcatenatedStringFlat::new`](crate::string::implicit::FormatImplicitConcatenatedStringFlat::new).
|
||||||
pub(super) fn preferred_quote_style(&self, string: StringLikePart) -> QuoteStyle {
|
pub(super) fn preferred_quote_style(&self, string: StringLikePart) -> QuoteStyle {
|
||||||
let preferred_quote_style = self
|
let preferred_quote_style = self
|
||||||
.preferred_quote_style
|
.preferred_quote_style
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@ use crate::prelude::*;
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
pub struct FormatTypeParams;
|
pub struct FormatTypeParams;
|
||||||
|
|
||||||
/// Formats a sequence of [`TypeParam`] nodes.
|
/// Formats a sequence of [`TypeParam`](ruff_python_ast::TypeParam) nodes.
|
||||||
impl FormatNodeRule<TypeParams> for FormatTypeParams {
|
impl FormatNodeRule<TypeParams> for FormatTypeParams {
|
||||||
fn fmt_fields(&self, item: &TypeParams, f: &mut PyFormatter) -> FormatResult<()> {
|
fn fmt_fields(&self, item: &TypeParams, f: &mut PyFormatter) -> FormatResult<()> {
|
||||||
// A dangling comment indicates a comment on the same line as the opening bracket, e.g.:
|
// A dangling comment indicates a comment on the same line as the opening bracket, e.g.:
|
||||||
|
|
|
||||||
|
|
@ -679,8 +679,9 @@ impl Indentation {
|
||||||
|
|
||||||
/// Returns `true` for a space or tab character.
|
/// Returns `true` for a space or tab character.
|
||||||
///
|
///
|
||||||
/// This is different than [`is_python_whitespace`] in that it returns `false` for a form feed character.
|
/// This is different than [`is_python_whitespace`](ruff_python_trivia::is_python_whitespace) in
|
||||||
/// Form feed characters are excluded because they should be preserved in the suppressed output.
|
/// that it returns `false` for a form feed character. Form feed characters are excluded because
|
||||||
|
/// they should be preserved in the suppressed output.
|
||||||
const fn is_indent_whitespace(c: char) -> bool {
|
const fn is_indent_whitespace(c: char) -> bool {
|
||||||
matches!(c, ' ' | '\t')
|
matches!(c, ' ' | '\t')
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -35,6 +35,7 @@ ruff_source_file = { workspace = true }
|
||||||
|
|
||||||
anyhow = { workspace = true }
|
anyhow = { workspace = true }
|
||||||
insta = { workspace = true, features = ["glob"] }
|
insta = { workspace = true, features = ["glob"] }
|
||||||
|
itertools = { workspace = true }
|
||||||
serde = { workspace = true }
|
serde = { workspace = true }
|
||||||
serde_json = { workspace = true }
|
serde_json = { workspace = true }
|
||||||
walkdir = { workspace = true }
|
walkdir = { workspace = true }
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,5 @@
|
||||||
|
# Regression test for https://github.com/astral-sh/ty/issues/1828
|
||||||
|
(c: int = 1,f"""{d=[
|
||||||
|
def a(
|
||||||
|
class A:
|
||||||
|
pass
|
||||||
|
|
@ -67,26 +67,59 @@ impl<'src> TokenSource<'src> {
|
||||||
///
|
///
|
||||||
/// [`re_lex_logical_token`]: Lexer::re_lex_logical_token
|
/// [`re_lex_logical_token`]: Lexer::re_lex_logical_token
|
||||||
pub(crate) fn re_lex_logical_token(&mut self) {
|
pub(crate) fn re_lex_logical_token(&mut self) {
|
||||||
let mut non_logical_newline_start = None;
|
let mut non_logical_newline = None;
|
||||||
for token in self.tokens.iter().rev() {
|
|
||||||
|
#[cfg(debug_assertions)]
|
||||||
|
let last_non_trivia_end_before = {
|
||||||
|
self.tokens
|
||||||
|
.iter()
|
||||||
|
.rev()
|
||||||
|
.find(|tok| !tok.kind().is_trivia())
|
||||||
|
.map(ruff_text_size::Ranged::end)
|
||||||
|
};
|
||||||
|
|
||||||
|
for (index, token) in self.tokens.iter().enumerate().rev() {
|
||||||
match token.kind() {
|
match token.kind() {
|
||||||
TokenKind::NonLogicalNewline => {
|
TokenKind::NonLogicalNewline => {
|
||||||
non_logical_newline_start = Some(token.start());
|
non_logical_newline = Some((index, token.start()));
|
||||||
}
|
}
|
||||||
TokenKind::Comment => continue,
|
TokenKind::Comment => continue,
|
||||||
_ => break,
|
_ => break,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if self.lexer.re_lex_logical_token(non_logical_newline_start) {
|
if !self
|
||||||
let current_start = self.current_range().start();
|
.lexer
|
||||||
while self
|
.re_lex_logical_token(non_logical_newline.map(|(_, start)| start))
|
||||||
.tokens
|
{
|
||||||
.last()
|
return;
|
||||||
.is_some_and(|last| last.start() >= current_start)
|
}
|
||||||
{
|
|
||||||
self.tokens.pop();
|
let non_logical_line_index = non_logical_newline
|
||||||
}
|
.expect(
|
||||||
|
"`re_lex_logical_token` should only return `true` if `non_logical_line` is `Some`",
|
||||||
|
)
|
||||||
|
.0;
|
||||||
|
|
||||||
|
// Trim the already bumped logical line token (and comments coming after it) as it might now have become a logical line token
|
||||||
|
self.tokens.truncate(non_logical_line_index);
|
||||||
|
|
||||||
|
#[cfg(debug_assertions)]
|
||||||
|
{
|
||||||
|
let last_non_trivia_end_now = {
|
||||||
|
self.tokens
|
||||||
|
.iter()
|
||||||
|
.rev()
|
||||||
|
.find(|tok| !tok.kind().is_trivia())
|
||||||
|
.map(ruff_text_size::Ranged::end)
|
||||||
|
};
|
||||||
|
|
||||||
|
assert_eq!(last_non_trivia_end_before, last_non_trivia_end_now);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ensure `current` is positioned at a non-trivia token.
|
||||||
|
if self.current_kind().is_trivia() {
|
||||||
|
self.bump(self.current_kind());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -4,15 +4,16 @@ use std::fmt::{Formatter, Write};
|
||||||
use std::fs;
|
use std::fs;
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
|
|
||||||
|
use itertools::Itertools;
|
||||||
use ruff_annotate_snippets::{Level, Renderer, Snippet};
|
use ruff_annotate_snippets::{Level, Renderer, Snippet};
|
||||||
use ruff_python_ast::token::Token;
|
use ruff_python_ast::token::{Token, Tokens};
|
||||||
use ruff_python_ast::visitor::Visitor;
|
use ruff_python_ast::visitor::Visitor;
|
||||||
use ruff_python_ast::visitor::source_order::{SourceOrderVisitor, TraversalSignal, walk_module};
|
use ruff_python_ast::visitor::source_order::{SourceOrderVisitor, TraversalSignal, walk_module};
|
||||||
use ruff_python_ast::{self as ast, AnyNodeRef, Mod, PythonVersion};
|
use ruff_python_ast::{self as ast, AnyNodeRef, Mod, PythonVersion};
|
||||||
use ruff_python_parser::semantic_errors::{
|
use ruff_python_parser::semantic_errors::{
|
||||||
SemanticSyntaxChecker, SemanticSyntaxContext, SemanticSyntaxError,
|
SemanticSyntaxChecker, SemanticSyntaxContext, SemanticSyntaxError,
|
||||||
};
|
};
|
||||||
use ruff_python_parser::{Mode, ParseErrorType, ParseOptions, parse_unchecked};
|
use ruff_python_parser::{Mode, ParseErrorType, ParseOptions, Parsed, parse_unchecked};
|
||||||
use ruff_source_file::{LineIndex, OneIndexed, SourceCode};
|
use ruff_source_file::{LineIndex, OneIndexed, SourceCode};
|
||||||
use ruff_text_size::{Ranged, TextLen, TextRange, TextSize};
|
use ruff_text_size::{Ranged, TextLen, TextRange, TextSize};
|
||||||
|
|
||||||
|
|
@ -81,7 +82,7 @@ fn test_valid_syntax(input_path: &Path) {
|
||||||
}
|
}
|
||||||
|
|
||||||
validate_tokens(parsed.tokens(), source.text_len(), input_path);
|
validate_tokens(parsed.tokens(), source.text_len(), input_path);
|
||||||
validate_ast(parsed.syntax(), source.text_len(), input_path);
|
validate_ast(&parsed, source.text_len(), input_path);
|
||||||
|
|
||||||
let mut output = String::new();
|
let mut output = String::new();
|
||||||
writeln!(&mut output, "## AST").unwrap();
|
writeln!(&mut output, "## AST").unwrap();
|
||||||
|
|
@ -139,7 +140,7 @@ fn test_invalid_syntax(input_path: &Path) {
|
||||||
let parsed = parse_unchecked(&source, options.clone());
|
let parsed = parse_unchecked(&source, options.clone());
|
||||||
|
|
||||||
validate_tokens(parsed.tokens(), source.text_len(), input_path);
|
validate_tokens(parsed.tokens(), source.text_len(), input_path);
|
||||||
validate_ast(parsed.syntax(), source.text_len(), input_path);
|
validate_ast(&parsed, source.text_len(), input_path);
|
||||||
|
|
||||||
let mut output = String::new();
|
let mut output = String::new();
|
||||||
writeln!(&mut output, "## AST").unwrap();
|
writeln!(&mut output, "## AST").unwrap();
|
||||||
|
|
@ -402,12 +403,16 @@ Tokens: {tokens:#?}
|
||||||
/// * the range of the parent node fully encloses all its child nodes
|
/// * the range of the parent node fully encloses all its child nodes
|
||||||
/// * the ranges are strictly increasing when traversing the nodes in pre-order.
|
/// * the ranges are strictly increasing when traversing the nodes in pre-order.
|
||||||
/// * all ranges are within the length of the source code.
|
/// * all ranges are within the length of the source code.
|
||||||
fn validate_ast(root: &Mod, source_len: TextSize, test_path: &Path) {
|
fn validate_ast(parsed: &Parsed<Mod>, source_len: TextSize, test_path: &Path) {
|
||||||
walk_module(&mut ValidateAstVisitor::new(source_len, test_path), root);
|
walk_module(
|
||||||
|
&mut ValidateAstVisitor::new(parsed.tokens(), source_len, test_path),
|
||||||
|
parsed.syntax(),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
struct ValidateAstVisitor<'a> {
|
struct ValidateAstVisitor<'a> {
|
||||||
|
tokens: std::iter::Peekable<std::slice::Iter<'a, Token>>,
|
||||||
parents: Vec<AnyNodeRef<'a>>,
|
parents: Vec<AnyNodeRef<'a>>,
|
||||||
previous: Option<AnyNodeRef<'a>>,
|
previous: Option<AnyNodeRef<'a>>,
|
||||||
source_length: TextSize,
|
source_length: TextSize,
|
||||||
|
|
@ -415,8 +420,9 @@ struct ValidateAstVisitor<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> ValidateAstVisitor<'a> {
|
impl<'a> ValidateAstVisitor<'a> {
|
||||||
fn new(source_length: TextSize, test_path: &'a Path) -> Self {
|
fn new(tokens: &'a Tokens, source_length: TextSize, test_path: &'a Path) -> Self {
|
||||||
Self {
|
Self {
|
||||||
|
tokens: tokens.iter().peekable(),
|
||||||
parents: Vec::new(),
|
parents: Vec::new(),
|
||||||
previous: None,
|
previous: None,
|
||||||
source_length,
|
source_length,
|
||||||
|
|
@ -425,6 +431,47 @@ impl<'a> ValidateAstVisitor<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl ValidateAstVisitor<'_> {
|
||||||
|
/// Check that the node's start doesn't fall within a token.
|
||||||
|
/// Called in `enter_node` before visiting children.
|
||||||
|
fn assert_start_boundary(&mut self, node: AnyNodeRef<'_>) {
|
||||||
|
// Skip tokens that end at or before the node starts.
|
||||||
|
self.tokens
|
||||||
|
.peeking_take_while(|t| t.end() <= node.start())
|
||||||
|
.last();
|
||||||
|
|
||||||
|
if let Some(next) = self.tokens.peek() {
|
||||||
|
// At this point, next_token.end() > node.start()
|
||||||
|
assert!(
|
||||||
|
next.start() >= node.start(),
|
||||||
|
"{path}: The start of the node falls within a token.\nNode: {node:#?}\n\nToken: {next:#?}\n\nRoot: {root:#?}",
|
||||||
|
path = self.test_path.display(),
|
||||||
|
root = self.parents.first()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Check that the node's end doesn't fall within a token.
|
||||||
|
/// Called in `leave_node` after visiting children, so all tokens
|
||||||
|
/// within the node have been consumed.
|
||||||
|
fn assert_end_boundary(&mut self, node: AnyNodeRef<'_>) {
|
||||||
|
// Skip tokens that end at or before the node ends.
|
||||||
|
self.tokens
|
||||||
|
.peeking_take_while(|t| t.end() <= node.end())
|
||||||
|
.last();
|
||||||
|
|
||||||
|
if let Some(next) = self.tokens.peek() {
|
||||||
|
// At this point, `next_token.end() > node.end()`
|
||||||
|
assert!(
|
||||||
|
next.start() >= node.end(),
|
||||||
|
"{path}: The end of the node falls within a token.\nNode: {node:#?}\n\nToken: {next:#?}\n\nRoot: {root:#?}",
|
||||||
|
path = self.test_path.display(),
|
||||||
|
root = self.parents.first()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<'ast> SourceOrderVisitor<'ast> for ValidateAstVisitor<'ast> {
|
impl<'ast> SourceOrderVisitor<'ast> for ValidateAstVisitor<'ast> {
|
||||||
fn enter_node(&mut self, node: AnyNodeRef<'ast>) -> TraversalSignal {
|
fn enter_node(&mut self, node: AnyNodeRef<'ast>) -> TraversalSignal {
|
||||||
assert!(
|
assert!(
|
||||||
|
|
@ -452,12 +499,16 @@ impl<'ast> SourceOrderVisitor<'ast> for ValidateAstVisitor<'ast> {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
self.assert_start_boundary(node);
|
||||||
|
|
||||||
self.parents.push(node);
|
self.parents.push(node);
|
||||||
|
|
||||||
TraversalSignal::Traverse
|
TraversalSignal::Traverse
|
||||||
}
|
}
|
||||||
|
|
||||||
fn leave_node(&mut self, node: AnyNodeRef<'ast>) {
|
fn leave_node(&mut self, node: AnyNodeRef<'ast>) {
|
||||||
|
self.assert_end_boundary(node);
|
||||||
|
|
||||||
self.parents.pop().expect("Expected tree to be balanced");
|
self.parents.pop().expect("Expected tree to be balanced");
|
||||||
|
|
||||||
self.previous = Some(node);
|
self.previous = Some(node);
|
||||||
|
|
|
||||||
|
|
@ -296,7 +296,7 @@ Module(
|
||||||
test: Call(
|
test: Call(
|
||||||
ExprCall {
|
ExprCall {
|
||||||
node_index: NodeIndex(None),
|
node_index: NodeIndex(None),
|
||||||
range: 456..472,
|
range: 456..471,
|
||||||
func: Name(
|
func: Name(
|
||||||
ExprName {
|
ExprName {
|
||||||
node_index: NodeIndex(None),
|
node_index: NodeIndex(None),
|
||||||
|
|
@ -306,7 +306,7 @@ Module(
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
arguments: Arguments {
|
arguments: Arguments {
|
||||||
range: 460..472,
|
range: 460..471,
|
||||||
node_index: NodeIndex(None),
|
node_index: NodeIndex(None),
|
||||||
args: [
|
args: [
|
||||||
Name(
|
Name(
|
||||||
|
|
@ -581,7 +581,7 @@ Module(
|
||||||
test: Call(
|
test: Call(
|
||||||
ExprCall {
|
ExprCall {
|
||||||
node_index: NodeIndex(None),
|
node_index: NodeIndex(None),
|
||||||
range: 890..906,
|
range: 890..905,
|
||||||
func: Name(
|
func: Name(
|
||||||
ExprName {
|
ExprName {
|
||||||
node_index: NodeIndex(None),
|
node_index: NodeIndex(None),
|
||||||
|
|
@ -591,7 +591,7 @@ Module(
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
arguments: Arguments {
|
arguments: Arguments {
|
||||||
range: 894..906,
|
range: 894..905,
|
||||||
node_index: NodeIndex(None),
|
node_index: NodeIndex(None),
|
||||||
args: [
|
args: [
|
||||||
FString(
|
FString(
|
||||||
|
|
@ -832,7 +832,16 @@ Module(
|
||||||
|
|
|
|
||||||
28 | # The lexer is nested with multiple levels of parentheses
|
28 | # The lexer is nested with multiple levels of parentheses
|
||||||
29 | if call(foo, [a, b
|
29 | if call(foo, [a, b
|
||||||
| ^ Syntax Error: Expected `]`, found NonLogicalNewline
|
30 | def bar():
|
||||||
|
| ^^^ Syntax Error: Expected `]`, found `def`
|
||||||
|
31 | pass
|
||||||
|
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
28 | # The lexer is nested with multiple levels of parentheses
|
||||||
|
29 | if call(foo, [a, b
|
||||||
|
| ^ Syntax Error: Expected `)`, found newline
|
||||||
30 | def bar():
|
30 | def bar():
|
||||||
31 | pass
|
31 | pass
|
||||||
|
|
|
|
||||||
|
|
@ -857,11 +866,10 @@ Module(
|
||||||
|
|
||||||
|
|
||||||
|
|
|
|
||||||
41 | # test is to make sure it emits a `NonLogicalNewline` token after `b`.
|
|
||||||
42 | if call(foo, [a,
|
42 | if call(foo, [a,
|
||||||
43 | b
|
43 | b
|
||||||
| ^ Syntax Error: Expected `]`, found NonLogicalNewline
|
|
||||||
44 | )
|
44 | )
|
||||||
|
| ^ Syntax Error: Expected `]`, found `)`
|
||||||
45 | def bar():
|
45 | def bar():
|
||||||
46 | pass
|
46 | pass
|
||||||
|
|
|
|
||||||
|
|
@ -898,7 +906,7 @@ Module(
|
||||||
|
|
|
|
||||||
49 | # F-strings uses normal list parsing, so test those as well
|
49 | # F-strings uses normal list parsing, so test those as well
|
||||||
50 | if call(f"hello {x
|
50 | if call(f"hello {x
|
||||||
| ^ Syntax Error: Expected FStringEnd, found NonLogicalNewline
|
| ^ Syntax Error: Expected `)`, found newline
|
||||||
51 | def bar():
|
51 | def bar():
|
||||||
52 | pass
|
52 | pass
|
||||||
|
|
|
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@ Module(
|
||||||
test: Call(
|
test: Call(
|
||||||
ExprCall {
|
ExprCall {
|
||||||
node_index: NodeIndex(None),
|
node_index: NodeIndex(None),
|
||||||
range: 3..19,
|
range: 3..18,
|
||||||
func: Name(
|
func: Name(
|
||||||
ExprName {
|
ExprName {
|
||||||
node_index: NodeIndex(None),
|
node_index: NodeIndex(None),
|
||||||
|
|
@ -27,7 +27,7 @@ Module(
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
arguments: Arguments {
|
arguments: Arguments {
|
||||||
range: 7..19,
|
range: 7..18,
|
||||||
node_index: NodeIndex(None),
|
node_index: NodeIndex(None),
|
||||||
args: [
|
args: [
|
||||||
Name(
|
Name(
|
||||||
|
|
@ -113,5 +113,11 @@ Module(
|
||||||
|
|
||||||
|
|
|
|
||||||
1 | if call(foo, [a, b
def bar():
pass
|
1 | if call(foo, [a, b
def bar():
pass
|
||||||
| ^ Syntax Error: Expected `]`, found NonLogicalNewline
|
| ^^^ Syntax Error: Expected `]`, found `def`
|
||||||
|
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
1 | if call(foo, [a, b
def bar():
pass
|
||||||
|
| ^ Syntax Error: Expected `)`, found newline
|
||||||
|
|
|
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@ Module(
|
||||||
test: Call(
|
test: Call(
|
||||||
ExprCall {
|
ExprCall {
|
||||||
node_index: NodeIndex(None),
|
node_index: NodeIndex(None),
|
||||||
range: 3..20,
|
range: 3..18,
|
||||||
func: Name(
|
func: Name(
|
||||||
ExprName {
|
ExprName {
|
||||||
node_index: NodeIndex(None),
|
node_index: NodeIndex(None),
|
||||||
|
|
@ -27,7 +27,7 @@ Module(
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
arguments: Arguments {
|
arguments: Arguments {
|
||||||
range: 7..20,
|
range: 7..18,
|
||||||
node_index: NodeIndex(None),
|
node_index: NodeIndex(None),
|
||||||
args: [
|
args: [
|
||||||
Name(
|
Name(
|
||||||
|
|
@ -113,7 +113,15 @@ Module(
|
||||||
|
|
||||||
|
|
|
|
||||||
1 | if call(foo, [a, b
|
1 | if call(foo, [a, b
|
||||||
| ^ Syntax Error: Expected `]`, found NonLogicalNewline
|
2 | def bar():
|
||||||
|
| ^^^ Syntax Error: Expected `]`, found `def`
|
||||||
|
3 | pass
|
||||||
|
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
1 | if call(foo, [a, b
|
||||||
|
| ^ Syntax Error: Expected `)`, found newline
|
||||||
2 | def bar():
|
2 | def bar():
|
||||||
3 | pass
|
3 | pass
|
||||||
|
|
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,227 @@
|
||||||
|
---
|
||||||
|
source: crates/ruff_python_parser/tests/fixtures.rs
|
||||||
|
input_file: crates/ruff_python_parser/resources/invalid/re_lexing/ty_1828.py
|
||||||
|
---
|
||||||
|
## AST
|
||||||
|
|
||||||
|
```
|
||||||
|
Module(
|
||||||
|
ModModule {
|
||||||
|
node_index: NodeIndex(None),
|
||||||
|
range: 0..112,
|
||||||
|
body: [
|
||||||
|
AnnAssign(
|
||||||
|
StmtAnnAssign {
|
||||||
|
node_index: NodeIndex(None),
|
||||||
|
range: 66..93,
|
||||||
|
target: Name(
|
||||||
|
ExprName {
|
||||||
|
node_index: NodeIndex(None),
|
||||||
|
range: 67..68,
|
||||||
|
id: Name("c"),
|
||||||
|
ctx: Store,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
annotation: Name(
|
||||||
|
ExprName {
|
||||||
|
node_index: NodeIndex(None),
|
||||||
|
range: 70..73,
|
||||||
|
id: Name("int"),
|
||||||
|
ctx: Load,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
value: Some(
|
||||||
|
Tuple(
|
||||||
|
ExprTuple {
|
||||||
|
node_index: NodeIndex(None),
|
||||||
|
range: 76..93,
|
||||||
|
elts: [
|
||||||
|
NumberLiteral(
|
||||||
|
ExprNumberLiteral {
|
||||||
|
node_index: NodeIndex(None),
|
||||||
|
range: 76..77,
|
||||||
|
value: Int(
|
||||||
|
1,
|
||||||
|
),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
Subscript(
|
||||||
|
ExprSubscript {
|
||||||
|
node_index: NodeIndex(None),
|
||||||
|
range: 78..90,
|
||||||
|
value: FString(
|
||||||
|
ExprFString {
|
||||||
|
node_index: NodeIndex(None),
|
||||||
|
range: 78..85,
|
||||||
|
value: FStringValue {
|
||||||
|
inner: Single(
|
||||||
|
FString(
|
||||||
|
FString {
|
||||||
|
range: 78..85,
|
||||||
|
node_index: NodeIndex(None),
|
||||||
|
elements: [
|
||||||
|
Interpolation(
|
||||||
|
InterpolatedElement {
|
||||||
|
range: 82..85,
|
||||||
|
node_index: NodeIndex(None),
|
||||||
|
expression: Name(
|
||||||
|
ExprName {
|
||||||
|
node_index: NodeIndex(None),
|
||||||
|
range: 83..84,
|
||||||
|
id: Name("d"),
|
||||||
|
ctx: Load,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
debug_text: Some(
|
||||||
|
DebugText {
|
||||||
|
leading: "",
|
||||||
|
trailing: "=",
|
||||||
|
},
|
||||||
|
),
|
||||||
|
conversion: None,
|
||||||
|
format_spec: None,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
flags: FStringFlags {
|
||||||
|
quote_style: Double,
|
||||||
|
prefix: Regular,
|
||||||
|
triple_quoted: true,
|
||||||
|
unclosed: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
),
|
||||||
|
slice: Slice(
|
||||||
|
ExprSlice {
|
||||||
|
node_index: NodeIndex(None),
|
||||||
|
range: 87..90,
|
||||||
|
lower: None,
|
||||||
|
upper: Some(
|
||||||
|
Name(
|
||||||
|
ExprName {
|
||||||
|
node_index: NodeIndex(None),
|
||||||
|
range: 87..90,
|
||||||
|
id: Name("def"),
|
||||||
|
ctx: Load,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
step: None,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
ctx: Load,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
Call(
|
||||||
|
ExprCall {
|
||||||
|
node_index: NodeIndex(None),
|
||||||
|
range: 91..93,
|
||||||
|
func: Name(
|
||||||
|
ExprName {
|
||||||
|
node_index: NodeIndex(None),
|
||||||
|
range: 91..92,
|
||||||
|
id: Name("a"),
|
||||||
|
ctx: Load,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
arguments: Arguments {
|
||||||
|
range: 92..93,
|
||||||
|
node_index: NodeIndex(None),
|
||||||
|
args: [],
|
||||||
|
keywords: [],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
ctx: Load,
|
||||||
|
parenthesized: false,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
simple: false,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
},
|
||||||
|
)
|
||||||
|
```
|
||||||
|
## Errors
|
||||||
|
|
||||||
|
|
|
||||||
|
1 | # Regression test for https://github.com/astral-sh/ty/issues/1828
|
||||||
|
2 | (c: int = 1,f"""{d=[
|
||||||
|
| ^ Syntax Error: Expected `)`, found `:`
|
||||||
|
3 | def a(
|
||||||
|
4 | class A:
|
||||||
|
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
1 | # Regression test for https://github.com/astral-sh/ty/issues/1828
|
||||||
|
2 | (c: int = 1,f"""{d=[
|
||||||
|
| ^ Syntax Error: f-string: expecting `}`
|
||||||
|
3 | def a(
|
||||||
|
4 | class A:
|
||||||
|
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
1 | # Regression test for https://github.com/astral-sh/ty/issues/1828
|
||||||
|
2 | (c: int = 1,f"""{d=[
|
||||||
|
3 | def a(
|
||||||
|
| ^^^ Syntax Error: Expected `:`, found `def`
|
||||||
|
4 | class A:
|
||||||
|
5 | pass
|
||||||
|
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
1 | # Regression test for https://github.com/astral-sh/ty/issues/1828
|
||||||
|
2 | (c: int = 1,f"""{d=[
|
||||||
|
3 | def a(
|
||||||
|
| ^ Syntax Error: Expected `]`, found name
|
||||||
|
4 | class A:
|
||||||
|
5 | pass
|
||||||
|
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
1 | # Regression test for https://github.com/astral-sh/ty/issues/1828
|
||||||
|
2 | (c: int = 1,f"""{d=[
|
||||||
|
3 | def a(
|
||||||
|
| _______^
|
||||||
|
4 | | class A:
|
||||||
|
5 | | pass
|
||||||
|
| |_________^ Syntax Error: f-string: unterminated triple-quoted string
|
||||||
|
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
2 | (c: int = 1,f"""{d=[
|
||||||
|
3 | def a(
|
||||||
|
4 | class A:
|
||||||
|
| ^^^^^ Syntax Error: Expected `)`, found `class`
|
||||||
|
5 | pass
|
||||||
|
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
1 | # Regression test for https://github.com/astral-sh/ty/issues/1828
|
||||||
|
2 | (c: int = 1,f"""{d=[
|
||||||
|
3 | def a(
|
||||||
|
| _______^
|
||||||
|
4 | | class A:
|
||||||
|
5 | | pass
|
||||||
|
| |_________^ Syntax Error: Expected a statement
|
||||||
|
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
4 | class A:
|
||||||
|
5 | pass
|
||||||
|
| ^ Syntax Error: unexpected EOF while parsing
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,6 @@
|
||||||
# ty
|
# ty
|
||||||
|
|
||||||
ty is an extremely fast type checker.
|
ty is an extremely fast type checker.
|
||||||
Currently, it is a work-in-progress and not ready for production use.
|
|
||||||
|
|
||||||
The Rust code for ty lives in this repository; see [CONTRIBUTING.md](CONTRIBUTING.md) for more
|
The Rust code for ty lives in this repository; see [CONTRIBUTING.md](CONTRIBUTING.md) for more
|
||||||
information on contributing to ty.
|
information on contributing to ty.
|
||||||
|
|
|
||||||
|
|
@ -39,7 +39,7 @@ def test(): -> "int":
|
||||||
Default level: <a href="../rules.md#rule-levels" title="This lint has a default level of 'error'."><code>error</code></a> ·
|
Default level: <a href="../rules.md#rule-levels" title="This lint has a default level of 'error'."><code>error</code></a> ·
|
||||||
Added in <a href="https://github.com/astral-sh/ty/releases/tag/0.0.1-alpha.1">0.0.1-alpha.1</a> ·
|
Added in <a href="https://github.com/astral-sh/ty/releases/tag/0.0.1-alpha.1">0.0.1-alpha.1</a> ·
|
||||||
<a href="https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20call-non-callable" target="_blank">Related issues</a> ·
|
<a href="https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20call-non-callable" target="_blank">Related issues</a> ·
|
||||||
<a href="https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L135" target="_blank">View source</a>
|
<a href="https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L134" target="_blank">View source</a>
|
||||||
</small>
|
</small>
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -63,7 +63,7 @@ Calling a non-callable object will raise a `TypeError` at runtime.
|
||||||
Default level: <a href="../rules.md#rule-levels" title="This lint has a default level of 'error'."><code>error</code></a> ·
|
Default level: <a href="../rules.md#rule-levels" title="This lint has a default level of 'error'."><code>error</code></a> ·
|
||||||
Added in <a href="https://github.com/astral-sh/ty/releases/tag/0.0.1-alpha.1">0.0.1-alpha.1</a> ·
|
Added in <a href="https://github.com/astral-sh/ty/releases/tag/0.0.1-alpha.1">0.0.1-alpha.1</a> ·
|
||||||
<a href="https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20conflicting-argument-forms" target="_blank">Related issues</a> ·
|
<a href="https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20conflicting-argument-forms" target="_blank">Related issues</a> ·
|
||||||
<a href="https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L179" target="_blank">View source</a>
|
<a href="https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L178" target="_blank">View source</a>
|
||||||
</small>
|
</small>
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -95,7 +95,7 @@ f(int) # error
|
||||||
Default level: <a href="../rules.md#rule-levels" title="This lint has a default level of 'error'."><code>error</code></a> ·
|
Default level: <a href="../rules.md#rule-levels" title="This lint has a default level of 'error'."><code>error</code></a> ·
|
||||||
Added in <a href="https://github.com/astral-sh/ty/releases/tag/0.0.1-alpha.1">0.0.1-alpha.1</a> ·
|
Added in <a href="https://github.com/astral-sh/ty/releases/tag/0.0.1-alpha.1">0.0.1-alpha.1</a> ·
|
||||||
<a href="https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20conflicting-declarations" target="_blank">Related issues</a> ·
|
<a href="https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20conflicting-declarations" target="_blank">Related issues</a> ·
|
||||||
<a href="https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L205" target="_blank">View source</a>
|
<a href="https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L204" target="_blank">View source</a>
|
||||||
</small>
|
</small>
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -126,7 +126,7 @@ a = 1
|
||||||
Default level: <a href="../rules.md#rule-levels" title="This lint has a default level of 'error'."><code>error</code></a> ·
|
Default level: <a href="../rules.md#rule-levels" title="This lint has a default level of 'error'."><code>error</code></a> ·
|
||||||
Added in <a href="https://github.com/astral-sh/ty/releases/tag/0.0.1-alpha.1">0.0.1-alpha.1</a> ·
|
Added in <a href="https://github.com/astral-sh/ty/releases/tag/0.0.1-alpha.1">0.0.1-alpha.1</a> ·
|
||||||
<a href="https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20conflicting-metaclass" target="_blank">Related issues</a> ·
|
<a href="https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20conflicting-metaclass" target="_blank">Related issues</a> ·
|
||||||
<a href="https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L230" target="_blank">View source</a>
|
<a href="https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L229" target="_blank">View source</a>
|
||||||
</small>
|
</small>
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -158,7 +158,7 @@ class C(A, B): ...
|
||||||
Default level: <a href="../rules.md#rule-levels" title="This lint has a default level of 'error'."><code>error</code></a> ·
|
Default level: <a href="../rules.md#rule-levels" title="This lint has a default level of 'error'."><code>error</code></a> ·
|
||||||
Added in <a href="https://github.com/astral-sh/ty/releases/tag/0.0.1-alpha.1">0.0.1-alpha.1</a> ·
|
Added in <a href="https://github.com/astral-sh/ty/releases/tag/0.0.1-alpha.1">0.0.1-alpha.1</a> ·
|
||||||
<a href="https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20cyclic-class-definition" target="_blank">Related issues</a> ·
|
<a href="https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20cyclic-class-definition" target="_blank">Related issues</a> ·
|
||||||
<a href="https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L256" target="_blank">View source</a>
|
<a href="https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L255" target="_blank">View source</a>
|
||||||
</small>
|
</small>
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -190,7 +190,7 @@ class B(A): ...
|
||||||
Default level: <a href="../rules.md#rule-levels" title="This lint has a default level of 'error'."><code>error</code></a> ·
|
Default level: <a href="../rules.md#rule-levels" title="This lint has a default level of 'error'."><code>error</code></a> ·
|
||||||
Preview (since <a href="https://github.com/astral-sh/ty/releases/tag/1.0.0">1.0.0</a>) ·
|
Preview (since <a href="https://github.com/astral-sh/ty/releases/tag/1.0.0">1.0.0</a>) ·
|
||||||
<a href="https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20cyclic-type-alias-definition" target="_blank">Related issues</a> ·
|
<a href="https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20cyclic-type-alias-definition" target="_blank">Related issues</a> ·
|
||||||
<a href="https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L282" target="_blank">View source</a>
|
<a href="https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L281" target="_blank">View source</a>
|
||||||
</small>
|
</small>
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -218,7 +218,7 @@ type B = A
|
||||||
Default level: <a href="../rules.md#rule-levels" title="This lint has a default level of 'error'."><code>error</code></a> ·
|
Default level: <a href="../rules.md#rule-levels" title="This lint has a default level of 'error'."><code>error</code></a> ·
|
||||||
Added in <a href="https://github.com/astral-sh/ty/releases/tag/0.0.1-alpha.1">0.0.1-alpha.1</a> ·
|
Added in <a href="https://github.com/astral-sh/ty/releases/tag/0.0.1-alpha.1">0.0.1-alpha.1</a> ·
|
||||||
<a href="https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20duplicate-base" target="_blank">Related issues</a> ·
|
<a href="https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20duplicate-base" target="_blank">Related issues</a> ·
|
||||||
<a href="https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L343" target="_blank">View source</a>
|
<a href="https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L342" target="_blank">View source</a>
|
||||||
</small>
|
</small>
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -245,7 +245,7 @@ class B(A, A): ...
|
||||||
Default level: <a href="../rules.md#rule-levels" title="This lint has a default level of 'error'."><code>error</code></a> ·
|
Default level: <a href="../rules.md#rule-levels" title="This lint has a default level of 'error'."><code>error</code></a> ·
|
||||||
Added in <a href="https://github.com/astral-sh/ty/releases/tag/0.0.1-alpha.12">0.0.1-alpha.12</a> ·
|
Added in <a href="https://github.com/astral-sh/ty/releases/tag/0.0.1-alpha.12">0.0.1-alpha.12</a> ·
|
||||||
<a href="https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20duplicate-kw-only" target="_blank">Related issues</a> ·
|
<a href="https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20duplicate-kw-only" target="_blank">Related issues</a> ·
|
||||||
<a href="https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L364" target="_blank">View source</a>
|
<a href="https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L363" target="_blank">View source</a>
|
||||||
</small>
|
</small>
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -357,7 +357,7 @@ def test(): -> "Literal[5]":
|
||||||
Default level: <a href="../rules.md#rule-levels" title="This lint has a default level of 'error'."><code>error</code></a> ·
|
Default level: <a href="../rules.md#rule-levels" title="This lint has a default level of 'error'."><code>error</code></a> ·
|
||||||
Added in <a href="https://github.com/astral-sh/ty/releases/tag/0.0.1-alpha.1">0.0.1-alpha.1</a> ·
|
Added in <a href="https://github.com/astral-sh/ty/releases/tag/0.0.1-alpha.1">0.0.1-alpha.1</a> ·
|
||||||
<a href="https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20inconsistent-mro" target="_blank">Related issues</a> ·
|
<a href="https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20inconsistent-mro" target="_blank">Related issues</a> ·
|
||||||
<a href="https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L590" target="_blank">View source</a>
|
<a href="https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L589" target="_blank">View source</a>
|
||||||
</small>
|
</small>
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -387,7 +387,7 @@ class C(A, B): ...
|
||||||
Default level: <a href="../rules.md#rule-levels" title="This lint has a default level of 'error'."><code>error</code></a> ·
|
Default level: <a href="../rules.md#rule-levels" title="This lint has a default level of 'error'."><code>error</code></a> ·
|
||||||
Added in <a href="https://github.com/astral-sh/ty/releases/tag/0.0.1-alpha.1">0.0.1-alpha.1</a> ·
|
Added in <a href="https://github.com/astral-sh/ty/releases/tag/0.0.1-alpha.1">0.0.1-alpha.1</a> ·
|
||||||
<a href="https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20index-out-of-bounds" target="_blank">Related issues</a> ·
|
<a href="https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20index-out-of-bounds" target="_blank">Related issues</a> ·
|
||||||
<a href="https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L614" target="_blank">View source</a>
|
<a href="https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L613" target="_blank">View source</a>
|
||||||
</small>
|
</small>
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -413,7 +413,7 @@ t[3] # IndexError: tuple index out of range
|
||||||
Default level: <a href="../rules.md#rule-levels" title="This lint has a default level of 'error'."><code>error</code></a> ·
|
Default level: <a href="../rules.md#rule-levels" title="This lint has a default level of 'error'."><code>error</code></a> ·
|
||||||
Added in <a href="https://github.com/astral-sh/ty/releases/tag/0.0.1-alpha.12">0.0.1-alpha.12</a> ·
|
Added in <a href="https://github.com/astral-sh/ty/releases/tag/0.0.1-alpha.12">0.0.1-alpha.12</a> ·
|
||||||
<a href="https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20instance-layout-conflict" target="_blank">Related issues</a> ·
|
<a href="https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20instance-layout-conflict" target="_blank">Related issues</a> ·
|
||||||
<a href="https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L396" target="_blank">View source</a>
|
<a href="https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L395" target="_blank">View source</a>
|
||||||
</small>
|
</small>
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -502,7 +502,7 @@ an atypical memory layout.
|
||||||
Default level: <a href="../rules.md#rule-levels" title="This lint has a default level of 'error'."><code>error</code></a> ·
|
Default level: <a href="../rules.md#rule-levels" title="This lint has a default level of 'error'."><code>error</code></a> ·
|
||||||
Added in <a href="https://github.com/astral-sh/ty/releases/tag/0.0.1-alpha.1">0.0.1-alpha.1</a> ·
|
Added in <a href="https://github.com/astral-sh/ty/releases/tag/0.0.1-alpha.1">0.0.1-alpha.1</a> ·
|
||||||
<a href="https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20invalid-argument-type" target="_blank">Related issues</a> ·
|
<a href="https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20invalid-argument-type" target="_blank">Related issues</a> ·
|
||||||
<a href="https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L668" target="_blank">View source</a>
|
<a href="https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L667" target="_blank">View source</a>
|
||||||
</small>
|
</small>
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -529,7 +529,7 @@ func("foo") # error: [invalid-argument-type]
|
||||||
Default level: <a href="../rules.md#rule-levels" title="This lint has a default level of 'error'."><code>error</code></a> ·
|
Default level: <a href="../rules.md#rule-levels" title="This lint has a default level of 'error'."><code>error</code></a> ·
|
||||||
Added in <a href="https://github.com/astral-sh/ty/releases/tag/0.0.1-alpha.1">0.0.1-alpha.1</a> ·
|
Added in <a href="https://github.com/astral-sh/ty/releases/tag/0.0.1-alpha.1">0.0.1-alpha.1</a> ·
|
||||||
<a href="https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20invalid-assignment" target="_blank">Related issues</a> ·
|
<a href="https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20invalid-assignment" target="_blank">Related issues</a> ·
|
||||||
<a href="https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L708" target="_blank">View source</a>
|
<a href="https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L707" target="_blank">View source</a>
|
||||||
</small>
|
</small>
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -557,7 +557,7 @@ a: int = ''
|
||||||
Default level: <a href="../rules.md#rule-levels" title="This lint has a default level of 'error'."><code>error</code></a> ·
|
Default level: <a href="../rules.md#rule-levels" title="This lint has a default level of 'error'."><code>error</code></a> ·
|
||||||
Added in <a href="https://github.com/astral-sh/ty/releases/tag/0.0.1-alpha.1">0.0.1-alpha.1</a> ·
|
Added in <a href="https://github.com/astral-sh/ty/releases/tag/0.0.1-alpha.1">0.0.1-alpha.1</a> ·
|
||||||
<a href="https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20invalid-attribute-access" target="_blank">Related issues</a> ·
|
<a href="https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20invalid-attribute-access" target="_blank">Related issues</a> ·
|
||||||
<a href="https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L1998" target="_blank">View source</a>
|
<a href="https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L1997" target="_blank">View source</a>
|
||||||
</small>
|
</small>
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -591,7 +591,7 @@ C.instance_var = 3 # error: Cannot assign to instance variable
|
||||||
Default level: <a href="../rules.md#rule-levels" title="This lint has a default level of 'error'."><code>error</code></a> ·
|
Default level: <a href="../rules.md#rule-levels" title="This lint has a default level of 'error'."><code>error</code></a> ·
|
||||||
Added in <a href="https://github.com/astral-sh/ty/releases/tag/0.0.1-alpha.19">0.0.1-alpha.19</a> ·
|
Added in <a href="https://github.com/astral-sh/ty/releases/tag/0.0.1-alpha.19">0.0.1-alpha.19</a> ·
|
||||||
<a href="https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20invalid-await" target="_blank">Related issues</a> ·
|
<a href="https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20invalid-await" target="_blank">Related issues</a> ·
|
||||||
<a href="https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L730" target="_blank">View source</a>
|
<a href="https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L729" target="_blank">View source</a>
|
||||||
</small>
|
</small>
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -627,7 +627,7 @@ asyncio.run(main())
|
||||||
Default level: <a href="../rules.md#rule-levels" title="This lint has a default level of 'error'."><code>error</code></a> ·
|
Default level: <a href="../rules.md#rule-levels" title="This lint has a default level of 'error'."><code>error</code></a> ·
|
||||||
Added in <a href="https://github.com/astral-sh/ty/releases/tag/0.0.1-alpha.1">0.0.1-alpha.1</a> ·
|
Added in <a href="https://github.com/astral-sh/ty/releases/tag/0.0.1-alpha.1">0.0.1-alpha.1</a> ·
|
||||||
<a href="https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20invalid-base" target="_blank">Related issues</a> ·
|
<a href="https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20invalid-base" target="_blank">Related issues</a> ·
|
||||||
<a href="https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L760" target="_blank">View source</a>
|
<a href="https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L759" target="_blank">View source</a>
|
||||||
</small>
|
</small>
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -651,7 +651,7 @@ class A(42): ... # error: [invalid-base]
|
||||||
Default level: <a href="../rules.md#rule-levels" title="This lint has a default level of 'error'."><code>error</code></a> ·
|
Default level: <a href="../rules.md#rule-levels" title="This lint has a default level of 'error'."><code>error</code></a> ·
|
||||||
Added in <a href="https://github.com/astral-sh/ty/releases/tag/0.0.1-alpha.1">0.0.1-alpha.1</a> ·
|
Added in <a href="https://github.com/astral-sh/ty/releases/tag/0.0.1-alpha.1">0.0.1-alpha.1</a> ·
|
||||||
<a href="https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20invalid-context-manager" target="_blank">Related issues</a> ·
|
<a href="https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20invalid-context-manager" target="_blank">Related issues</a> ·
|
||||||
<a href="https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L811" target="_blank">View source</a>
|
<a href="https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L810" target="_blank">View source</a>
|
||||||
</small>
|
</small>
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -678,7 +678,7 @@ with 1:
|
||||||
Default level: <a href="../rules.md#rule-levels" title="This lint has a default level of 'error'."><code>error</code></a> ·
|
Default level: <a href="../rules.md#rule-levels" title="This lint has a default level of 'error'."><code>error</code></a> ·
|
||||||
Added in <a href="https://github.com/astral-sh/ty/releases/tag/0.0.1-alpha.1">0.0.1-alpha.1</a> ·
|
Added in <a href="https://github.com/astral-sh/ty/releases/tag/0.0.1-alpha.1">0.0.1-alpha.1</a> ·
|
||||||
<a href="https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20invalid-declaration" target="_blank">Related issues</a> ·
|
<a href="https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20invalid-declaration" target="_blank">Related issues</a> ·
|
||||||
<a href="https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L832" target="_blank">View source</a>
|
<a href="https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L831" target="_blank">View source</a>
|
||||||
</small>
|
</small>
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -707,7 +707,7 @@ a: str
|
||||||
Default level: <a href="../rules.md#rule-levels" title="This lint has a default level of 'error'."><code>error</code></a> ·
|
Default level: <a href="../rules.md#rule-levels" title="This lint has a default level of 'error'."><code>error</code></a> ·
|
||||||
Added in <a href="https://github.com/astral-sh/ty/releases/tag/0.0.1-alpha.1">0.0.1-alpha.1</a> ·
|
Added in <a href="https://github.com/astral-sh/ty/releases/tag/0.0.1-alpha.1">0.0.1-alpha.1</a> ·
|
||||||
<a href="https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20invalid-exception-caught" target="_blank">Related issues</a> ·
|
<a href="https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20invalid-exception-caught" target="_blank">Related issues</a> ·
|
||||||
<a href="https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L855" target="_blank">View source</a>
|
<a href="https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L854" target="_blank">View source</a>
|
||||||
</small>
|
</small>
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -751,7 +751,7 @@ except ZeroDivisionError:
|
||||||
Default level: <a href="../rules.md#rule-levels" title="This lint has a default level of 'error'."><code>error</code></a> ·
|
Default level: <a href="../rules.md#rule-levels" title="This lint has a default level of 'error'."><code>error</code></a> ·
|
||||||
Added in <a href="https://github.com/astral-sh/ty/releases/tag/0.0.1-alpha.28">0.0.1-alpha.28</a> ·
|
Added in <a href="https://github.com/astral-sh/ty/releases/tag/0.0.1-alpha.28">0.0.1-alpha.28</a> ·
|
||||||
<a href="https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20invalid-explicit-override" target="_blank">Related issues</a> ·
|
<a href="https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20invalid-explicit-override" target="_blank">Related issues</a> ·
|
||||||
<a href="https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L1668" target="_blank">View source</a>
|
<a href="https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L1667" target="_blank">View source</a>
|
||||||
</small>
|
</small>
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -793,7 +793,7 @@ class D(A):
|
||||||
Default level: <a href="../rules.md#rule-levels" title="This lint has a default level of 'error'."><code>error</code></a> ·
|
Default level: <a href="../rules.md#rule-levels" title="This lint has a default level of 'error'."><code>error</code></a> ·
|
||||||
Added in <a href="https://github.com/astral-sh/ty/releases/tag/0.0.1-alpha.1">0.0.1-alpha.1</a> ·
|
Added in <a href="https://github.com/astral-sh/ty/releases/tag/0.0.1-alpha.1">0.0.1-alpha.1</a> ·
|
||||||
<a href="https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20invalid-generic-class" target="_blank">Related issues</a> ·
|
<a href="https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20invalid-generic-class" target="_blank">Related issues</a> ·
|
||||||
<a href="https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L891" target="_blank">View source</a>
|
<a href="https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L890" target="_blank">View source</a>
|
||||||
</small>
|
</small>
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -826,7 +826,7 @@ class C[U](Generic[T]): ...
|
||||||
Default level: <a href="../rules.md#rule-levels" title="This lint has a default level of 'error'."><code>error</code></a> ·
|
Default level: <a href="../rules.md#rule-levels" title="This lint has a default level of 'error'."><code>error</code></a> ·
|
||||||
Added in <a href="https://github.com/astral-sh/ty/releases/tag/0.0.1-alpha.17">0.0.1-alpha.17</a> ·
|
Added in <a href="https://github.com/astral-sh/ty/releases/tag/0.0.1-alpha.17">0.0.1-alpha.17</a> ·
|
||||||
<a href="https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20invalid-key" target="_blank">Related issues</a> ·
|
<a href="https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20invalid-key" target="_blank">Related issues</a> ·
|
||||||
<a href="https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L635" target="_blank">View source</a>
|
<a href="https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L634" target="_blank">View source</a>
|
||||||
</small>
|
</small>
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -865,7 +865,7 @@ carol = Person(name="Carol", age=25) # typo!
|
||||||
Default level: <a href="../rules.md#rule-levels" title="This lint has a default level of 'error'."><code>error</code></a> ·
|
Default level: <a href="../rules.md#rule-levels" title="This lint has a default level of 'error'."><code>error</code></a> ·
|
||||||
Added in <a href="https://github.com/astral-sh/ty/releases/tag/0.0.1-alpha.1">0.0.1-alpha.1</a> ·
|
Added in <a href="https://github.com/astral-sh/ty/releases/tag/0.0.1-alpha.1">0.0.1-alpha.1</a> ·
|
||||||
<a href="https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20invalid-legacy-type-variable" target="_blank">Related issues</a> ·
|
<a href="https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20invalid-legacy-type-variable" target="_blank">Related issues</a> ·
|
||||||
<a href="https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L917" target="_blank">View source</a>
|
<a href="https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L916" target="_blank">View source</a>
|
||||||
</small>
|
</small>
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -900,7 +900,7 @@ def f(t: TypeVar("U")): ...
|
||||||
Default level: <a href="../rules.md#rule-levels" title="This lint has a default level of 'error'."><code>error</code></a> ·
|
Default level: <a href="../rules.md#rule-levels" title="This lint has a default level of 'error'."><code>error</code></a> ·
|
||||||
Added in <a href="https://github.com/astral-sh/ty/releases/tag/0.0.1-alpha.1">0.0.1-alpha.1</a> ·
|
Added in <a href="https://github.com/astral-sh/ty/releases/tag/0.0.1-alpha.1">0.0.1-alpha.1</a> ·
|
||||||
<a href="https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20invalid-metaclass" target="_blank">Related issues</a> ·
|
<a href="https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20invalid-metaclass" target="_blank">Related issues</a> ·
|
||||||
<a href="https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L1014" target="_blank">View source</a>
|
<a href="https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L1013" target="_blank">View source</a>
|
||||||
</small>
|
</small>
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -934,7 +934,7 @@ class B(metaclass=f): ...
|
||||||
Default level: <a href="../rules.md#rule-levels" title="This lint has a default level of 'error'."><code>error</code></a> ·
|
Default level: <a href="../rules.md#rule-levels" title="This lint has a default level of 'error'."><code>error</code></a> ·
|
||||||
Added in <a href="https://github.com/astral-sh/ty/releases/tag/0.0.1-alpha.20">0.0.1-alpha.20</a> ·
|
Added in <a href="https://github.com/astral-sh/ty/releases/tag/0.0.1-alpha.20">0.0.1-alpha.20</a> ·
|
||||||
<a href="https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20invalid-method-override" target="_blank">Related issues</a> ·
|
<a href="https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20invalid-method-override" target="_blank">Related issues</a> ·
|
||||||
<a href="https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L2126" target="_blank">View source</a>
|
<a href="https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L2125" target="_blank">View source</a>
|
||||||
</small>
|
</small>
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -1041,7 +1041,7 @@ Correct use of `@override` is enforced by ty's `invalid-explicit-override` rule.
|
||||||
Default level: <a href="../rules.md#rule-levels" title="This lint has a default level of 'error'."><code>error</code></a> ·
|
Default level: <a href="../rules.md#rule-levels" title="This lint has a default level of 'error'."><code>error</code></a> ·
|
||||||
Added in <a href="https://github.com/astral-sh/ty/releases/tag/0.0.1-alpha.19">0.0.1-alpha.19</a> ·
|
Added in <a href="https://github.com/astral-sh/ty/releases/tag/0.0.1-alpha.19">0.0.1-alpha.19</a> ·
|
||||||
<a href="https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20invalid-named-tuple" target="_blank">Related issues</a> ·
|
<a href="https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20invalid-named-tuple" target="_blank">Related issues</a> ·
|
||||||
<a href="https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L542" target="_blank">View source</a>
|
<a href="https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L541" target="_blank">View source</a>
|
||||||
</small>
|
</small>
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -1095,7 +1095,7 @@ AttributeError: Cannot overwrite NamedTuple attribute _asdict
|
||||||
Default level: <a href="../rules.md#rule-levels" title="This lint has a default level of 'error'."><code>error</code></a> ·
|
Default level: <a href="../rules.md#rule-levels" title="This lint has a default level of 'error'."><code>error</code></a> ·
|
||||||
Preview (since <a href="https://github.com/astral-sh/ty/releases/tag/1.0.0">1.0.0</a>) ·
|
Preview (since <a href="https://github.com/astral-sh/ty/releases/tag/1.0.0">1.0.0</a>) ·
|
||||||
<a href="https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20invalid-newtype" target="_blank">Related issues</a> ·
|
<a href="https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20invalid-newtype" target="_blank">Related issues</a> ·
|
||||||
<a href="https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L990" target="_blank">View source</a>
|
<a href="https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L989" target="_blank">View source</a>
|
||||||
</small>
|
</small>
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -1125,7 +1125,7 @@ Baz = NewType("Baz", int | str) # error: invalid base for `typing.NewType`
|
||||||
Default level: <a href="../rules.md#rule-levels" title="This lint has a default level of 'error'."><code>error</code></a> ·
|
Default level: <a href="../rules.md#rule-levels" title="This lint has a default level of 'error'."><code>error</code></a> ·
|
||||||
Added in <a href="https://github.com/astral-sh/ty/releases/tag/0.0.1-alpha.1">0.0.1-alpha.1</a> ·
|
Added in <a href="https://github.com/astral-sh/ty/releases/tag/0.0.1-alpha.1">0.0.1-alpha.1</a> ·
|
||||||
<a href="https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20invalid-overload" target="_blank">Related issues</a> ·
|
<a href="https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20invalid-overload" target="_blank">Related issues</a> ·
|
||||||
<a href="https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L1041" target="_blank">View source</a>
|
<a href="https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L1040" target="_blank">View source</a>
|
||||||
</small>
|
</small>
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -1175,7 +1175,7 @@ def foo(x: int) -> int: ...
|
||||||
Default level: <a href="../rules.md#rule-levels" title="This lint has a default level of 'error'."><code>error</code></a> ·
|
Default level: <a href="../rules.md#rule-levels" title="This lint has a default level of 'error'."><code>error</code></a> ·
|
||||||
Added in <a href="https://github.com/astral-sh/ty/releases/tag/0.0.1-alpha.1">0.0.1-alpha.1</a> ·
|
Added in <a href="https://github.com/astral-sh/ty/releases/tag/0.0.1-alpha.1">0.0.1-alpha.1</a> ·
|
||||||
<a href="https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20invalid-parameter-default" target="_blank">Related issues</a> ·
|
<a href="https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20invalid-parameter-default" target="_blank">Related issues</a> ·
|
||||||
<a href="https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L1140" target="_blank">View source</a>
|
<a href="https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L1139" target="_blank">View source</a>
|
||||||
</small>
|
</small>
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -1201,7 +1201,7 @@ def f(a: int = ''): ...
|
||||||
Default level: <a href="../rules.md#rule-levels" title="This lint has a default level of 'error'."><code>error</code></a> ·
|
Default level: <a href="../rules.md#rule-levels" title="This lint has a default level of 'error'."><code>error</code></a> ·
|
||||||
Added in <a href="https://github.com/astral-sh/ty/releases/tag/0.0.1-alpha.1">0.0.1-alpha.1</a> ·
|
Added in <a href="https://github.com/astral-sh/ty/releases/tag/0.0.1-alpha.1">0.0.1-alpha.1</a> ·
|
||||||
<a href="https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20invalid-paramspec" target="_blank">Related issues</a> ·
|
<a href="https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20invalid-paramspec" target="_blank">Related issues</a> ·
|
||||||
<a href="https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L945" target="_blank">View source</a>
|
<a href="https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L944" target="_blank">View source</a>
|
||||||
</small>
|
</small>
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -1232,7 +1232,7 @@ P2 = ParamSpec("S2") # error: ParamSpec name must match the variable it's assig
|
||||||
Default level: <a href="../rules.md#rule-levels" title="This lint has a default level of 'error'."><code>error</code></a> ·
|
Default level: <a href="../rules.md#rule-levels" title="This lint has a default level of 'error'."><code>error</code></a> ·
|
||||||
Added in <a href="https://github.com/astral-sh/ty/releases/tag/0.0.1-alpha.1">0.0.1-alpha.1</a> ·
|
Added in <a href="https://github.com/astral-sh/ty/releases/tag/0.0.1-alpha.1">0.0.1-alpha.1</a> ·
|
||||||
<a href="https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20invalid-protocol" target="_blank">Related issues</a> ·
|
<a href="https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20invalid-protocol" target="_blank">Related issues</a> ·
|
||||||
<a href="https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L478" target="_blank">View source</a>
|
<a href="https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L477" target="_blank">View source</a>
|
||||||
</small>
|
</small>
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -1266,7 +1266,7 @@ TypeError: Protocols can only inherit from other protocols, got <class 'int'>
|
||||||
Default level: <a href="../rules.md#rule-levels" title="This lint has a default level of 'error'."><code>error</code></a> ·
|
Default level: <a href="../rules.md#rule-levels" title="This lint has a default level of 'error'."><code>error</code></a> ·
|
||||||
Added in <a href="https://github.com/astral-sh/ty/releases/tag/0.0.1-alpha.1">0.0.1-alpha.1</a> ·
|
Added in <a href="https://github.com/astral-sh/ty/releases/tag/0.0.1-alpha.1">0.0.1-alpha.1</a> ·
|
||||||
<a href="https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20invalid-raise" target="_blank">Related issues</a> ·
|
<a href="https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20invalid-raise" target="_blank">Related issues</a> ·
|
||||||
<a href="https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L1160" target="_blank">View source</a>
|
<a href="https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L1159" target="_blank">View source</a>
|
||||||
</small>
|
</small>
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -1315,7 +1315,7 @@ def g():
|
||||||
Default level: <a href="../rules.md#rule-levels" title="This lint has a default level of 'error'."><code>error</code></a> ·
|
Default level: <a href="../rules.md#rule-levels" title="This lint has a default level of 'error'."><code>error</code></a> ·
|
||||||
Added in <a href="https://github.com/astral-sh/ty/releases/tag/0.0.1-alpha.1">0.0.1-alpha.1</a> ·
|
Added in <a href="https://github.com/astral-sh/ty/releases/tag/0.0.1-alpha.1">0.0.1-alpha.1</a> ·
|
||||||
<a href="https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20invalid-return-type" target="_blank">Related issues</a> ·
|
<a href="https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20invalid-return-type" target="_blank">Related issues</a> ·
|
||||||
<a href="https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L689" target="_blank">View source</a>
|
<a href="https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L688" target="_blank">View source</a>
|
||||||
</small>
|
</small>
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -1340,7 +1340,7 @@ def func() -> int:
|
||||||
Default level: <a href="../rules.md#rule-levels" title="This lint has a default level of 'error'."><code>error</code></a> ·
|
Default level: <a href="../rules.md#rule-levels" title="This lint has a default level of 'error'."><code>error</code></a> ·
|
||||||
Added in <a href="https://github.com/astral-sh/ty/releases/tag/0.0.1-alpha.1">0.0.1-alpha.1</a> ·
|
Added in <a href="https://github.com/astral-sh/ty/releases/tag/0.0.1-alpha.1">0.0.1-alpha.1</a> ·
|
||||||
<a href="https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20invalid-super-argument" target="_blank">Related issues</a> ·
|
<a href="https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20invalid-super-argument" target="_blank">Related issues</a> ·
|
||||||
<a href="https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L1203" target="_blank">View source</a>
|
<a href="https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L1202" target="_blank">View source</a>
|
||||||
</small>
|
</small>
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -1398,7 +1398,7 @@ TODO #14889
|
||||||
Default level: <a href="../rules.md#rule-levels" title="This lint has a default level of 'error'."><code>error</code></a> ·
|
Default level: <a href="../rules.md#rule-levels" title="This lint has a default level of 'error'."><code>error</code></a> ·
|
||||||
Added in <a href="https://github.com/astral-sh/ty/releases/tag/0.0.1-alpha.6">0.0.1-alpha.6</a> ·
|
Added in <a href="https://github.com/astral-sh/ty/releases/tag/0.0.1-alpha.6">0.0.1-alpha.6</a> ·
|
||||||
<a href="https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20invalid-type-alias-type" target="_blank">Related issues</a> ·
|
<a href="https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20invalid-type-alias-type" target="_blank">Related issues</a> ·
|
||||||
<a href="https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L969" target="_blank">View source</a>
|
<a href="https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L968" target="_blank">View source</a>
|
||||||
</small>
|
</small>
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -1425,7 +1425,7 @@ NewAlias = TypeAliasType(get_name(), int) # error: TypeAliasType name mus
|
||||||
Default level: <a href="../rules.md#rule-levels" title="This lint has a default level of 'error'."><code>error</code></a> ·
|
Default level: <a href="../rules.md#rule-levels" title="This lint has a default level of 'error'."><code>error</code></a> ·
|
||||||
Added in <a href="https://github.com/astral-sh/ty/releases/tag/0.0.1-alpha.29">0.0.1-alpha.29</a> ·
|
Added in <a href="https://github.com/astral-sh/ty/releases/tag/0.0.1-alpha.29">0.0.1-alpha.29</a> ·
|
||||||
<a href="https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20invalid-type-arguments" target="_blank">Related issues</a> ·
|
<a href="https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20invalid-type-arguments" target="_blank">Related issues</a> ·
|
||||||
<a href="https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L1435" target="_blank">View source</a>
|
<a href="https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L1434" target="_blank">View source</a>
|
||||||
</small>
|
</small>
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -1472,7 +1472,7 @@ Bar[int] # error: too few arguments
|
||||||
Default level: <a href="../rules.md#rule-levels" title="This lint has a default level of 'error'."><code>error</code></a> ·
|
Default level: <a href="../rules.md#rule-levels" title="This lint has a default level of 'error'."><code>error</code></a> ·
|
||||||
Added in <a href="https://github.com/astral-sh/ty/releases/tag/0.0.1-alpha.1">0.0.1-alpha.1</a> ·
|
Added in <a href="https://github.com/astral-sh/ty/releases/tag/0.0.1-alpha.1">0.0.1-alpha.1</a> ·
|
||||||
<a href="https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20invalid-type-checking-constant" target="_blank">Related issues</a> ·
|
<a href="https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20invalid-type-checking-constant" target="_blank">Related issues</a> ·
|
||||||
<a href="https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L1242" target="_blank">View source</a>
|
<a href="https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L1241" target="_blank">View source</a>
|
||||||
</small>
|
</small>
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -1502,7 +1502,7 @@ TYPE_CHECKING = ''
|
||||||
Default level: <a href="../rules.md#rule-levels" title="This lint has a default level of 'error'."><code>error</code></a> ·
|
Default level: <a href="../rules.md#rule-levels" title="This lint has a default level of 'error'."><code>error</code></a> ·
|
||||||
Added in <a href="https://github.com/astral-sh/ty/releases/tag/0.0.1-alpha.1">0.0.1-alpha.1</a> ·
|
Added in <a href="https://github.com/astral-sh/ty/releases/tag/0.0.1-alpha.1">0.0.1-alpha.1</a> ·
|
||||||
<a href="https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20invalid-type-form" target="_blank">Related issues</a> ·
|
<a href="https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20invalid-type-form" target="_blank">Related issues</a> ·
|
||||||
<a href="https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L1266" target="_blank">View source</a>
|
<a href="https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L1265" target="_blank">View source</a>
|
||||||
</small>
|
</small>
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -1532,7 +1532,7 @@ b: Annotated[int] # `Annotated` expects at least two arguments
|
||||||
Default level: <a href="../rules.md#rule-levels" title="This lint has a default level of 'error'."><code>error</code></a> ·
|
Default level: <a href="../rules.md#rule-levels" title="This lint has a default level of 'error'."><code>error</code></a> ·
|
||||||
Added in <a href="https://github.com/astral-sh/ty/releases/tag/0.0.1-alpha.11">0.0.1-alpha.11</a> ·
|
Added in <a href="https://github.com/astral-sh/ty/releases/tag/0.0.1-alpha.11">0.0.1-alpha.11</a> ·
|
||||||
<a href="https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20invalid-type-guard-call" target="_blank">Related issues</a> ·
|
<a href="https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20invalid-type-guard-call" target="_blank">Related issues</a> ·
|
||||||
<a href="https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L1318" target="_blank">View source</a>
|
<a href="https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L1317" target="_blank">View source</a>
|
||||||
</small>
|
</small>
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -1566,7 +1566,7 @@ f(10) # Error
|
||||||
Default level: <a href="../rules.md#rule-levels" title="This lint has a default level of 'error'."><code>error</code></a> ·
|
Default level: <a href="../rules.md#rule-levels" title="This lint has a default level of 'error'."><code>error</code></a> ·
|
||||||
Added in <a href="https://github.com/astral-sh/ty/releases/tag/0.0.1-alpha.11">0.0.1-alpha.11</a> ·
|
Added in <a href="https://github.com/astral-sh/ty/releases/tag/0.0.1-alpha.11">0.0.1-alpha.11</a> ·
|
||||||
<a href="https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20invalid-type-guard-definition" target="_blank">Related issues</a> ·
|
<a href="https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20invalid-type-guard-definition" target="_blank">Related issues</a> ·
|
||||||
<a href="https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L1290" target="_blank">View source</a>
|
<a href="https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L1289" target="_blank">View source</a>
|
||||||
</small>
|
</small>
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -1600,7 +1600,7 @@ class C:
|
||||||
Default level: <a href="../rules.md#rule-levels" title="This lint has a default level of 'error'."><code>error</code></a> ·
|
Default level: <a href="../rules.md#rule-levels" title="This lint has a default level of 'error'."><code>error</code></a> ·
|
||||||
Added in <a href="https://github.com/astral-sh/ty/releases/tag/0.0.1-alpha.1">0.0.1-alpha.1</a> ·
|
Added in <a href="https://github.com/astral-sh/ty/releases/tag/0.0.1-alpha.1">0.0.1-alpha.1</a> ·
|
||||||
<a href="https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20invalid-type-variable-constraints" target="_blank">Related issues</a> ·
|
<a href="https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20invalid-type-variable-constraints" target="_blank">Related issues</a> ·
|
||||||
<a href="https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L1346" target="_blank">View source</a>
|
<a href="https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L1345" target="_blank">View source</a>
|
||||||
</small>
|
</small>
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -1635,7 +1635,7 @@ T = TypeVar('T', bound=str) # valid bound TypeVar
|
||||||
Default level: <a href="../rules.md#rule-levels" title="This lint has a default level of 'error'."><code>error</code></a> ·
|
Default level: <a href="../rules.md#rule-levels" title="This lint has a default level of 'error'."><code>error</code></a> ·
|
||||||
Added in <a href="https://github.com/astral-sh/ty/releases/tag/0.0.1-alpha.1">0.0.1-alpha.1</a> ·
|
Added in <a href="https://github.com/astral-sh/ty/releases/tag/0.0.1-alpha.1">0.0.1-alpha.1</a> ·
|
||||||
<a href="https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20missing-argument" target="_blank">Related issues</a> ·
|
<a href="https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20missing-argument" target="_blank">Related issues</a> ·
|
||||||
<a href="https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L1375" target="_blank">View source</a>
|
<a href="https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L1374" target="_blank">View source</a>
|
||||||
</small>
|
</small>
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -1660,7 +1660,7 @@ func() # TypeError: func() missing 1 required positional argument: 'x'
|
||||||
Default level: <a href="../rules.md#rule-levels" title="This lint has a default level of 'error'."><code>error</code></a> ·
|
Default level: <a href="../rules.md#rule-levels" title="This lint has a default level of 'error'."><code>error</code></a> ·
|
||||||
Added in <a href="https://github.com/astral-sh/ty/releases/tag/0.0.1-alpha.20">0.0.1-alpha.20</a> ·
|
Added in <a href="https://github.com/astral-sh/ty/releases/tag/0.0.1-alpha.20">0.0.1-alpha.20</a> ·
|
||||||
<a href="https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20missing-typed-dict-key" target="_blank">Related issues</a> ·
|
<a href="https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20missing-typed-dict-key" target="_blank">Related issues</a> ·
|
||||||
<a href="https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L2099" target="_blank">View source</a>
|
<a href="https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L2098" target="_blank">View source</a>
|
||||||
</small>
|
</small>
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -1693,7 +1693,7 @@ alice["age"] # KeyError
|
||||||
Default level: <a href="../rules.md#rule-levels" title="This lint has a default level of 'error'."><code>error</code></a> ·
|
Default level: <a href="../rules.md#rule-levels" title="This lint has a default level of 'error'."><code>error</code></a> ·
|
||||||
Added in <a href="https://github.com/astral-sh/ty/releases/tag/0.0.1-alpha.1">0.0.1-alpha.1</a> ·
|
Added in <a href="https://github.com/astral-sh/ty/releases/tag/0.0.1-alpha.1">0.0.1-alpha.1</a> ·
|
||||||
<a href="https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20no-matching-overload" target="_blank">Related issues</a> ·
|
<a href="https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20no-matching-overload" target="_blank">Related issues</a> ·
|
||||||
<a href="https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L1394" target="_blank">View source</a>
|
<a href="https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L1393" target="_blank">View source</a>
|
||||||
</small>
|
</small>
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -1722,7 +1722,7 @@ func("string") # error: [no-matching-overload]
|
||||||
Default level: <a href="../rules.md#rule-levels" title="This lint has a default level of 'error'."><code>error</code></a> ·
|
Default level: <a href="../rules.md#rule-levels" title="This lint has a default level of 'error'."><code>error</code></a> ·
|
||||||
Added in <a href="https://github.com/astral-sh/ty/releases/tag/0.0.1-alpha.1">0.0.1-alpha.1</a> ·
|
Added in <a href="https://github.com/astral-sh/ty/releases/tag/0.0.1-alpha.1">0.0.1-alpha.1</a> ·
|
||||||
<a href="https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20non-subscriptable" target="_blank">Related issues</a> ·
|
<a href="https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20non-subscriptable" target="_blank">Related issues</a> ·
|
||||||
<a href="https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L1417" target="_blank">View source</a>
|
<a href="https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L1416" target="_blank">View source</a>
|
||||||
</small>
|
</small>
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -1746,7 +1746,7 @@ Subscripting an object that does not support it will raise a `TypeError` at runt
|
||||||
Default level: <a href="../rules.md#rule-levels" title="This lint has a default level of 'error'."><code>error</code></a> ·
|
Default level: <a href="../rules.md#rule-levels" title="This lint has a default level of 'error'."><code>error</code></a> ·
|
||||||
Added in <a href="https://github.com/astral-sh/ty/releases/tag/0.0.1-alpha.1">0.0.1-alpha.1</a> ·
|
Added in <a href="https://github.com/astral-sh/ty/releases/tag/0.0.1-alpha.1">0.0.1-alpha.1</a> ·
|
||||||
<a href="https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20not-iterable" target="_blank">Related issues</a> ·
|
<a href="https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20not-iterable" target="_blank">Related issues</a> ·
|
||||||
<a href="https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L1476" target="_blank">View source</a>
|
<a href="https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L1475" target="_blank">View source</a>
|
||||||
</small>
|
</small>
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -1772,7 +1772,7 @@ for i in 34: # TypeError: 'int' object is not iterable
|
||||||
Default level: <a href="../rules.md#rule-levels" title="This lint has a default level of 'error'."><code>error</code></a> ·
|
Default level: <a href="../rules.md#rule-levels" title="This lint has a default level of 'error'."><code>error</code></a> ·
|
||||||
Added in <a href="https://github.com/astral-sh/ty/releases/tag/0.0.1-alpha.29">0.0.1-alpha.29</a> ·
|
Added in <a href="https://github.com/astral-sh/ty/releases/tag/0.0.1-alpha.29">0.0.1-alpha.29</a> ·
|
||||||
<a href="https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20override-of-final-method" target="_blank">Related issues</a> ·
|
<a href="https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20override-of-final-method" target="_blank">Related issues</a> ·
|
||||||
<a href="https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L1641" target="_blank">View source</a>
|
<a href="https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L1640" target="_blank">View source</a>
|
||||||
</small>
|
</small>
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -1805,7 +1805,7 @@ class B(A):
|
||||||
Default level: <a href="../rules.md#rule-levels" title="This lint has a default level of 'error'."><code>error</code></a> ·
|
Default level: <a href="../rules.md#rule-levels" title="This lint has a default level of 'error'."><code>error</code></a> ·
|
||||||
Added in <a href="https://github.com/astral-sh/ty/releases/tag/0.0.1-alpha.1">0.0.1-alpha.1</a> ·
|
Added in <a href="https://github.com/astral-sh/ty/releases/tag/0.0.1-alpha.1">0.0.1-alpha.1</a> ·
|
||||||
<a href="https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20parameter-already-assigned" target="_blank">Related issues</a> ·
|
<a href="https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20parameter-already-assigned" target="_blank">Related issues</a> ·
|
||||||
<a href="https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L1527" target="_blank">View source</a>
|
<a href="https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L1526" target="_blank">View source</a>
|
||||||
</small>
|
</small>
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -1832,7 +1832,7 @@ f(1, x=2) # Error raised here
|
||||||
Default level: <a href="../rules.md#rule-levels" title="This lint has a default level of 'error'."><code>error</code></a> ·
|
Default level: <a href="../rules.md#rule-levels" title="This lint has a default level of 'error'."><code>error</code></a> ·
|
||||||
Added in <a href="https://github.com/astral-sh/ty/releases/tag/0.0.1-alpha.22">0.0.1-alpha.22</a> ·
|
Added in <a href="https://github.com/astral-sh/ty/releases/tag/0.0.1-alpha.22">0.0.1-alpha.22</a> ·
|
||||||
<a href="https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20positional-only-parameter-as-kwarg" target="_blank">Related issues</a> ·
|
<a href="https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20positional-only-parameter-as-kwarg" target="_blank">Related issues</a> ·
|
||||||
<a href="https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L1852" target="_blank">View source</a>
|
<a href="https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L1851" target="_blank">View source</a>
|
||||||
</small>
|
</small>
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -1890,7 +1890,7 @@ def test(): -> "int":
|
||||||
Default level: <a href="../rules.md#rule-levels" title="This lint has a default level of 'error'."><code>error</code></a> ·
|
Default level: <a href="../rules.md#rule-levels" title="This lint has a default level of 'error'."><code>error</code></a> ·
|
||||||
Added in <a href="https://github.com/astral-sh/ty/releases/tag/0.0.1-alpha.1">0.0.1-alpha.1</a> ·
|
Added in <a href="https://github.com/astral-sh/ty/releases/tag/0.0.1-alpha.1">0.0.1-alpha.1</a> ·
|
||||||
<a href="https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20static-assert-error" target="_blank">Related issues</a> ·
|
<a href="https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20static-assert-error" target="_blank">Related issues</a> ·
|
||||||
<a href="https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L1974" target="_blank">View source</a>
|
<a href="https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L1973" target="_blank">View source</a>
|
||||||
</small>
|
</small>
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -1920,7 +1920,7 @@ static_assert(int(2.0 * 3.0) == 6) # error: does not have a statically known tr
|
||||||
Default level: <a href="../rules.md#rule-levels" title="This lint has a default level of 'error'."><code>error</code></a> ·
|
Default level: <a href="../rules.md#rule-levels" title="This lint has a default level of 'error'."><code>error</code></a> ·
|
||||||
Added in <a href="https://github.com/astral-sh/ty/releases/tag/0.0.1-alpha.1">0.0.1-alpha.1</a> ·
|
Added in <a href="https://github.com/astral-sh/ty/releases/tag/0.0.1-alpha.1">0.0.1-alpha.1</a> ·
|
||||||
<a href="https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20subclass-of-final-class" target="_blank">Related issues</a> ·
|
<a href="https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20subclass-of-final-class" target="_blank">Related issues</a> ·
|
||||||
<a href="https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L1618" target="_blank">View source</a>
|
<a href="https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L1617" target="_blank">View source</a>
|
||||||
</small>
|
</small>
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -1949,7 +1949,7 @@ class B(A): ... # Error raised here
|
||||||
Default level: <a href="../rules.md#rule-levels" title="This lint has a default level of 'error'."><code>error</code></a> ·
|
Default level: <a href="../rules.md#rule-levels" title="This lint has a default level of 'error'."><code>error</code></a> ·
|
||||||
Preview (since <a href="https://github.com/astral-sh/ty/releases/tag/0.0.1-alpha.30">0.0.1-alpha.30</a>) ·
|
Preview (since <a href="https://github.com/astral-sh/ty/releases/tag/0.0.1-alpha.30">0.0.1-alpha.30</a>) ·
|
||||||
<a href="https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20super-call-in-named-tuple-method" target="_blank">Related issues</a> ·
|
<a href="https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20super-call-in-named-tuple-method" target="_blank">Related issues</a> ·
|
||||||
<a href="https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L1786" target="_blank">View source</a>
|
<a href="https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L1785" target="_blank">View source</a>
|
||||||
</small>
|
</small>
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -1983,7 +1983,7 @@ class F(NamedTuple):
|
||||||
Default level: <a href="../rules.md#rule-levels" title="This lint has a default level of 'error'."><code>error</code></a> ·
|
Default level: <a href="../rules.md#rule-levels" title="This lint has a default level of 'error'."><code>error</code></a> ·
|
||||||
Added in <a href="https://github.com/astral-sh/ty/releases/tag/0.0.1-alpha.1">0.0.1-alpha.1</a> ·
|
Added in <a href="https://github.com/astral-sh/ty/releases/tag/0.0.1-alpha.1">0.0.1-alpha.1</a> ·
|
||||||
<a href="https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20too-many-positional-arguments" target="_blank">Related issues</a> ·
|
<a href="https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20too-many-positional-arguments" target="_blank">Related issues</a> ·
|
||||||
<a href="https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L1726" target="_blank">View source</a>
|
<a href="https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L1725" target="_blank">View source</a>
|
||||||
</small>
|
</small>
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -2010,7 +2010,7 @@ f("foo") # Error raised here
|
||||||
Default level: <a href="../rules.md#rule-levels" title="This lint has a default level of 'error'."><code>error</code></a> ·
|
Default level: <a href="../rules.md#rule-levels" title="This lint has a default level of 'error'."><code>error</code></a> ·
|
||||||
Added in <a href="https://github.com/astral-sh/ty/releases/tag/0.0.1-alpha.1">0.0.1-alpha.1</a> ·
|
Added in <a href="https://github.com/astral-sh/ty/releases/tag/0.0.1-alpha.1">0.0.1-alpha.1</a> ·
|
||||||
<a href="https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20type-assertion-failure" target="_blank">Related issues</a> ·
|
<a href="https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20type-assertion-failure" target="_blank">Related issues</a> ·
|
||||||
<a href="https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L1704" target="_blank">View source</a>
|
<a href="https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L1703" target="_blank">View source</a>
|
||||||
</small>
|
</small>
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -2038,7 +2038,7 @@ def _(x: int):
|
||||||
Default level: <a href="../rules.md#rule-levels" title="This lint has a default level of 'error'."><code>error</code></a> ·
|
Default level: <a href="../rules.md#rule-levels" title="This lint has a default level of 'error'."><code>error</code></a> ·
|
||||||
Added in <a href="https://github.com/astral-sh/ty/releases/tag/0.0.1-alpha.1">0.0.1-alpha.1</a> ·
|
Added in <a href="https://github.com/astral-sh/ty/releases/tag/0.0.1-alpha.1">0.0.1-alpha.1</a> ·
|
||||||
<a href="https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20unavailable-implicit-super-arguments" target="_blank">Related issues</a> ·
|
<a href="https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20unavailable-implicit-super-arguments" target="_blank">Related issues</a> ·
|
||||||
<a href="https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L1747" target="_blank">View source</a>
|
<a href="https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L1746" target="_blank">View source</a>
|
||||||
</small>
|
</small>
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -2084,7 +2084,7 @@ class A:
|
||||||
Default level: <a href="../rules.md#rule-levels" title="This lint has a default level of 'error'."><code>error</code></a> ·
|
Default level: <a href="../rules.md#rule-levels" title="This lint has a default level of 'error'."><code>error</code></a> ·
|
||||||
Added in <a href="https://github.com/astral-sh/ty/releases/tag/0.0.1-alpha.1">0.0.1-alpha.1</a> ·
|
Added in <a href="https://github.com/astral-sh/ty/releases/tag/0.0.1-alpha.1">0.0.1-alpha.1</a> ·
|
||||||
<a href="https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20unknown-argument" target="_blank">Related issues</a> ·
|
<a href="https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20unknown-argument" target="_blank">Related issues</a> ·
|
||||||
<a href="https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L1831" target="_blank">View source</a>
|
<a href="https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L1830" target="_blank">View source</a>
|
||||||
</small>
|
</small>
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -2111,7 +2111,7 @@ f(x=1, y=2) # Error raised here
|
||||||
Default level: <a href="../rules.md#rule-levels" title="This lint has a default level of 'error'."><code>error</code></a> ·
|
Default level: <a href="../rules.md#rule-levels" title="This lint has a default level of 'error'."><code>error</code></a> ·
|
||||||
Added in <a href="https://github.com/astral-sh/ty/releases/tag/0.0.1-alpha.1">0.0.1-alpha.1</a> ·
|
Added in <a href="https://github.com/astral-sh/ty/releases/tag/0.0.1-alpha.1">0.0.1-alpha.1</a> ·
|
||||||
<a href="https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20unresolved-attribute" target="_blank">Related issues</a> ·
|
<a href="https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20unresolved-attribute" target="_blank">Related issues</a> ·
|
||||||
<a href="https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L1873" target="_blank">View source</a>
|
<a href="https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L1872" target="_blank">View source</a>
|
||||||
</small>
|
</small>
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -2139,7 +2139,7 @@ A().foo # AttributeError: 'A' object has no attribute 'foo'
|
||||||
Default level: <a href="../rules.md#rule-levels" title="This lint has a default level of 'error'."><code>error</code></a> ·
|
Default level: <a href="../rules.md#rule-levels" title="This lint has a default level of 'error'."><code>error</code></a> ·
|
||||||
Added in <a href="https://github.com/astral-sh/ty/releases/tag/0.0.1-alpha.1">0.0.1-alpha.1</a> ·
|
Added in <a href="https://github.com/astral-sh/ty/releases/tag/0.0.1-alpha.1">0.0.1-alpha.1</a> ·
|
||||||
<a href="https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20unresolved-import" target="_blank">Related issues</a> ·
|
<a href="https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20unresolved-import" target="_blank">Related issues</a> ·
|
||||||
<a href="https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L1895" target="_blank">View source</a>
|
<a href="https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L1894" target="_blank">View source</a>
|
||||||
</small>
|
</small>
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -2164,7 +2164,7 @@ import foo # ModuleNotFoundError: No module named 'foo'
|
||||||
Default level: <a href="../rules.md#rule-levels" title="This lint has a default level of 'error'."><code>error</code></a> ·
|
Default level: <a href="../rules.md#rule-levels" title="This lint has a default level of 'error'."><code>error</code></a> ·
|
||||||
Added in <a href="https://github.com/astral-sh/ty/releases/tag/0.0.1-alpha.1">0.0.1-alpha.1</a> ·
|
Added in <a href="https://github.com/astral-sh/ty/releases/tag/0.0.1-alpha.1">0.0.1-alpha.1</a> ·
|
||||||
<a href="https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20unresolved-reference" target="_blank">Related issues</a> ·
|
<a href="https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20unresolved-reference" target="_blank">Related issues</a> ·
|
||||||
<a href="https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L1914" target="_blank">View source</a>
|
<a href="https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L1913" target="_blank">View source</a>
|
||||||
</small>
|
</small>
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -2189,7 +2189,7 @@ print(x) # NameError: name 'x' is not defined
|
||||||
Default level: <a href="../rules.md#rule-levels" title="This lint has a default level of 'error'."><code>error</code></a> ·
|
Default level: <a href="../rules.md#rule-levels" title="This lint has a default level of 'error'."><code>error</code></a> ·
|
||||||
Added in <a href="https://github.com/astral-sh/ty/releases/tag/0.0.1-alpha.1">0.0.1-alpha.1</a> ·
|
Added in <a href="https://github.com/astral-sh/ty/releases/tag/0.0.1-alpha.1">0.0.1-alpha.1</a> ·
|
||||||
<a href="https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20unsupported-bool-conversion" target="_blank">Related issues</a> ·
|
<a href="https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20unsupported-bool-conversion" target="_blank">Related issues</a> ·
|
||||||
<a href="https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L1496" target="_blank">View source</a>
|
<a href="https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L1495" target="_blank">View source</a>
|
||||||
</small>
|
</small>
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -2226,7 +2226,7 @@ b1 < b2 < b1 # exception raised here
|
||||||
Default level: <a href="../rules.md#rule-levels" title="This lint has a default level of 'error'."><code>error</code></a> ·
|
Default level: <a href="../rules.md#rule-levels" title="This lint has a default level of 'error'."><code>error</code></a> ·
|
||||||
Added in <a href="https://github.com/astral-sh/ty/releases/tag/0.0.1-alpha.1">0.0.1-alpha.1</a> ·
|
Added in <a href="https://github.com/astral-sh/ty/releases/tag/0.0.1-alpha.1">0.0.1-alpha.1</a> ·
|
||||||
<a href="https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20unsupported-operator" target="_blank">Related issues</a> ·
|
<a href="https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20unsupported-operator" target="_blank">Related issues</a> ·
|
||||||
<a href="https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L1933" target="_blank">View source</a>
|
<a href="https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L1932" target="_blank">View source</a>
|
||||||
</small>
|
</small>
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -2254,7 +2254,7 @@ A() + A() # TypeError: unsupported operand type(s) for +: 'A' and 'A'
|
||||||
Default level: <a href="../rules.md#rule-levels" title="This lint has a default level of 'error'."><code>error</code></a> ·
|
Default level: <a href="../rules.md#rule-levels" title="This lint has a default level of 'error'."><code>error</code></a> ·
|
||||||
Added in <a href="https://github.com/astral-sh/ty/releases/tag/0.0.1-alpha.1">0.0.1-alpha.1</a> ·
|
Added in <a href="https://github.com/astral-sh/ty/releases/tag/0.0.1-alpha.1">0.0.1-alpha.1</a> ·
|
||||||
<a href="https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20zero-stepsize-in-slice" target="_blank">Related issues</a> ·
|
<a href="https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20zero-stepsize-in-slice" target="_blank">Related issues</a> ·
|
||||||
<a href="https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L1955" target="_blank">View source</a>
|
<a href="https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L1954" target="_blank">View source</a>
|
||||||
</small>
|
</small>
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -2279,7 +2279,7 @@ l[1:10:0] # ValueError: slice step cannot be zero
|
||||||
Default level: <a href="../rules.md#rule-levels" title="This lint has a default level of 'warn'."><code>warn</code></a> ·
|
Default level: <a href="../rules.md#rule-levels" title="This lint has a default level of 'warn'."><code>warn</code></a> ·
|
||||||
Added in <a href="https://github.com/astral-sh/ty/releases/tag/0.0.1-alpha.20">0.0.1-alpha.20</a> ·
|
Added in <a href="https://github.com/astral-sh/ty/releases/tag/0.0.1-alpha.20">0.0.1-alpha.20</a> ·
|
||||||
<a href="https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20ambiguous-protocol-member" target="_blank">Related issues</a> ·
|
<a href="https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20ambiguous-protocol-member" target="_blank">Related issues</a> ·
|
||||||
<a href="https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L507" target="_blank">View source</a>
|
<a href="https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L506" target="_blank">View source</a>
|
||||||
</small>
|
</small>
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -2320,7 +2320,7 @@ class SubProto(BaseProto, Protocol):
|
||||||
Default level: <a href="../rules.md#rule-levels" title="This lint has a default level of 'warn'."><code>warn</code></a> ·
|
Default level: <a href="../rules.md#rule-levels" title="This lint has a default level of 'warn'."><code>warn</code></a> ·
|
||||||
Added in <a href="https://github.com/astral-sh/ty/releases/tag/0.0.1-alpha.16">0.0.1-alpha.16</a> ·
|
Added in <a href="https://github.com/astral-sh/ty/releases/tag/0.0.1-alpha.16">0.0.1-alpha.16</a> ·
|
||||||
<a href="https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20deprecated" target="_blank">Related issues</a> ·
|
<a href="https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20deprecated" target="_blank">Related issues</a> ·
|
||||||
<a href="https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L322" target="_blank">View source</a>
|
<a href="https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L321" target="_blank">View source</a>
|
||||||
</small>
|
</small>
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -2408,7 +2408,7 @@ a = 20 / 0 # type: ignore
|
||||||
Default level: <a href="../rules.md#rule-levels" title="This lint has a default level of 'warn'."><code>warn</code></a> ·
|
Default level: <a href="../rules.md#rule-levels" title="This lint has a default level of 'warn'."><code>warn</code></a> ·
|
||||||
Added in <a href="https://github.com/astral-sh/ty/releases/tag/0.0.1-alpha.22">0.0.1-alpha.22</a> ·
|
Added in <a href="https://github.com/astral-sh/ty/releases/tag/0.0.1-alpha.22">0.0.1-alpha.22</a> ·
|
||||||
<a href="https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20possibly-missing-attribute" target="_blank">Related issues</a> ·
|
<a href="https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20possibly-missing-attribute" target="_blank">Related issues</a> ·
|
||||||
<a href="https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L1548" target="_blank">View source</a>
|
<a href="https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L1547" target="_blank">View source</a>
|
||||||
</small>
|
</small>
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -2436,7 +2436,7 @@ A.c # AttributeError: type object 'A' has no attribute 'c'
|
||||||
Default level: <a href="../rules.md#rule-levels" title="This lint has a default level of 'warn'."><code>warn</code></a> ·
|
Default level: <a href="../rules.md#rule-levels" title="This lint has a default level of 'warn'."><code>warn</code></a> ·
|
||||||
Added in <a href="https://github.com/astral-sh/ty/releases/tag/0.0.1-alpha.22">0.0.1-alpha.22</a> ·
|
Added in <a href="https://github.com/astral-sh/ty/releases/tag/0.0.1-alpha.22">0.0.1-alpha.22</a> ·
|
||||||
<a href="https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20possibly-missing-implicit-call" target="_blank">Related issues</a> ·
|
<a href="https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20possibly-missing-implicit-call" target="_blank">Related issues</a> ·
|
||||||
<a href="https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L153" target="_blank">View source</a>
|
<a href="https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L152" target="_blank">View source</a>
|
||||||
</small>
|
</small>
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -2468,7 +2468,7 @@ A()[0] # TypeError: 'A' object is not subscriptable
|
||||||
Default level: <a href="../rules.md#rule-levels" title="This lint has a default level of 'warn'."><code>warn</code></a> ·
|
Default level: <a href="../rules.md#rule-levels" title="This lint has a default level of 'warn'."><code>warn</code></a> ·
|
||||||
Added in <a href="https://github.com/astral-sh/ty/releases/tag/0.0.1-alpha.22">0.0.1-alpha.22</a> ·
|
Added in <a href="https://github.com/astral-sh/ty/releases/tag/0.0.1-alpha.22">0.0.1-alpha.22</a> ·
|
||||||
<a href="https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20possibly-missing-import" target="_blank">Related issues</a> ·
|
<a href="https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20possibly-missing-import" target="_blank">Related issues</a> ·
|
||||||
<a href="https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L1570" target="_blank">View source</a>
|
<a href="https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L1569" target="_blank">View source</a>
|
||||||
</small>
|
</small>
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -2500,7 +2500,7 @@ from module import a # ImportError: cannot import name 'a' from 'module'
|
||||||
Default level: <a href="../rules.md#rule-levels" title="This lint has a default level of 'warn'."><code>warn</code></a> ·
|
Default level: <a href="../rules.md#rule-levels" title="This lint has a default level of 'warn'."><code>warn</code></a> ·
|
||||||
Added in <a href="https://github.com/astral-sh/ty/releases/tag/0.0.1-alpha.1">0.0.1-alpha.1</a> ·
|
Added in <a href="https://github.com/astral-sh/ty/releases/tag/0.0.1-alpha.1">0.0.1-alpha.1</a> ·
|
||||||
<a href="https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20redundant-cast" target="_blank">Related issues</a> ·
|
<a href="https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20redundant-cast" target="_blank">Related issues</a> ·
|
||||||
<a href="https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L2026" target="_blank">View source</a>
|
<a href="https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L2025" target="_blank">View source</a>
|
||||||
</small>
|
</small>
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -2527,7 +2527,7 @@ cast(int, f()) # Redundant
|
||||||
Default level: <a href="../rules.md#rule-levels" title="This lint has a default level of 'warn'."><code>warn</code></a> ·
|
Default level: <a href="../rules.md#rule-levels" title="This lint has a default level of 'warn'."><code>warn</code></a> ·
|
||||||
Added in <a href="https://github.com/astral-sh/ty/releases/tag/0.0.1-alpha.1">0.0.1-alpha.1</a> ·
|
Added in <a href="https://github.com/astral-sh/ty/releases/tag/0.0.1-alpha.1">0.0.1-alpha.1</a> ·
|
||||||
<a href="https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20undefined-reveal" target="_blank">Related issues</a> ·
|
<a href="https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20undefined-reveal" target="_blank">Related issues</a> ·
|
||||||
<a href="https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L1813" target="_blank">View source</a>
|
<a href="https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L1812" target="_blank">View source</a>
|
||||||
</small>
|
</small>
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -2551,7 +2551,7 @@ reveal_type(1) # NameError: name 'reveal_type' is not defined
|
||||||
Default level: <a href="../rules.md#rule-levels" title="This lint has a default level of 'warn'."><code>warn</code></a> ·
|
Default level: <a href="../rules.md#rule-levels" title="This lint has a default level of 'warn'."><code>warn</code></a> ·
|
||||||
Added in <a href="https://github.com/astral-sh/ty/releases/tag/0.0.1-alpha.15">0.0.1-alpha.15</a> ·
|
Added in <a href="https://github.com/astral-sh/ty/releases/tag/0.0.1-alpha.15">0.0.1-alpha.15</a> ·
|
||||||
<a href="https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20unresolved-global" target="_blank">Related issues</a> ·
|
<a href="https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20unresolved-global" target="_blank">Related issues</a> ·
|
||||||
<a href="https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L2047" target="_blank">View source</a>
|
<a href="https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L2046" target="_blank">View source</a>
|
||||||
</small>
|
</small>
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -2609,7 +2609,7 @@ def g():
|
||||||
Default level: <a href="../rules.md#rule-levels" title="This lint has a default level of 'warn'."><code>warn</code></a> ·
|
Default level: <a href="../rules.md#rule-levels" title="This lint has a default level of 'warn'."><code>warn</code></a> ·
|
||||||
Added in <a href="https://github.com/astral-sh/ty/releases/tag/0.0.1-alpha.7">0.0.1-alpha.7</a> ·
|
Added in <a href="https://github.com/astral-sh/ty/releases/tag/0.0.1-alpha.7">0.0.1-alpha.7</a> ·
|
||||||
<a href="https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20unsupported-base" target="_blank">Related issues</a> ·
|
<a href="https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20unsupported-base" target="_blank">Related issues</a> ·
|
||||||
<a href="https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L778" target="_blank">View source</a>
|
<a href="https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L777" target="_blank">View source</a>
|
||||||
</small>
|
</small>
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -2648,7 +2648,7 @@ class D(C): ... # error: [unsupported-base]
|
||||||
Default level: <a href="../rules.md#rule-levels" title="This lint has a default level of 'warn'."><code>warn</code></a> ·
|
Default level: <a href="../rules.md#rule-levels" title="This lint has a default level of 'warn'."><code>warn</code></a> ·
|
||||||
Added in <a href="https://github.com/astral-sh/ty/releases/tag/0.0.1-alpha.22">0.0.1-alpha.22</a> ·
|
Added in <a href="https://github.com/astral-sh/ty/releases/tag/0.0.1-alpha.22">0.0.1-alpha.22</a> ·
|
||||||
<a href="https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20useless-overload-body" target="_blank">Related issues</a> ·
|
<a href="https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20useless-overload-body" target="_blank">Related issues</a> ·
|
||||||
<a href="https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L1084" target="_blank">View source</a>
|
<a href="https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L1083" target="_blank">View source</a>
|
||||||
</small>
|
</small>
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -2711,7 +2711,7 @@ def foo(x: int | str) -> int | str:
|
||||||
Default level: <a href="../rules.md#rule-levels" title="This lint has a default level of 'ignore'."><code>ignore</code></a> ·
|
Default level: <a href="../rules.md#rule-levels" title="This lint has a default level of 'ignore'."><code>ignore</code></a> ·
|
||||||
Preview (since <a href="https://github.com/astral-sh/ty/releases/tag/0.0.1-alpha.1">0.0.1-alpha.1</a>) ·
|
Preview (since <a href="https://github.com/astral-sh/ty/releases/tag/0.0.1-alpha.1">0.0.1-alpha.1</a>) ·
|
||||||
<a href="https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20division-by-zero" target="_blank">Related issues</a> ·
|
<a href="https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20division-by-zero" target="_blank">Related issues</a> ·
|
||||||
<a href="https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L304" target="_blank">View source</a>
|
<a href="https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L303" target="_blank">View source</a>
|
||||||
</small>
|
</small>
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -2735,7 +2735,7 @@ Dividing by zero raises a `ZeroDivisionError` at runtime.
|
||||||
Default level: <a href="../rules.md#rule-levels" title="This lint has a default level of 'ignore'."><code>ignore</code></a> ·
|
Default level: <a href="../rules.md#rule-levels" title="This lint has a default level of 'ignore'."><code>ignore</code></a> ·
|
||||||
Added in <a href="https://github.com/astral-sh/ty/releases/tag/0.0.1-alpha.1">0.0.1-alpha.1</a> ·
|
Added in <a href="https://github.com/astral-sh/ty/releases/tag/0.0.1-alpha.1">0.0.1-alpha.1</a> ·
|
||||||
<a href="https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20possibly-unresolved-reference" target="_blank">Related issues</a> ·
|
<a href="https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20possibly-unresolved-reference" target="_blank">Related issues</a> ·
|
||||||
<a href="https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L1596" target="_blank">View source</a>
|
<a href="https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L1595" target="_blank">View source</a>
|
||||||
</small>
|
</small>
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -580,6 +580,53 @@ fn check_non_existing_path() -> anyhow::Result<()> {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn check_file_without_extension() -> anyhow::Result<()> {
|
||||||
|
let case = CliTest::with_file("main", "a = b")?;
|
||||||
|
|
||||||
|
assert_cmd_snapshot!(
|
||||||
|
case.command().arg("main"),
|
||||||
|
@r"
|
||||||
|
success: false
|
||||||
|
exit_code: 1
|
||||||
|
----- stdout -----
|
||||||
|
error[unresolved-reference]: Name `b` used when not defined
|
||||||
|
--> main:1:5
|
||||||
|
|
|
||||||
|
1 | a = b
|
||||||
|
| ^
|
||||||
|
|
|
||||||
|
info: rule `unresolved-reference` is enabled by default
|
||||||
|
|
||||||
|
Found 1 diagnostic
|
||||||
|
|
||||||
|
----- stderr -----
|
||||||
|
"
|
||||||
|
);
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn check_file_without_extension_in_subfolder() -> anyhow::Result<()> {
|
||||||
|
let case = CliTest::with_file("src/main", "a = b")?;
|
||||||
|
|
||||||
|
assert_cmd_snapshot!(
|
||||||
|
case.command().arg("src"),
|
||||||
|
@r"
|
||||||
|
success: true
|
||||||
|
exit_code: 0
|
||||||
|
----- stdout -----
|
||||||
|
All checks passed!
|
||||||
|
|
||||||
|
----- stderr -----
|
||||||
|
WARN No python files found under the given path(s)
|
||||||
|
"
|
||||||
|
);
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn concise_diagnostics() -> anyhow::Result<()> {
|
fn concise_diagnostics() -> anyhow::Result<()> {
|
||||||
let case = CliTest::with_file(
|
let case = CliTest::with_file(
|
||||||
|
|
|
||||||
|
|
@ -6433,6 +6433,155 @@ collabc<CURSOR>
|
||||||
assert_snapshot!(snapshot, @"collections.abc");
|
assert_snapshot!(snapshot, @"collections.abc");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn local_function_variable_with_return() {
|
||||||
|
let builder = completion_test_builder(
|
||||||
|
"\
|
||||||
|
variable_global = 1
|
||||||
|
def foo():
|
||||||
|
variable_local = 1
|
||||||
|
variable_<CURSOR>
|
||||||
|
return
|
||||||
|
",
|
||||||
|
);
|
||||||
|
assert_snapshot!(
|
||||||
|
builder.skip_auto_import().build().snapshot(),
|
||||||
|
@r"
|
||||||
|
variable_global
|
||||||
|
variable_local
|
||||||
|
",
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn nested_scopes_with_return() {
|
||||||
|
let builder = completion_test_builder(
|
||||||
|
"\
|
||||||
|
variable_1 = 1
|
||||||
|
def fun1():
|
||||||
|
variable_2 = 1
|
||||||
|
def fun2():
|
||||||
|
variable_3 = 1
|
||||||
|
def fun3():
|
||||||
|
variable_4 = 1
|
||||||
|
variable_<CURSOR>
|
||||||
|
return
|
||||||
|
return
|
||||||
|
return
|
||||||
|
",
|
||||||
|
);
|
||||||
|
assert_snapshot!(
|
||||||
|
builder.skip_auto_import().build().snapshot(),
|
||||||
|
@r"
|
||||||
|
variable_1
|
||||||
|
variable_2
|
||||||
|
variable_3
|
||||||
|
variable_4
|
||||||
|
",
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn multiple_declarations_global_scope1() {
|
||||||
|
let builder = completion_test_builder(
|
||||||
|
"\
|
||||||
|
zqzqzq: int = 1
|
||||||
|
zqzqzq: str = 'foo'
|
||||||
|
zqzq<CURSOR>
|
||||||
|
",
|
||||||
|
);
|
||||||
|
// The type for `zqzqzq` *should* be `str`, but we consider all
|
||||||
|
// reachable declarations and bindings, which means we get a
|
||||||
|
// union of `int` and `str` here even though the `int` binding
|
||||||
|
// isn't live at the cursor position.
|
||||||
|
assert_snapshot!(
|
||||||
|
builder.skip_auto_import().type_signatures().build().snapshot(),
|
||||||
|
@"zqzqzq :: int | str",
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn multiple_declarations_global_scope2() {
|
||||||
|
let builder = completion_test_builder(
|
||||||
|
"\
|
||||||
|
zqzqzq: int = 1
|
||||||
|
zqzq<CURSOR>
|
||||||
|
zqzqzq: str = 'foo'
|
||||||
|
",
|
||||||
|
);
|
||||||
|
// The type for `zqzqzq` *should* be `int`, but we consider all
|
||||||
|
// reachable declarations and bindings, which means we get a
|
||||||
|
// union of `int` and `str` here even though the `str` binding
|
||||||
|
// doesn't exist at the cursor position.
|
||||||
|
assert_snapshot!(
|
||||||
|
builder.skip_auto_import().type_signatures().build().snapshot(),
|
||||||
|
@"zqzqzq :: int | str",
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn multiple_declarations_function_scope1() {
|
||||||
|
let builder = completion_test_builder(
|
||||||
|
"\
|
||||||
|
def foo():
|
||||||
|
zqzqzq: int = 1
|
||||||
|
zqzqzq: str = 'foo'
|
||||||
|
zqzq<CURSOR>
|
||||||
|
return
|
||||||
|
",
|
||||||
|
);
|
||||||
|
// The type for `zqzqzq` *should* be `str`, but we consider all
|
||||||
|
// reachable declarations and bindings, which means we get a
|
||||||
|
// union of `int` and `str` here even though the `int` binding
|
||||||
|
// isn't live at the cursor position.
|
||||||
|
assert_snapshot!(
|
||||||
|
builder.skip_auto_import().type_signatures().build().snapshot(),
|
||||||
|
@"zqzqzq :: int | str",
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn multiple_declarations_function_scope2() {
|
||||||
|
let builder = completion_test_builder(
|
||||||
|
"\
|
||||||
|
def foo():
|
||||||
|
zqzqzq: int = 1
|
||||||
|
zqzq<CURSOR>
|
||||||
|
zqzqzq: str = 'foo'
|
||||||
|
return
|
||||||
|
",
|
||||||
|
);
|
||||||
|
// The type for `zqzqzq` *should* be `int`, but we consider all
|
||||||
|
// reachable declarations and bindings, which means we get a
|
||||||
|
// union of `int` and `str` here even though the `str` binding
|
||||||
|
// doesn't exist at the cursor position.
|
||||||
|
assert_snapshot!(
|
||||||
|
builder.skip_auto_import().type_signatures().build().snapshot(),
|
||||||
|
@"zqzqzq :: int | str",
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn multiple_declarations_function_parameter() {
|
||||||
|
let builder = completion_test_builder(
|
||||||
|
"\
|
||||||
|
from pathlib import Path
|
||||||
|
def f(zqzqzq: str):
|
||||||
|
zqzqzq: Path = Path(zqzqzq)
|
||||||
|
zqzq<CURSOR>
|
||||||
|
return
|
||||||
|
",
|
||||||
|
);
|
||||||
|
// The type for `zqzqzq` *should* be `Path`, but we consider all
|
||||||
|
// reachable declarations and bindings, which means we get a
|
||||||
|
// union of `str` and `Path` here even though the `str` binding
|
||||||
|
// isn't live at the cursor position.
|
||||||
|
assert_snapshot!(
|
||||||
|
builder.skip_auto_import().type_signatures().build().snapshot(),
|
||||||
|
@"zqzqzq :: str | Path",
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
/// A way to create a simple single-file (named `main.py`) completion test
|
/// A way to create a simple single-file (named `main.py`) completion test
|
||||||
/// builder.
|
/// builder.
|
||||||
///
|
///
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load Diff
|
|
@ -295,7 +295,7 @@ impl<'db> Definitions<'db> {
|
||||||
|
|
||||||
impl GotoTarget<'_> {
|
impl GotoTarget<'_> {
|
||||||
pub(crate) fn inferred_type<'db>(&self, model: &SemanticModel<'db>) -> Option<Type<'db>> {
|
pub(crate) fn inferred_type<'db>(&self, model: &SemanticModel<'db>) -> Option<Type<'db>> {
|
||||||
let ty = match self {
|
match self {
|
||||||
GotoTarget::Expression(expression) => expression.inferred_type(model),
|
GotoTarget::Expression(expression) => expression.inferred_type(model),
|
||||||
GotoTarget::FunctionDef(function) => function.inferred_type(model),
|
GotoTarget::FunctionDef(function) => function.inferred_type(model),
|
||||||
GotoTarget::ClassDef(class) => class.inferred_type(model),
|
GotoTarget::ClassDef(class) => class.inferred_type(model),
|
||||||
|
|
@ -317,7 +317,7 @@ impl GotoTarget<'_> {
|
||||||
} => {
|
} => {
|
||||||
// We don't currently support hovering the bare `.` so there is always a name
|
// We don't currently support hovering the bare `.` so there is always a name
|
||||||
let module = import_name(module_name, *component_index);
|
let module = import_name(module_name, *component_index);
|
||||||
model.resolve_module_type(Some(module), *level)?
|
model.resolve_module_type(Some(module), *level)
|
||||||
}
|
}
|
||||||
GotoTarget::StringAnnotationSubexpr {
|
GotoTarget::StringAnnotationSubexpr {
|
||||||
string_expr,
|
string_expr,
|
||||||
|
|
@ -334,16 +334,16 @@ impl GotoTarget<'_> {
|
||||||
} else {
|
} else {
|
||||||
// TODO: force the typechecker to tell us its secrets
|
// TODO: force the typechecker to tell us its secrets
|
||||||
// (it computes but then immediately discards these types)
|
// (it computes but then immediately discards these types)
|
||||||
return None;
|
None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
GotoTarget::BinOp { expression, .. } => {
|
GotoTarget::BinOp { expression, .. } => {
|
||||||
let (_, ty) = ty_python_semantic::definitions_for_bin_op(model, expression)?;
|
let (_, ty) = ty_python_semantic::definitions_for_bin_op(model, expression)?;
|
||||||
ty
|
Some(ty)
|
||||||
}
|
}
|
||||||
GotoTarget::UnaryOp { expression, .. } => {
|
GotoTarget::UnaryOp { expression, .. } => {
|
||||||
let (_, ty) = ty_python_semantic::definitions_for_unary_op(model, expression)?;
|
let (_, ty) = ty_python_semantic::definitions_for_unary_op(model, expression)?;
|
||||||
ty
|
Some(ty)
|
||||||
}
|
}
|
||||||
// TODO: Support identifier targets
|
// TODO: Support identifier targets
|
||||||
GotoTarget::PatternMatchRest(_)
|
GotoTarget::PatternMatchRest(_)
|
||||||
|
|
@ -353,10 +353,8 @@ impl GotoTarget<'_> {
|
||||||
| GotoTarget::TypeParamParamSpecName(_)
|
| GotoTarget::TypeParamParamSpecName(_)
|
||||||
| GotoTarget::TypeParamTypeVarTupleName(_)
|
| GotoTarget::TypeParamTypeVarTupleName(_)
|
||||||
| GotoTarget::NonLocal { .. }
|
| GotoTarget::NonLocal { .. }
|
||||||
| GotoTarget::Globals { .. } => return None,
|
| GotoTarget::Globals { .. } => None,
|
||||||
};
|
}
|
||||||
|
|
||||||
Some(ty)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Try to get a simplified display of this callable type by resolving overloads
|
/// Try to get a simplified display of this callable type by resolving overloads
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue