Skip to content

[flake8-bugbear] point previous occurrence (B033)#22634

Merged
ntBre merged 5 commits intoastral-sh:mainfrom
leandrobbraga:feat/improve-b033-error-message
Feb 4, 2026
Merged

[flake8-bugbear] point previous occurrence (B033)#22634
ntBre merged 5 commits intoastral-sh:mainfrom
leandrobbraga:feat/improve-b033-error-message

Conversation

@leandrobbraga
Copy link
Contributor

@leandrobbraga leandrobbraga commented Jan 16, 2026

Improves B033 linting error by pointing to the previous occurrence of the duplicate item.

Before

B033 [*] Sets should not contain duplicate item `"value1"`
 --> B033.py:4:35
4 | incorrect_set = {"value1", 23, 5, "value1"}
  |                                   ^^^^^^^^
help: Remove duplicate item
  - incorrect_set = {"value1", 23, 5, "value1"}
4 + incorrect_set = {"value1", 23, 5}

After

B033 [*] Sets should not contain duplicate item `"value1"`
 --> B033.py:4:18
4 | incorrect_set = {"value1", 23, 5, "value1"}
  |                  --------         ^^^^^^^^ duplicated here
  |                  |
  |                  previous occurrence here
help: Remove duplicate item
  - incorrect_set = {"value1", 23, 5, "value1"}
4 + incorrect_set = {"value1", 23, 5}

@astral-sh-bot
Copy link

astral-sh-bot bot commented Jan 16, 2026

ruff-ecosystem results

Linter (stable)

✅ ecosystem check detected no linter changes.

Linter (preview)

✅ ecosystem check detected no linter changes.

@amyreese amyreese requested a review from ntBre January 16, 2026 23:40
@amyreese amyreese added the rule Implementing or modifying a lint rule label Jan 16, 2026
@amyreese
Copy link
Member

Is there an example showing what would happen if there were three occurrences of the same value in a single set, eg {1, 1, 1}?

…lue.rs

Co-authored-by: Amethyst Reese <amethyst@n7.gg>
@leandrobbraga
Copy link
Contributor Author

leandrobbraga commented Jan 16, 2026

Is there an example showing what would happen if there were three occurrences of the same value in a single set, eg {1, 1, 1}?

It always consider the immediately previous element as the previous occurrence.

$ echo '{1, 1, 1}' | cargo run -p ruff  -- check --select B033 -
B033 [*] Sets should not contain duplicate item `1`
 --> -:1:2
  |
1 | {1, 1, 1}
  |  -  ^ duplicated here
  |  |
  |  previous occurrence here
  |
help: Remove duplicate item

B033 [*] Sets should not contain duplicate item `1`
 --> -:1:5
  |
1 | {1, 1, 1}
  |     -  ^ duplicated here
  |     |
  |     previous occurrence here
  |
help: Remove duplicate item

Found 2 errors.
[*] 2 fixable with the `--fix` option.

@leandrobbraga leandrobbraga changed the title [ruff] point previous occurrence in B033 [flake8-bugbear] point previous occurrence in (B033) Jan 17, 2026
@leandrobbraga leandrobbraga changed the title [flake8-bugbear] point previous occurrence in (B033) [flake8-bugbear] point previous occurrence (B033) Jan 17, 2026
value.range(),
);
diagnostic.secondary_annotation(format_args!("previous occurrence here"), existing);
diagnostic.set_primary_message(format_args!("duplicated here"));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is in line with the two other uses of set_primary_message in Ruff, but one thing to consider here is that the primary annotation message is appended to the concise diagnostic message:

❯ just run check --select B033 --output-format concise - <<<"s = {1, 2, 1}"
-:1:12: B033 [*] Sets should not contain duplicate item `1`: duplicated here

I think this looks slightly awkward, so I would lean towards omitting the primary message, even though it looks nicer in the full output. But I'm curious what you and @amyreese think!

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps we could move the item X out of the diagnostic message in some way, so that it reads more like:

Set contains duplicates: item `X`

Copy link
Contributor Author

@leandrobbraga leandrobbraga Jan 25, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@amyreese I didn’t fully understand. Is this your intended message?

echo "s = {1, 2, 1}" | cargo run -p ruff -- check --select B033 --output-format concise -
-:1:12: B033 [*] Set contains duplicates: item `X`

For consistency, here is the current output for a duplicate in __all__:

echo "__all__ = ['a', 'a']" | cargo run -p ruff -- check --preview --select RUF068 --output-format concise -
-:1:17: RUF068 [*] `__all__` contains duplicate entries: `a` duplicated here

Copy link
Contributor Author

@leandrobbraga leandrobbraga Jan 25, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tested and it seems that removing the primary message works best here. I added a commit removing the primary message.

Full Message

> echo "s = {True, 2, 1}" | cargo run -p ruff -- check --select B033 -
B033 [*] Sets should not contain duplicate items, but `True` and `1` has the same value
 --> -:1:6
  |
1 | s = {True, 2, 1}
  |      ----     ^
  |      |
  |      previous occurrence here
  |
help: Remove duplicate item

Found 1 error.
[*] 1 fixable with the `--fix` option.

Concise message

> echo "s = {True, 2, 1}" | cargo run -p ruff -- check --select B033 --output-format concise -
-:1:15: B033 [*] Sets should not contain duplicate items, but `True` and `1` has the same value
Found 1 error.
[*] 1 fixable with the `--fix` option.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ntBre if you liked this version more, I can remove the primary message from RUF068 as well.

@ntBre ntBre added the diagnostics Related to reporting of diagnostics. label Jan 23, 2026
leandrobbraga and others added 2 commits January 25, 2026 15:50
The primary message was leaving the concise message inconsistent
Copy link
Contributor

@ntBre ntBre left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's move ahead with the current state of the PR. I think it's okay to prioritize the full diagnostic over the concise or other output formats, and I like the way the full diagnostic looks. I pushed one commit capitalizing the P in the secondary annotation, but this is otherwise good to go. Thank you!

@ntBre ntBre enabled auto-merge (squash) February 4, 2026 14:30
@ntBre ntBre merged commit 6a93673 into astral-sh:main Feb 4, 2026
40 checks passed
bxff pushed a commit to bxff/ruff that referenced this pull request Feb 4, 2026
Improves B033 linting error by pointing to the previous occurrence of
the duplicate item.

# Before
```text
B033 [*] Sets should not contain duplicate item `"value1"`
 --> B033.py:4:35
4 | incorrect_set = {"value1", 23, 5, "value1"}
  |                                   ^^^^^^^^
help: Remove duplicate item
  - incorrect_set = {"value1", 23, 5, "value1"}
4 + incorrect_set = {"value1", 23, 5}
```

# After
```text
B033 [*] Sets should not contain duplicate item `"value1"`
 --> B033.py:4:18
4 | incorrect_set = {"value1", 23, 5, "value1"}
  |                  --------         ^^^^^^^^ duplicated here
  |                  |
  |                  previous occurrence here
help: Remove duplicate item
  - incorrect_set = {"value1", 23, 5, "value1"}
4 + incorrect_set = {"value1", 23, 5}
```

---------

Co-authored-by: Amethyst Reese <amethyst@n7.gg>
Co-authored-by: Brent Westbrook <brentrwestbrook@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

diagnostics Related to reporting of diagnostics. rule Implementing or modifying a lint rule

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants