Skip to content

Commit

Permalink
Fix various bugs found via running the test suite
Browse files Browse the repository at this point in the history
  • Loading branch information
dhruvmanila committed May 30, 2024
1 parent e113c34 commit c137200
Show file tree
Hide file tree
Showing 11 changed files with 100 additions and 90 deletions.
2 changes: 1 addition & 1 deletion crates/ruff_linter/src/checkers/ast/analyze/expression.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1160,7 +1160,7 @@ pub(crate) fn expression(expr: &Expr, checker: &mut Checker) {
}
}
if checker.enabled(Rule::PrintfStringFormatting) {
pyupgrade::rules::printf_string_formatting(checker, format_string, right);
pyupgrade::rules::printf_string_formatting(checker, bin_op, format_string);
}
if checker.enabled(Rule::BadStringFormatCharacter) {
pylint::rules::bad_string_format_character::percent(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ pub(crate) fn implicit(
let (a_range, b_range) = match (a_token.kind(), b_token.kind()) {
(TokenKind::String, TokenKind::String) => (a_token.range(), b_token.range()),
(TokenKind::String, TokenKind::FStringStart) => {
match indexer.fstring_ranges().innermost(a_token.start()) {
match indexer.fstring_ranges().innermost(b_token.start()) {
Some(b_range) => (a_token.range(), b_range),
None => continue,
}
Expand Down
91 changes: 47 additions & 44 deletions crates/ruff_linter/src/rules/pycodestyle/rules/blank_lines.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ use itertools::Itertools;
use ruff_notebook::CellOffsets;
use ruff_python_parser::Token;
use ruff_python_parser::Tokens;
use ruff_text_size::Ranged;
use std::cmp::Ordering;
use std::iter::Peekable;
use std::num::NonZeroU32;
Expand Down Expand Up @@ -436,55 +435,59 @@ impl<'a> Iterator for LinePreprocessor<'a> {
continue;
}

let (logical_line_kind, first_token_range) = if let Some(first_token_range) =
first_logical_line_token
{
first_token_range
}
// At the start of the line...
else {
// Check if we are at the beginning of a cell in a notebook.
if let Some(ref mut cell_offsets) = self.cell_offsets {
if cell_offsets
.peek()
.is_some_and(|offset| offset == &&self.line_start)
{
self.is_beginning_of_cell = true;
cell_offsets.next();
blank_lines = BlankLines::Zero;
self.max_preceding_blank_lines = BlankLines::Zero;
}
let (logical_line_kind, first_token_range) =
if let Some(first_token_range) = first_logical_line_token {
first_token_range
}
// At the start of the line...
else {
// Check if we are at the beginning of a cell in a notebook.
if let Some(ref mut cell_offsets) = self.cell_offsets {
if cell_offsets
.peek()
.is_some_and(|offset| offset == &&self.line_start)
{
self.is_beginning_of_cell = true;
cell_offsets.next();
blank_lines = BlankLines::Zero;
self.max_preceding_blank_lines = BlankLines::Zero;
}
}

// An empty line
if kind == TokenKind::NonLogicalNewline {
blank_lines.add(range);

self.line_start = range.end();
// An empty line
if kind == TokenKind::NonLogicalNewline {
blank_lines.add(range);

continue;
}
self.line_start = range.end();

is_docstring = kind == TokenKind::String;

let logical_line_kind = match kind {
TokenKind::Class => LogicalLineKind::Class,
TokenKind::Comment => LogicalLineKind::Comment,
TokenKind::At => LogicalLineKind::Decorator,
TokenKind::Def => LogicalLineKind::Function,
// Lookahead to distinguish `async def` from `async with`.
TokenKind::Async if matches!(self.tokens.peek(), Some((TokenKind::Def, _))) => {
LogicalLineKind::Function
continue;
}
TokenKind::Import => LogicalLineKind::Import,
TokenKind::From => LogicalLineKind::FromImport,
_ => LogicalLineKind::Other,
};

first_logical_line_token = Some((logical_line_kind, range));
is_docstring = kind == TokenKind::String;

let logical_line_kind = match kind {
TokenKind::Class => LogicalLineKind::Class,
TokenKind::Comment => LogicalLineKind::Comment,
TokenKind::At => LogicalLineKind::Decorator,
TokenKind::Def => LogicalLineKind::Function,
// Lookahead to distinguish `async def` from `async with`.
TokenKind::Async
if self
.tokens
.peek()
.is_some_and(|token| token.kind() == TokenKind::Def) =>
{
LogicalLineKind::Function
}
TokenKind::Import => LogicalLineKind::Import,
TokenKind::From => LogicalLineKind::FromImport,
_ => LogicalLineKind::Other,
};

first_logical_line_token = Some((logical_line_kind, range));

(logical_line_kind, range)
};
(logical_line_kind, range)
};

if !kind.is_trivia() {
line_is_comment_only = false;
Expand Down Expand Up @@ -543,7 +546,7 @@ impl<'a> Iterator for LinePreprocessor<'a> {
}

if !kind.is_trivia() {
last_token = token;
last_token = kind;
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use ruff_diagnostics::{AlwaysFixableViolation, Diagnostic, Edit, Fix};
use ruff_macros::{derive_message_formats, violation};
use ruff_python_ast::helpers;
use ruff_python_parser::{TokenKind, Tokens};
use ruff_text_size::{Ranged, TextRange, TextSize};
use ruff_text_size::{Ranged, TextRange};

use crate::checkers::ast::Checker;

Expand Down Expand Up @@ -110,7 +110,7 @@ pub(crate) fn invalid_literal_comparison(
} {
diagnostic.set_fix(Fix::safe_edit(Edit::range_replacement(
content,
located_op.range + expr.start(),
located_op.range,
)));
}
} else {
Expand Down Expand Up @@ -175,11 +175,9 @@ fn locate_cmp_ops(expr: &Expr, tokens: &Tokens) -> Vec<LocatedCmpOp> {

match token.kind() {
TokenKind::Not => {
if let Some((_, next_range)) =
tok_iter.next_if(|token| token.kind() == TokenKind::In)
{
if let Some(next_token) = tok_iter.next_if(|token| token.kind() == TokenKind::In) {
ops.push(LocatedCmpOp::new(
TextRange::new(token.start(), next_range.end()),
TextRange::new(token.start(), next_token.end()),
CmpOp::NotIn,
));
}
Expand All @@ -188,11 +186,11 @@ fn locate_cmp_ops(expr: &Expr, tokens: &Tokens) -> Vec<LocatedCmpOp> {
ops.push(LocatedCmpOp::new(token.range(), CmpOp::In));
}
TokenKind::Is => {
let op = if let Some((_, next_range)) =
let op = if let Some(next_token) =
tok_iter.next_if(|token| token.kind() == TokenKind::Not)
{
LocatedCmpOp::new(
TextRange::new(token.start(), next_range.end()),
TextRange::new(token.start(), next_token.end()),
CmpOp::IsNot,
)
} else {
Expand Down
10 changes: 5 additions & 5 deletions crates/ruff_linter/src/rules/pyupgrade/fixes.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use ruff_python_ast::{Alias, StmtImportFrom};
use ruff_python_parser::{lexer, Mode, Tok, TokenKind, Tokens};
use ruff_python_ast::StmtImportFrom;
use ruff_python_parser::{TokenKind, Tokens};
use ruff_source_file::Locator;
use ruff_text_size::{Ranged, TextRange, TextSize};
use ruff_text_size::{Ranged, TextRange};

/// Remove any imports matching `members` from an import-from statement.
pub(crate) fn remove_import_members(
Expand All @@ -25,7 +25,7 @@ pub(crate) fn remove_import_members(

// Reconstruct the source code by skipping any names that are in `members`.
let mut output = String::with_capacity(import_from_stmt.range().len().to_usize());
let mut last_pos = TextSize::default();
let mut last_pos = import_from_stmt.start();
let mut is_first = true;

for (index, member) in import_from_stmt.names.iter().enumerate() {
Expand Down Expand Up @@ -58,7 +58,7 @@ pub(crate) fn remove_import_members(
}

// Add the remaining content.
let slice = locator.after(last_pos);
let slice = locator.slice(TextRange::new(last_pos, import_from_stmt.end()));
output.push_str(slice);
output
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use ruff_python_codegen::Stylist;
use ruff_python_literal::cformat::{
CConversionFlags, CFormatPart, CFormatPrecision, CFormatQuantity, CFormatString,
};
use ruff_python_parser::{lexer, AsMode, Tok, TokenKind};
use ruff_python_parser::TokenKind;
use ruff_python_stdlib::identifiers::is_identifier;
use ruff_source_file::Locator;
use ruff_text_size::{Ranged, TextRange};
Expand Down Expand Up @@ -346,9 +346,11 @@ fn convertible(format_string: &CFormatString, params: &Expr) -> bool {
/// UP031
pub(crate) fn printf_string_formatting(
checker: &mut Checker,
bin_op: &ast::ExprBinOp,
string_expr: &ast::ExprStringLiteral,
right: &Expr,
) {
let right = &*bin_op.right;

let mut num_positional_arguments = 0;
let mut num_keyword_arguments = 0;
let mut format_strings: Vec<(TextRange, String)> =
Expand Down Expand Up @@ -434,14 +436,14 @@ pub(crate) fn printf_string_formatting(
// Reconstruct the string.
let mut contents = String::new();
let mut prev_end = None;
for (range, format_string) in format_strings.into_iter() {
for (range, format_string) in format_strings {
// Add the content before the string segment.
match prev_end {
None => {
contents.push_str(
checker
.locator()
.slice(TextRange::new(string_expr.start(), range.start())),
.slice(TextRange::new(bin_op.start(), range.start())),
);
}
Some(prev_end) => {
Expand Down Expand Up @@ -478,10 +480,10 @@ pub(crate) fn printf_string_formatting(
// Add the `.format` call.
contents.push_str(&format!(".format{params_string}"));

let mut diagnostic = Diagnostic::new(PrintfStringFormatting, string_expr.range());
let mut diagnostic = Diagnostic::new(PrintfStringFormatting, bin_op.range());
diagnostic.set_fix(Fix::unsafe_edit(Edit::range_replacement(
contents,
string_expr.range(),
bin_op.range(),
)));
checker.diagnostics.push(diagnostic);
}
Expand Down
6 changes: 3 additions & 3 deletions crates/ruff_python_formatter/src/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ pub struct PyFormatContext<'a> {
options: PyFormatOptions,
contents: &'a str,
comments: Comments<'a>,
tokens: &Tokens,
tokens: &'a Tokens,
node_level: NodeLevel,
indent_level: IndentLevel,
/// Set to a non-None value when the formatter is running on a code
Expand All @@ -34,7 +34,7 @@ impl<'a> PyFormatContext<'a> {
options: PyFormatOptions,
contents: &'a str,
comments: Comments<'a>,
tokens: &Tokens,
tokens: &'a Tokens,
) -> Self {
Self {
options,
Expand Down Expand Up @@ -77,7 +77,7 @@ impl<'a> PyFormatContext<'a> {
&self.comments
}

pub(crate) fn tokens(&self) -> &Tokens {
pub(crate) fn tokens(&self) -> &'a Tokens {
self.tokens
}

Expand Down
8 changes: 4 additions & 4 deletions crates/ruff_python_formatter/src/verbatim.rs
Original file line number Diff line number Diff line change
Expand Up @@ -792,8 +792,8 @@ struct LogicalLinesIter<'a> {
content_end: TextSize,
}

impl LogicalLinesIter<'_> {
fn new(tokens: Iter<'_, parser::Token>, verbatim_range: TextRange) -> Self {
impl<'a> LogicalLinesIter<'a> {
fn new(tokens: Iter<'a, parser::Token>, verbatim_range: TextRange) -> Self {
Self {
tokens,
last_line_end: verbatim_range.start(),
Expand All @@ -802,7 +802,7 @@ impl LogicalLinesIter<'_> {
}
}

impl Iterator for LogicalLinesIter {
impl<'a> Iterator for LogicalLinesIter<'a> {
type Item = FormatResult<LogicalLine>;

fn next(&mut self) -> Option<Self::Item> {
Expand Down Expand Up @@ -856,7 +856,7 @@ impl Iterator for LogicalLinesIter {
}
}

impl<I> FusedIterator for LogicalLinesIter<I> where I: Iterator<Item = parser::Token> {}
impl<'a> FusedIterator for LogicalLinesIter<'a> {}

/// A logical line or a comment (or form feed only) line
struct LogicalLine {
Expand Down
2 changes: 1 addition & 1 deletion crates/ruff_python_index/src/multiline_ranges.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ pub(crate) struct MultilineRangesBuilder {

impl MultilineRangesBuilder {
pub(crate) fn visit_token(&mut self, token: &Token) {
if matches!(token.kind(), TokenKind::String | TokenKind::FStringStart) {
if matches!(token.kind(), TokenKind::String | TokenKind::FStringMiddle) {
if token.is_triple_quoted_string() {
self.ranges.push(token.range());
}
Expand Down
Loading

0 comments on commit c137200

Please sign in to comment.