Skip to content

Flag useless string expressions in preview - #27558

Draft
MichaReiser wants to merge 6 commits into
mainfrom
micha/b018-useless-strings
Draft

Flag useless string expressions in preview#27558
MichaReiser wants to merge 6 commits into
mainfrom
micha/b018-useless-strings

Conversation

@MichaReiser

@MichaReiser MichaReiser commented Aug 6, 2026

Copy link
Copy Markdown
Member

Summary

  • Flag standalone string literals and f-strings as B018 in preview mode.
  • Preserve attribute docstrings after module/class assignments, PEP 695 type statements, and instance attribute assignments directly in a class-defined __init__.

Closes #11292.

The open question from #11292 is whether this should be a separate rule so that projects using string literals as section separators can enable the remaining B018 checks:

...

"""MAIN"""

if __name__ == "__main__":
    block()

"""AFTER MAIN"""

more()

Test Plan

  • Added mdtests for useless string expressions and the relevant docstring exclusions.
  • Added focused coverage for PEP 695 type alias docstrings at module and class scope.
  • Added focused coverage for __init__ instance attributes, annotated attributes, custom instance-parameter names, rebound receivers, locals, nested assignments, and other methods.
  • cargo nextest run -p ruff_linter -p ruff_mdtest (2,837 passed)
  • cargo clippy -p ruff_linter --all-targets --all-features -- -D warnings
  • cargo dev generate-all
  • Repository hooks for the changed files

@MichaReiser MichaReiser added rule Implementing or modifying a lint rule preview Related to preview mode features labels Aug 6, 2026
@MichaReiser MichaReiser closed this Aug 7, 2026
@MichaReiser MichaReiser reopened this Aug 7, 2026
@astral-sh-bot

astral-sh-bot Bot commented Aug 7, 2026

Copy link
Copy Markdown

ruff-ecosystem results

Linter (stable)

✅ ecosystem check detected no linter changes.

Linter (preview)

ℹ️ ecosystem check detected linter changes. (+4357 -1 violations, +0 -0 fixes in 26 projects; 33 projects unchanged)

PostHog/HouseWatch (+2 -0 violations, +0 -0 fixes)

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

+ housewatch/async_migrations/runner.py:19:1: useless-expression Found useless expression. Either assign it to a variable or remove it.
+ housewatch/clickhouse/backups.py:32:5: useless-expression Found useless expression. Either assign it to a variable or remove it.

PlasmaPy/PlasmaPy (+10 -0 violations, +0 -0 fixes)

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

+ docs/_author_list_from_cff.py:199:5: useless-expression Found useless expression. Either assign it to a variable or remove it.
+ docs/_global_substitutions.py:223:5: useless-expression Found useless expression. Either assign it to a variable or remove it.
+ src/plasmapy/formulary/dielectric.py:31:1: useless-expression Found useless expression. Either assign it to a variable or remove it.
+ tests/diagnostics/charged_particle_radiography/test_synthetic_radiography.py:1008:5: useless-expression Found useless expression. Either assign it to a variable or remove it.
+ tests/diagnostics/charged_particle_radiography/test_synthetic_radiography.py:883:5: useless-expression Found useless expression. Either assign it to a variable or remove it.
+ tests/simulation/test_particle_tracker.py:1070:9: useless-expression Found useless expression. Either assign it to a variable or remove it.
+ tests/simulation/test_particle_tracker.py:837:9: useless-expression Found useless expression. Either assign it to a variable or remove it.
+ tests/simulation/test_particle_tracker.py:868:9: useless-expression Found useless expression. Either assign it to a variable or remove it.
+ tests/simulation/test_particle_tracker.py:964:9: useless-expression Found useless expression. Either assign it to a variable or remove it.
+ tests/simulation/test_particle_tracker.py:996:9: useless-expression Found useless expression. Either assign it to a variable or remove it.

apache/airflow (+71 -0 violations, +0 -0 fixes)

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

