Skip to content

[flake8-pytest-style] Make fixes safe by default and unsafe only when comments are present (PT018) - #27201

Merged
ntBre merged 3 commits into
astral-sh:mainfrom
jesco-absolut:fix-20698-pt018-fix-safety
Jul 28, 2026
Merged

ntBre merged 3 commits into
astral-sh:mainfrom
jesco-absolut:fix-20698-pt018-fix-safety

Conversation

@jesco-absolut

Copy link
Copy Markdown
Contributor

Summary

Fixes #20698.

  • Default Fix Safety: The PT018 rule splits composite assertions into individual assert statements. Because standard transformations (without custom messages) maintain short-circuiting and original runtime behavior, these fixes are now classified as safe by default, rather than marking every fix as unsafe.
  • Handling Comments: Previously, Ruff completely disabled fixes for assertions containing comments. Now, assertions with internal comments will still offer a fix, but marked with an unsafe classification to ensure user verification while preserving functionality.

Proposed fixed will now composite assertion with an internal comment. Ordinary transformations are safe while the comment-bearing case receives an unsafe fix and this is verified.

Test Plan

  • Ran the focused PT018 fixture and snapshot test:
    cargo test -p ruff_linter --lib rule_pytestcompositeassertion_path_new_pt018_py_settings_default_pt018_expects
  • Ran cargo fmt --all --check

@astral-sh-bot
astral-sh-bot Bot requested a review from ntBre July 26, 2026 23:08
@astral-sh-bot

astral-sh-bot Bot commented Jul 26, 2026

Copy link
Copy Markdown

ruff-ecosystem results

Linter (stable)

✅ ecosystem check detected no linter changes.

Linter (preview)

ℹ️ ecosystem check detected linter changes. (+53 -53 violations, +0 -0 fixes in 3 projects; 54 projects unchanged)

bokeh/bokeh (+21 -21 violations, +0 -0 fixes)

ruff check --no-cache --exit-zero --no-fix --output-format concise --preview --select ALL

- tests/unit/bokeh/application/handlers/test_server_lifecycle.py:184:9: pytest-composite-assertion Assertion should be broken down into multiple parts
+ tests/unit/bokeh/application/handlers/test_server_lifecycle.py:184:9: pytest-composite-assertion [*] Assertion should be broken down into multiple parts
- tests/unit/bokeh/application/handlers/test_server_request_handler.py:98:9: pytest-composite-assertion Assertion should be broken down into multiple parts
+ tests/unit/bokeh/application/handlers/test_server_request_handler.py:98:9: pytest-composite-assertion [*] Assertion should be broken down into multiple parts
- tests/unit/bokeh/command/subcommands/test_settings__subcommands.py:96:5: pytest-composite-assertion Assertion should be broken down into multiple parts
+ tests/unit/bokeh/command/subcommands/test_settings__subcommands.py:96:5: pytest-composite-assertion [*] Assertion should be broken down into multiple parts
- tests/unit/bokeh/core/property/test_wrappers__property.py:178:5: pytest-composite-assertion Assertion should be broken down into multiple parts
+ tests/unit/bokeh/core/property/test_wrappers__property.py:178:5: pytest-composite-assertion [*] Assertion should be broken down into multiple parts
- tests/unit/bokeh/core/test_json_encoder.py:41:5: pytest-composite-assertion Assertion should be broken down into multiple parts
+ tests/unit/bokeh/core/test_json_encoder.py:41:5: pytest-composite-assertion [*] Assertion should be broken down into multiple parts
- tests/unit/bokeh/embed/test_standalone.py:406:13: pytest-composite-assertion Assertion should be broken down into multiple parts
+ tests/unit/bokeh/embed/test_standalone.py:406:13: pytest-composite-assertion [*] Assertion should be broken down into multiple parts
- tests/unit/bokeh/embed/test_standalone.py:413:13: pytest-composite-assertion Assertion should be broken down into multiple parts
+ tests/unit/bokeh/embed/test_standalone.py:413:13: pytest-composite-assertion [*] Assertion should be broken down into multiple parts
- tests/unit/bokeh/io/test_export.py:257:5: pytest-composite-assertion Assertion should be broken down into multiple parts
+ tests/unit/bokeh/io/test_export.py:257:5: pytest-composite-assertion [*] Assertion should be broken down into multiple parts
- tests/unit/bokeh/io/test_export.py:471:9: pytest-composite-assertion Assertion should be broken down into multiple parts
+ tests/unit/bokeh/io/test_export.py:471:9: pytest-composite-assertion [*] Assertion should be broken down into multiple parts
- tests/unit/bokeh/models/test_sources.py:513:9: pytest-composite-assertion Assertion should be broken down into multiple parts
... 23 additional changes omitted for project

latchbio/latch (+1 -1 violations, +0 -0 fixes)

ruff check --no-cache --exit-zero --no-fix --output-format concise --preview

- src/latch_cli/services/register/register.py:256:9: pytest-composite-assertion Assertion should be broken down into multiple parts
+ src/latch_cli/services/register/register.py:256:9: pytest-composite-assertion [*] Assertion should be broken down into multiple parts

