Skip to content

Commit

Permalink
Exclude pragma comments from measured line width (#7008)
Browse files Browse the repository at this point in the history
Co-authored-by: Micha Reiser <micha@reiser.io>
  • Loading branch information
cnpryer and MichaReiser authored Sep 1, 2023
1 parent 376d3ca commit 17a44c0
Show file tree
Hide file tree
Showing 7 changed files with 132 additions and 291 deletions.
Original file line number Diff line number Diff line change
@@ -1,6 +1,29 @@
# Pragma reserved width fixtures
i = ("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",) # noqa: This shouldn't break
i = ("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",) # type: This shouldn't break
i = ("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",) # pyright: This shouldn't break
i = ("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",) # pylint: This shouldn't break
i = ("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",) # noqa This shouldn't break
i = ("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",) # nocoverage: This should break


# Pragma fixtures for non-breaking space (lead by NBSP)
i = ("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",) # noqa: This shouldn't break
i = ("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",) # type: This shouldn't break
i = ("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",) # pyright: This shouldn't break
i = ("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",) # pylint: This shouldn't break
i = ("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",) # noqa This shouldn't break
i = ("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",) # nocoverage: This should break


# As of adding this fixture Black adds a space before the non-breaking space if part of a type pragma.
# https://github.com/psf/black/blob/b4dca26c7d93f930bbd5a7b552807370b60d4298/src/black/comments.py#L122-L129
i2 = "" #  type: Add space before leading NBSP followed by spaces
i3 = "" #type: A space is added
i4 = "" #  type: Add space before leading NBSP followed by a space
i5 = "" # type: Add space before leading NBSP
i = "" #  type: Add space before leading NBSP followed by spaces
i = "" #type: A space is added
i = "" #  type: Add space before leading NBSP followed by a space
i = "" # type: Add space before leading NBSP
i = "" #  type: Add space before two leading NBSP


# A noqa as `#\u{A0}\u{A0}noqa` becomes `# \u{A0}noqa`
i = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" #  noqa
53 changes: 38 additions & 15 deletions crates/ruff_python_formatter/src/comments/format.rs
Original file line number Diff line number Diff line change
Expand Up @@ -357,17 +357,33 @@ impl Format<PyFormatContext<'_>> for FormatTrailingEndOfLineComment<'_> {

let normalized_comment = normalize_comment(self.comment, source)?;

// Start with 2 because of the two leading spaces.
let mut reserved_width = 2;

// SAFE: The formatted file is <= 4GB, and each comment should as well.
#[allow(clippy::cast_possible_truncation)]
for c in normalized_comment.chars() {
reserved_width += match c {
'\t' => f.options().tab_width().value(),
c => c.width().unwrap_or(0) as u32,
// Trim the normalized comment to detect excluded pragmas (strips NBSP).
let trimmed = strip_comment_prefix(&normalized_comment)?.trim_start();

let is_pragma = if let Some((maybe_pragma, _)) = trimmed.split_once(':') {
matches!(maybe_pragma, "noqa" | "type" | "pyright" | "pylint")
} else {
trimmed.starts_with("noqa")
};

// Don't reserve width for excluded pragma comments.
let reserved_width = if is_pragma {
0
} else {
// Start with 2 because of the two leading spaces.
let mut width = 2;

// SAFETY: The formatted file is <= 4GB, and each comment should as well.
#[allow(clippy::cast_possible_truncation)]
for c in normalized_comment.chars() {
width += match c {
'\t' => f.options().tab_width().value(),
c => c.width().unwrap_or(0) as u32,
}
}
}

width
};

write!(
f,
Expand Down Expand Up @@ -442,11 +458,7 @@ fn normalize_comment<'a>(

let trimmed = comment_text.trim_end();

let Some(content) = trimmed.strip_prefix('#') else {
return Err(FormatError::syntax_error(
"Didn't find expected comment token `#`",
));
};
let content = strip_comment_prefix(trimmed)?;

if content.is_empty() {
return Ok(Cow::Borrowed("#"));
Expand Down Expand Up @@ -476,6 +488,17 @@ fn normalize_comment<'a>(
Ok(Cow::Owned(std::format!("# {}", content.trim_start())))
}

/// A helper for stripping '#' from comments.
fn strip_comment_prefix(comment_text: &str) -> FormatResult<&str> {
let Some(content) = comment_text.strip_prefix('#') else {
return Err(FormatError::syntax_error(
"Didn't find expected comment token `#`",
));
};

Ok(content)
}

/// Format the empty lines between a node and its trailing comments.
///
/// For example, given:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,7 @@ aaaaaaaaaaaaa, bbbbbbbbb = map(list, map(itertools.chain.from_iterable, zip(*ite
)
@@ -108,11 +112,20 @@
@@ -108,11 +112,18 @@
"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
)
Expand All @@ -176,10 +176,7 @@ aaaaaaaaaaaaa, bbbbbbbbb = map(list, map(itertools.chain.from_iterable, zip(*ite
+ ], # type: ignore
)
-aaaaaaaaaaaaa, bbbbbbbbb = map(list, map(itertools.chain.from_iterable, zip(*items))) # type: ignore[arg-type]
+aaaaaaaaaaaaa, bbbbbbbbb = map(
+ list, map(itertools.chain.from_iterable, zip(*items))
+) # type: ignore[arg-type]
aaaaaaaaaaaaa, bbbbbbbbb = map(list, map(itertools.chain.from_iterable, zip(*items))) # type: ignore[arg-type]
```

## Ruff Output
Expand Down Expand Up @@ -313,9 +310,7 @@ call_to_some_function_asdf(
], # type: ignore
)
aaaaaaaaaaaaa, bbbbbbbbb = map(
list, map(itertools.chain.from_iterable, zip(*items))
) # type: ignore[arg-type]
aaaaaaaaaaaaa, bbbbbbbbb = map(list, map(itertools.chain.from_iterable, zip(*items))) # type: ignore[arg-type]
```

## Black Output
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -300,17 +300,6 @@ last_call()
) # note: no trailing comma pre-3.6
call(*gidgets[:2])
call(a, *gidgets[:2])
@@ -142,7 +143,9 @@
xxxx_xxxxx_xxxx_xxx: Callable[..., List[SomeClass]] = classmethod( # type: ignore
sync(async_xxxx_xxx_xxxx_xxxxx_xxxx_xxx.__func__)
)
-xxxx_xxx_xxxx_xxxxx_xxxx_xxx: Callable[..., List[SomeClass]] = classmethod( # type: ignore
+xxxx_xxx_xxxx_xxxxx_xxxx_xxx: Callable[
+ ..., List[SomeClass]
+] = classmethod( # type: ignore
sync(async_xxxx_xxx_xxxx_xxxxx_xxxx_xxx.__func__)
)
xxxx_xxx_xxxx_xxxxx_xxxx_xxx: Callable[..., List[SomeClass]] = classmethod(
```
## Ruff Output
Expand Down Expand Up @@ -461,9 +450,7 @@ very_long_variable_name_filters: t.List[
xxxx_xxxxx_xxxx_xxx: Callable[..., List[SomeClass]] = classmethod( # type: ignore
sync(async_xxxx_xxx_xxxx_xxxxx_xxxx_xxx.__func__)
)
xxxx_xxx_xxxx_xxxxx_xxxx_xxx: Callable[
..., List[SomeClass]
] = classmethod( # type: ignore
xxxx_xxx_xxxx_xxxxx_xxxx_xxx: Callable[..., List[SomeClass]] = classmethod( # type: ignore
sync(async_xxxx_xxx_xxxx_xxxxx_xxxx_xxx.__func__)
)
xxxx_xxx_xxxx_xxxxx_xxxx_xxx: Callable[..., List[SomeClass]] = classmethod(
Expand Down
Loading

0 comments on commit 17a44c0

Please sign in to comment.