+ airflow-core/src/airflow/dag_processing/manager.py:1175:9: useless-expression Found useless expression. Either assign it to a variable or remove it.
+ airflow-core/src/airflow/example_dags/example_asset_partition.py:146:5: useless-expression Found useless expression. Either assign it to a variable or remove it.
+ airflow-core/src/airflow/example_dags/example_asset_partition.py:167:5: useless-expression Found useless expression. Either assign it to a variable or remove it.
+ airflow-core/src/airflow/example_dags/example_asset_partition.py:188:5: useless-expression Found useless expression. Either assign it to a variable or remove it.
+ airflow-core/src/airflow/example_dags/example_asset_partition.py:214:5: useless-expression Found useless expression. Either assign it to a variable or remove it.
+ airflow-core/src/airflow/example_dags/example_asset_partition.py:272:5: useless-expression Found useless expression. Either assign it to a variable or remove it.
+ airflow-core/src/airflow/example_dags/example_asset_partition.py:329:5: useless-expression Found useless expression. Either assign it to a variable or remove it.
+ airflow-core/src/airflow/example_dags/example_asset_partition.py:362:5: useless-expression Found useless expression. Either assign it to a variable or remove it.
+ airflow-core/src/airflow/example_dags/example_asset_partition.py:393:5: useless-expression Found useless expression. Either assign it to a variable or remove it.
+ airflow-core/src/airflow/example_dags/example_asset_partition.py:426:5: useless-expression Found useless expression. Either assign it to a variable or remove it.
... 61 additional changes omitted for project

apache/superset (+37 -0 violations, +0 -0 fixes)

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

+ tests/integration_tests/db_engine_specs/base_engine_spec_tests.py:118:9: useless-expression Found useless expression. Either assign it to a variable or remove it.
+ tests/integration_tests/db_engine_specs/postgres_tests.py:41:9: useless-expression Found useless expression. Either assign it to a variable or remove it.
+ tests/integration_tests/query_context_tests.py:1296:5: useless-expression Found useless expression. Either assign it to a variable or remove it.
+ tests/integration_tests/query_context_tests.py:1348:5: useless-expression Found useless expression. Either assign it to a variable or remove it.
+ tests/integration_tests/query_context_tests.py:1407:5: useless-expression Found useless expression. Either assign it to a variable or remove it.
+ tests/integration_tests/query_context_tests.py:1424:5: useless-expression Found useless expression. Either assign it to a variable or remove it.
+ tests/integration_tests/sqla_models_tests.py:756:5: useless-expression Found useless expression. Either assign it to a variable or remove it.
+ tests/unit_tests/common/test_process_time_range.py:27:5: useless-expression Found useless expression. Either assign it to a variable or remove it.
+ tests/unit_tests/common/test_process_time_range.py:36:5: useless-expression Found useless expression. Either assign it to a variable or remove it.
+ tests/unit_tests/pandas_postprocessing/test_compare.py:121:5: useless-expression Found useless expression. Either assign it to a variable or remove it.
... 27 additional changes omitted for project

binary-husky/gpt_academic (+27 -0 violations, +0 -0 fixes)

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

+ config.py:22:5: useless-expression Found useless expression. Either assign it to a variable or remove it.
+ crazy_functional.py:745:5: useless-expression Found useless expression. Either assign it to a variable or remove it.
+ crazy_functions/Document_Conversation.py:199:9: useless-expression Found useless expression. Either assign it to a variable or remove it.
+ crazy_functions/Paper_Reading.py:70:9: useless-expression Found useless expression. Either assign it to a variable or remove it.
+ crazy_functions/game_fns/game_interactive_story.py:125:9: useless-expression Found useless expression. Either assign it to a variable or remove it.
+ crazy_functions/game_fns/game_interactive_story.py:129:13: useless-expression Found useless expression. Either assign it to a variable or remove it.
+ crazy_functions/game_fns/game_interactive_story.py:159:13: useless-expression Found useless expression. Either assign it to a variable or remove it.
+ crazy_functions/game_fns/game_interactive_story.py:194:13: useless-expression Found useless expression. Either assign it to a variable or remove it.
+ crazy_functions/latex_fns/latex_toolbox.py:146:1: useless-expression Found useless expression. Either assign it to a variable or remove it.
+ crazy_functions/latex_fns/latex_toolbox.py:278:1: useless-expression Found useless expression. Either assign it to a variable or remove it.
... 17 additional changes omitted for project

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

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

+ tests/unit/bokeh/core/test_serialization.py:1056:1: useless-expression Found useless expression. Either assign it to a variable or remove it.
+ tests/unit/bokeh/embed/test_notebook__embed.py:42:1: useless-expression Found useless expression. Either assign it to a variable or remove it.

demisto/content (+4093 -0 violations, +0 -0 fixes)

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