zulip/zulip (+31 -31 violations, +0 -0 fixes)

ruff check --no-cache --exit-zero --no-fix --output-format concise --preview --select ALL

- corporate/lib/stripe.py:1315:9: pytest-composite-assertion Assertion should be broken down into multiple parts
+ corporate/lib/stripe.py:1315:9: pytest-composite-assertion [*] Assertion should be broken down into multiple parts
- corporate/lib/stripe.py:1420:9: pytest-composite-assertion Assertion should be broken down into multiple parts
+ corporate/lib/stripe.py:1420:9: pytest-composite-assertion [*] Assertion should be broken down into multiple parts
- corporate/lib/stripe.py:4337:13: pytest-composite-assertion Assertion should be broken down into multiple parts
+ corporate/lib/stripe.py:4337:13: pytest-composite-assertion [*] Assertion should be broken down into multiple parts
- corporate/lib/stripe.py:805:9: pytest-composite-assertion Assertion should be broken down into multiple parts
+ corporate/lib/stripe.py:805:9: pytest-composite-assertion [*] Assertion should be broken down into multiple parts
- zerver/actions/user_settings.py:191:9: pytest-composite-assertion Assertion should be broken down into multiple parts
+ zerver/actions/user_settings.py:191:9: pytest-composite-assertion [*] Assertion should be broken down into multiple parts
- zerver/lib/bot_lib.py:162:5: pytest-composite-assertion Assertion should be broken down into multiple parts
+ zerver/lib/bot_lib.py:162:5: pytest-composite-assertion [*] Assertion should be broken down into multiple parts
- zerver/lib/email_notifications.py:691:9: pytest-composite-assertion Assertion should be broken down into multiple parts
+ zerver/lib/email_notifications.py:691:9: pytest-composite-assertion [*] Assertion should be broken down into multiple parts
- zerver/lib/email_notifications.py:877:9: pytest-composite-assertion Assertion should be broken down into multiple parts
+ zerver/lib/email_notifications.py:877:9: pytest-composite-assertion [*] Assertion should be broken down into multiple parts
- zerver/lib/email_notifications.py:933:9: pytest-composite-assertion Assertion should be broken down into multiple parts
+ zerver/lib/email_notifications.py:933:9: pytest-composite-assertion [*] Assertion should be broken down into multiple parts
- zerver/lib/export.py:699:13: pytest-composite-assertion Assertion should be broken down into multiple parts
+ zerver/lib/export.py:699:13: pytest-composite-assertion [*] Assertion should be broken down into multiple parts
- zerver/lib/import_realm.py:699:9: pytest-composite-assertion Assertion should be broken down into multiple parts
+ zerver/lib/import_realm.py:699:9: pytest-composite-assertion [*] Assertion should be broken down into multiple parts
- zerver/lib/notification_data.py:38:13: pytest-composite-assertion Assertion should be broken down into multiple parts
+ zerver/lib/notification_data.py:38:13: pytest-composite-assertion [*] Assertion should be broken down into multiple parts
- zerver/lib/notification_data.py:51:13: pytest-composite-assertion Assertion should be broken down into multiple parts
+ zerver/lib/notification_data.py:51:13: pytest-composite-assertion [*] Assertion should be broken down into multiple parts
- zerver/lib/push_notifications.py:1081:9: pytest-composite-assertion Assertion should be broken down into multiple parts
+ zerver/lib/push_notifications.py:1081:9: pytest-composite-assertion [*] Assertion should be broken down into multiple parts
- zerver/lib/push_notifications.py:150:13: pytest-composite-assertion Assertion should be broken down into multiple parts
... 33 additional changes omitted for project

Changes by rule (1 rules affected)

code total + violation - violation + fix - fix
pytest-composite-assertion 106 53 53 0 0

@jesco-absolut jesco-absolut changed the title PT018 when no comments are affected, the fix is safe and also remove unsafe fix if comments were to be removed. PT018 fixes are safe without affected comments and unsafe when comments would be removed Jul 26, 2026

@ntBre ntBre left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This is a stable rule, so we have to make this change in preview in accordance with our Versioning policy.

@ntBre ntBre added fixes Related to suggested fixes for violations preview Related to preview mode features labels Jul 27, 2026

@ntBre ntBre left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Thank you!

@ntBre ntBre changed the title PT018 fixes are safe without affected comments and unsafe when comments would be removed [flake8-pytest-style] Make fixes safe by default and unsafe only when comments are present (PT018) Jul 28, 2026
@ntBre
ntBre enabled auto-merge (squash) July 28, 2026 14:44
@ntBre
ntBre merged commit 1082445 into astral-sh:main Jul 28, 2026
46 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

fixes Related to suggested fixes for violations preview Related to preview mode features

Projects

None yet

Development

Successfully merging this pull request may close these issues.

PT018 fix should be safe instead of unsafe generally, and unsafe with comments instead of suppressed

2 participants