+ Packs/AHA/Integrations/AHA/AHA.py:103:1: useless-expression Found useless expression. Either assign it to a variable or remove it.
+ Packs/AHA/Integrations/AHA/AHA.py:11:1: useless-expression Found useless expression. Either assign it to a variable or remove it.
+ Packs/AHA/Integrations/AHA/AHA.py:155:1: useless-expression Found useless expression. Either assign it to a variable or remove it.
+ Packs/AHA/Integrations/AHA/AHA.py:228:1: useless-expression Found useless expression. Either assign it to a variable or remove it.
+ Packs/AHA/Integrations/AHA/AHA.py:271:1: useless-expression Found useless expression. Either assign it to a variable or remove it.
+ Packs/AHA/Integrations/AHA/AHA.py:51:1: useless-expression Found useless expression. Either assign it to a variable or remove it.
+ Packs/AMP/Integrations/AMPv2/AMPv2.py:1162:1: useless-expression Found useless expression. Either assign it to a variable or remove it.
+ Packs/AMP/Integrations/AMPv2/AMPv2.py:16:1: useless-expression Found useless expression. Either assign it to a variable or remove it.
+ Packs/AMP/Integrations/AMPv2/AMPv2.py:3184:1: useless-expression Found useless expression. Either assign it to a variable or remove it.
+ Packs/AMP/Integrations/AMPv2/AMPv2.py:3649:1: useless-expression Found useless expression. Either assign it to a variable or remove it.
+ Packs/AMP/Integrations/AMPv2/AMPv2.py:4:1: useless-expression Found useless expression. Either assign it to a variable or remove it.
+ Packs/AMP/Integrations/CiscoAMPEventCollector/CiscoAMPEventCollector.py:10:1: useless-expression Found useless expression. Either assign it to a variable or remove it.
+ Packs/AMP/Integrations/CiscoAMPEventCollector/CiscoAMPEventCollector.py:197:1: useless-expression Found useless expression. Either assign it to a variable or remove it.
+ Packs/AMP/Integrations/CiscoAMPEventCollector/CiscoAMPEventCollector.py:238:1: useless-expression Found useless expression. Either assign it to a variable or remove it.
+ Packs/ANYRUN/Integrations/ANYRUN/ANYRUN.py:16:1: useless-expression Found useless expression. Either assign it to a variable or remove it.
+ Packs/ANYRUN/Integrations/ANYRUN/ANYRUN.py:52:1: useless-expression Found useless expression. Either assign it to a variable or remove it.
+ Packs/ANYRUN/Integrations/ANYRUN/ANYRUN.py:684:1: useless-expression Found useless expression. Either assign it to a variable or remove it.
+ Packs/ANYRUN/Integrations/ANYRUN/ANYRUN.py:6:1: useless-expression Found useless expression. Either assign it to a variable or remove it.
+ Packs/ANYRUN/Integrations/ANYRUN/ANYRUN.py:871:1: useless-expression Found useless expression. Either assign it to a variable or remove it.
+ Packs/APIVoid/Integrations/APIVoid/APIVoid.py:13:1: useless-expression Found useless expression. Either assign it to a variable or remove it.
+ Packs/APIVoid/Integrations/APIVoid/APIVoid.py:5:1: useless-expression Found useless expression. Either assign it to a variable or remove it.
+ Packs/ARIAPacketIntelligence/Integrations/ARIAPacketIntelligence/ARIAPacketIntelligence.py:115:5: useless-expression Found useless expression. Either assign it to a variable or remove it.
+ Packs/ARIAPacketIntelligence/Integrations/ARIAPacketIntelligence/ARIAPacketIntelligence.py:1274:5: useless-expression Found useless expression. Either assign it to a variable or remove it.
+ Packs/ARIAPacketIntelligence/Integrations/ARIAPacketIntelligence/ARIAPacketIntelligence.py:139:5: useless-expression Found useless expression. Either assign it to a variable or remove it.
+ Packs/ARIAPacketIntelligence/Integrations/ARIAPacketIntelligence/ARIAPacketIntelligence.py:159:5: useless-expression Found useless expression. Either assign it to a variable or remove it.
+ Packs/ARIAPacketIntelligence/Integrations/ARIAPacketIntelligence/ARIAPacketIntelligence.py:15:1: useless-expression Found useless expression. Either assign it to a variable or remove it.
+ Packs/ARIAPacketIntelligence/Integrations/ARIAPacketIntelligence/ARIAPacketIntelligence.py:2176:1: useless-expression Found useless expression. Either assign it to a variable or remove it.
+ Packs/ARIAPacketIntelligence/Integrations/ARIAPacketIntelligence/ARIAPacketIntelligence.py:2208:1: useless-expression Found useless expression. Either assign it to a variable or remove it.
+ Packs/ARIAPacketIntelligence/Integrations/ARIAPacketIntelligence/ARIAPacketIntelligence.py:222:5: useless-expression Found useless expression. Either assign it to a variable or remove it.
+ Packs/ARIAPacketIntelligence/Integrations/ARIAPacketIntelligence/ARIAPacketIntelligence.py:238:5: useless-expression Found useless expression. Either assign it to a variable or remove it.
+ Packs/ARIAPacketIntelligence/Integrations/ARIAPacketIntelligence/ARIAPacketIntelligence.py:295:5: useless-expression Found useless expression. Either assign it to a variable or remove it.
+ Packs/ARIAPacketIntelligence/Integrations/ARIAPacketIntelligence/ARIAPacketIntelligence.py:32:9: useless-expression Found useless expression. Either assign it to a variable or remove it.
+ Packs/ARIAPacketIntelligence/Integrations/ARIAPacketIntelligence/ARIAPacketIntelligence.py:353:5: useless-expression Found useless expression. Either assign it to a variable or remove it.
+ Packs/ARIAPacketIntelligence/Integrations/ARIAPacketIntelligence/ARIAPacketIntelligence.py:37:5: useless-expression Found useless expression. Either assign it to a variable or remove it.
+ Packs/ARIAPacketIntelligence/Integrations/ARIAPacketIntelligence/ARIAPacketIntelligence.py:44:5: useless-expression Found useless expression. Either assign it to a variable or remove it.
+ Packs/ARIAPacketIntelligence/Integrations/ARIAPacketIntelligence/ARIAPacketIntelligence.py:521:5: useless-expression Found useless expression. Either assign it to a variable or remove it.
+ Packs/ARIAPacketIntelligence/Integrations/ARIAPacketIntelligence/ARIAPacketIntelligence.py:572:13: useless-expression Found useless expression. Either assign it to a variable or remove it.
+ Packs/ARIAPacketIntelligence/Integrations/ARIAPacketIntelligence/ARIAPacketIntelligence.py:622:5: useless-expression Found useless expression. Either assign it to a variable or remove it.
+ Packs/ARIAPacketIntelligence/Integrations/ARIAPacketIntelligence/ARIAPacketIntelligence.py:67:5: useless-expression Found useless expression. Either assign it to a variable or remove it.
+ Packs/ARIAPacketIntelligence/Integrations/ARIAPacketIntelligence/ARIAPacketIntelligence.py:698:5: useless-expression Found useless expression. Either assign it to a variable or remove it.
+ Packs/ARIAPacketIntelligence/Integrations/ARIAPacketIntelligence/ARIAPacketIntelligence.py:748:5: useless-expression Found useless expression. Either assign it to a variable or remove it.
+ Packs/ARIAPacketIntelligence/Integrations/ARIAPacketIntelligence/ARIAPacketIntelligence.py:766:5: useless-expression Found useless expression. Either assign it to a variable or remove it.
+ Packs/ARIAPacketIntelligence/Integrations/ARIAPacketIntelligence/ARIAPacketIntelligence.py:774:5: useless-expression Found useless expression. Either assign it to a variable or remove it.
+ Packs/ARIAPacketIntelligence/Integrations/ARIAPacketIntelligence/ARIAPacketIntelligence.py:790:5: useless-expression Found useless expression. Either assign it to a variable or remove it.
+ Packs/ARIAPacketIntelligence/Integrations/ARIAPacketIntelligence/ARIAPacketIntelligence.py:803:5: useless-expression Found useless expression. Either assign it to a variable or remove it.
+ Packs/ARIAPacketIntelligence/Integrations/ARIAPacketIntelligence/ARIAPacketIntelligence.py:821:5: useless-expression Found useless expression. Either assign it to a variable or remove it.
... 4047 additional changes omitted for project

... Truncated remaining completed project reports due to GitHub comment length restrictions

Changes by rule (2 rules affected)

code total + violation - violation + fix - fix
useless-expression 4357 4357 0 0 0
unused-noqa 1 0 1 0 0

@yonatangross

This comment was marked as low quality.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

preview Related to preview mode features rule Implementing or modifying a lint rule

Projects

None yet

Development

Successfully merging this pull request may close these issues.

False negative with useless-expression on strings

2 participants