Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Avoid mutable-class-default (RUF012) for fully untyped classes #5275

Closed
wants to merge 1 commit into from

Conversation

charliermarsh
Copy link
Member

Summary

This PR attempts to avoid flagging mutable class attributes (and suggesting that they be annotated with ClassVar) for classes that are fully untyped. I'm somewhat undecided on it (the underlying issue is still present, but the suggested fix isn't applicable), but you can see the discussion in #5243.

Comment on lines 54 to 55
if class_def.body.iter().any(Stmt::is_ann_assign_stmt) {
for statement in &class_def.body {
Copy link
Member

Choose a reason for hiding this comment

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

This changes the runtime of this rule to always iterate over the body twice. I don't know if this is a big issue, considering that classes only have a few top-level statements (it skips over all function bodies).

However, I don't have a good idea that is guaranteed to be faster:

  • Collecting the diagnostics and ignoring them if no assignment statement was seen is probably slower it requires allocating the diagnostics Vec and the messages in DiagnosticKind.
  • Filtering out the AnnAssignStmt and AnnAssign statements and storing them in a Vec. Running is_any and the check only over that sublist. Again, the allocation may be as expensive as iterating over all statements.

@aberres
Copy link

aberres commented Jun 30, 2023

I think this would solve most of the false positives in our (mostly) typed codebase.

@zanieb zanieb added the needs-decision Awaiting a decision from a maintainer label Oct 19, 2023
@zanieb
Copy link
Member

zanieb commented Oct 19, 2023

There's no other way to indicate that a mutable class default is the desired behavior, is there? Could we look for mutation of the variable outside of @classmethod annotated functions? 😬

Copy link
Contributor

ruff-ecosystem results

Linter (stable)

ℹ️ ecosystem check detected linter changes. (+6 -1661 violations, +0 -0 fixes in 41 projects)

RasaHQ/rasa (+4 -0 violations, +0 -0 fixes)

+ rasa/core/channels/twilio_voice.py:21:27: RUF100 [*] Unused `noqa` directive (unused: `RUF012`)
+ rasa/core/channels/twilio_voice.py:91:34: RUF100 [*] Unused `noqa` directive (unused: `RUF012`)
+ rasa/core/evaluation/marker_tracker_loader.py:31:24: RUF100 [*] Unused `noqa` directive (unused: `RUF012`)
+ rasa/core/featurizers/precomputation.py:60:64: RUF100 [*] Unused `noqa` directive (unused: `RUF012`)

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

ruff check --no-cache --exit-zero --no-preview --select ALL

- airflow/api_connexion/schemas/common_schema.py:106:20: RUF012 Mutable class attributes should be annotated with `typing.ClassVar`
- airflow/example_dags/plugins/listener_plugin.py:26:17: RUF012 Mutable class attributes should be annotated with `typing.ClassVar`
- airflow/example_dags/plugins/workday.py:103:18: RUF012 Mutable class attributes should be annotated with `typing.ClassVar`
- airflow/operators/python.py:309:38: RUF012 Mutable class attributes should be annotated with `typing.ClassVar`
- airflow/operators/python.py:330:42: RUF012 Mutable class attributes should be annotated with `typing.ClassVar`
- airflow/operators/python.py:343:41: RUF012 Mutable class attributes should be annotated with `typing.ClassVar`
- airflow/providers/alibaba/cloud/hooks/analyticdb_spark.py:71:23: RUF012 Mutable class attributes should be annotated with `typing.ClassVar`
- airflow/providers/amazon/aws/hooks/emr.py:256:31: RUF012 Mutable class attributes should be annotated with `typing.ClassVar`
- airflow/providers/amazon/aws/hooks/emr.py:257:26: RUF012 Mutable class attributes should be annotated with `typing.ClassVar`
- airflow/providers/amazon/aws/hooks/emr.py:258:26: RUF012 Mutable class attributes should be annotated with `typing.ClassVar`
- airflow/providers/amazon/aws/hooks/emr.py:261:39: RUF012 Mutable class attributes should be annotated with `typing.ClassVar`
- airflow/providers/amazon/aws/hooks/emr.py:262:34: RUF012 Mutable class attributes should be annotated with `typing.ClassVar`
... 390 additional changes omitted for project

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

ruff check --no-cache --exit-zero --no-preview --select ALL

- examples/advanced/extensions/font-awesome/fontawesome_icon.py:11:24: RUF012 Mutable class attributes should be annotated with `typing.ClassVar`
- examples/advanced/extensions/widget.py:15:22: RUF012 Mutable class attributes should be annotated with `typing.ClassVar`
- src/bokeh/core/property/visual.py:84:22: RUF012 Mutable class attributes should be annotated with `typing.ClassVar`
- src/bokeh/models/glyphs.py:797:18: RUF012 Mutable class attributes should be annotated with `typing.ClassVar`
- src/bokeh/sphinxext/bokeh_color.py:74:19: RUF012 Mutable class attributes should be annotated with `typing.ClassVar`
- src/bokeh/sphinxext/bokeh_enum.py:95:19: RUF012 Mutable class attributes should be annotated with `typing.ClassVar`
- src/bokeh/sphinxext/bokeh_example_metadata.py:70:19: RUF012 Mutable class attributes should be annotated with `typing.ClassVar`
- src/bokeh/sphinxext/bokeh_jinja.py:77:19: RUF012 Mutable class attributes should be annotated with `typing.ClassVar`
- src/bokeh/sphinxext/bokeh_model.py:105:19: RUF012 Mutable class attributes should be annotated with `typing.ClassVar`
- src/bokeh/sphinxext/bokeh_options.py:96:19: RUF012 Mutable class attributes should be annotated with `typing.ClassVar`
... 18 additional changes omitted for project

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

+ tools/pylint/log_checker.py:30:15: RUF100 [*] Unused `noqa` directive (unused: `RUF012`)
+ tools/pylint/not_checker.py:20:15: RUF100 [*] Unused `noqa` directive (unused: `RUF012`)

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

ruff check --no-cache --exit-zero --no-preview --select ALL

- analytics/migrations/0001_initial.py:12:18: RUF012 Mutable class attributes should be annotated with `typing.ClassVar`
- analytics/migrations/0001_initial.py:7:20: RUF012 Mutable class attributes should be annotated with `typing.ClassVar`
- analytics/migrations/0002_remove_huddlecount.py:5:20: RUF012 Mutable class attributes should be annotated with `typing.ClassVar`
- analytics/migrations/0002_remove_huddlecount.py:9:18: RUF012 Mutable class attributes should be annotated with `typing.ClassVar`
- analytics/migrations/0003_fillstate.py:5:20: RUF012 Mutable class attributes should be annotated with `typing.ClassVar`
- analytics/migrations/0003_fillstate.py:9:18: RUF012 Mutable class attributes should be annotated with `typing.ClassVar`
- analytics/migrations/0004_add_subgroup.py:5:20: RUF012 Mutable class attributes should be annotated with `typing.ClassVar`
- analytics/migrations/0004_add_subgroup.py:9:18: RUF012 Mutable class attributes should be annotated with `typing.ClassVar`
- analytics/migrations/0005_alter_field_size.py:5:20: RUF012 Mutable class attributes should be annotated with `typing.ClassVar`
- analytics/migrations/0005_alter_field_size.py:9:18: RUF012 Mutable class attributes should be annotated with `typing.ClassVar`
- analytics/migrations/0006_add_subgroup_to_unique_constraints.py:5:20: RUF012 Mutable class attributes should be annotated with `typing.ClassVar`
- analytics/migrations/0006_add_subgroup_to_unique_constraints.py:9:18: RUF012 Mutable class attributes should be annotated with `typing.ClassVar`
- analytics/migrations/0007_remove_interval.py:10:18: RUF012 Mutable class attributes should be annotated with `typing.ClassVar`
- analytics/migrations/0007_remove_interval.py:6:20: RUF012 Mutable class attributes should be annotated with `typing.ClassVar`
- analytics/migrations/0008_add_count_indexes.py:11:18: RUF012 Mutable class attributes should be annotated with `typing.ClassVar`
- analytics/migrations/0008_add_count_indexes.py:6:20: RUF012 Mutable class attributes should be annotated with `typing.ClassVar`
- analytics/migrations/0009_remove_messages_to_stream_stat.py:24:20: RUF012 Mutable class attributes should be annotated with `typing.ClassVar`
- analytics/migrations/0009_remove_messages_to_stream_stat.py:28:18: RUF012 Mutable class attributes should be annotated with `typing.ClassVar`
- analytics/migrations/0010_clear_messages_sent_values.py:24:20: RUF012 Mutable class attributes should be annotated with `typing.ClassVar`
- analytics/migrations/0010_clear_messages_sent_values.py:26:18: RUF012 Mutable class attributes should be annotated with `typing.ClassVar`
- analytics/migrations/0011_clear_analytics_tables.py:21:20: RUF012 Mutable class attributes should be annotated with `typing.ClassVar`
- analytics/migrations/0011_clear_analytics_tables.py:25:18: RUF012 Mutable class attributes should be annotated with `typing.ClassVar`
- analytics/migrations/0012_add_on_delete.py:12:18: RUF012 Mutable class attributes should be annotated with `typing.ClassVar`
- analytics/migrations/0012_add_on_delete.py:8:20: RUF012 Mutable class attributes should be annotated with `typing.ClassVar`
- analytics/migrations/0013_remove_anomaly.py:11:18: RUF012 Mutable class attributes should be annotated with `typing.ClassVar`
- analytics/migrations/0013_remove_anomaly.py:7:20: RUF012 Mutable class attributes should be annotated with `typing.ClassVar`
- analytics/migrations/0014_remove_fillstate_last_modified.py:11:18: RUF012 Mutable class attributes should be annotated with `typing.ClassVar`
- analytics/migrations/0014_remove_fillstate_last_modified.py:7:20: RUF012 Mutable class attributes should be annotated with `typing.ClassVar`
- analytics/migrations/0015_clear_duplicate_counts.py:58:20: RUF012 Mutable class attributes should be annotated with `typing.ClassVar`
- analytics/migrations/0015_clear_duplicate_counts.py:62:18: RUF012 Mutable class attributes should be annotated with `typing.ClassVar`
- analytics/migrations/0016_unique_constraint_when_subgroup_null.py:11:18: RUF012 Mutable class attributes should be annotated with `typing.ClassVar`
- analytics/migrations/0016_unique_constraint_when_subgroup_null.py:7:20: RUF012 Mutable class attributes should be annotated with `typing.ClassVar`
- analytics/migrations/0017_regenerate_partial_indexes.py:17:18: RUF012 Mutable class attributes should be annotated with `typing.ClassVar`
- analytics/migrations/0017_regenerate_partial_indexes.py:5:20: RUF012 Mutable class attributes should be annotated with `typing.ClassVar`
- analytics/models.py:106:23: RUF012 Mutable class attributes should be annotated with `typing.ClassVar`
- analytics/models.py:120:19: RUF012 Mutable class attributes should be annotated with `typing.ClassVar`
... 1195 additional changes omitted for project

Changes by rule (2 rules affected)

code total + violation - violation + fix - fix
RUF012 1661 0 1661 0 0
RUF100 6 6 0 0 0

Linter (preview)

ℹ️ ecosystem check detected linter changes. (+6 -1563 violations, +0 -0 fixes in 41 projects)

RasaHQ/rasa (+4 -0 violations, +0 -0 fixes)

ruff check --no-cache --exit-zero --preview

+ rasa/core/channels/twilio_voice.py:21:27: RUF100 [*] Unused `noqa` directive (unused: `RUF012`)
+ rasa/core/channels/twilio_voice.py:91:34: RUF100 [*] Unused `noqa` directive (unused: `RUF012`)
+ rasa/core/evaluation/marker_tracker_loader.py:31:24: RUF100 [*] Unused `noqa` directive (unused: `RUF012`)
+ rasa/core/featurizers/precomputation.py:60:64: RUF100 [*] Unused `noqa` directive (unused: `RUF012`)

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

ruff check --no-cache --exit-zero --preview --select ALL

- airflow/api_connexion/schemas/common_schema.py:106:20: RUF012 Mutable class attributes should be annotated with `typing.ClassVar`
- airflow/example_dags/plugins/listener_plugin.py:26:17: RUF012 Mutable class attributes should be annotated with `typing.ClassVar`
- airflow/example_dags/plugins/workday.py:103:18: RUF012 Mutable class attributes should be annotated with `typing.ClassVar`
- airflow/operators/python.py:309:38: RUF012 Mutable class attributes should be annotated with `typing.ClassVar`
- airflow/operators/python.py:330:42: RUF012 Mutable class attributes should be annotated with `typing.ClassVar`
- airflow/operators/python.py:343:41: RUF012 Mutable class attributes should be annotated with `typing.ClassVar`
- airflow/providers/alibaba/cloud/hooks/analyticdb_spark.py:71:23: RUF012 Mutable class attributes should be annotated with `typing.ClassVar`
- airflow/providers/amazon/aws/hooks/emr.py:256:31: RUF012 Mutable class attributes should be annotated with `typing.ClassVar`
- airflow/providers/amazon/aws/hooks/emr.py:257:26: RUF012 Mutable class attributes should be annotated with `typing.ClassVar`
- airflow/providers/amazon/aws/hooks/emr.py:258:26: RUF012 Mutable class attributes should be annotated with `typing.ClassVar`
... 295 additional changes omitted for project

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

ruff check --no-cache --exit-zero --preview --select ALL

- examples/advanced/extensions/font-awesome/fontawesome_icon.py:11:24: RUF012 Mutable class attributes should be annotated with `typing.ClassVar`
- examples/advanced/extensions/widget.py:15:22: RUF012 Mutable class attributes should be annotated with `typing.ClassVar`
- src/bokeh/models/glyphs.py:797:18: RUF012 Mutable class attributes should be annotated with `typing.ClassVar`
- src/bokeh/sphinxext/bokeh_color.py:74:19: RUF012 Mutable class attributes should be annotated with `typing.ClassVar`
- src/bokeh/sphinxext/bokeh_enum.py:95:19: RUF012 Mutable class attributes should be annotated with `typing.ClassVar`
- src/bokeh/sphinxext/bokeh_example_metadata.py:70:19: RUF012 Mutable class attributes should be annotated with `typing.ClassVar`
- src/bokeh/sphinxext/bokeh_jinja.py:77:19: RUF012 Mutable class attributes should be annotated with `typing.ClassVar`
- src/bokeh/sphinxext/bokeh_model.py:105:19: RUF012 Mutable class attributes should be annotated with `typing.ClassVar`
- src/bokeh/sphinxext/bokeh_options.py:96:19: RUF012 Mutable class attributes should be annotated with `typing.ClassVar`
- src/bokeh/sphinxext/bokeh_plot.py:157:19: RUF012 Mutable class attributes should be annotated with `typing.ClassVar`
... 17 additional changes omitted for project

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

ruff check --no-cache --exit-zero --preview

+ tools/pylint/log_checker.py:30:15: RUF100 [*] Unused `noqa` directive (unused: `RUF012`)
+ tools/pylint/not_checker.py:20:15: RUF100 [*] Unused `noqa` directive (unused: `RUF012`)

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

ruff check --no-cache --exit-zero --preview --select ALL

- analytics/migrations/0001_initial.py:12:18: RUF012 Mutable class attributes should be annotated with `typing.ClassVar`
- analytics/migrations/0001_initial.py:7:20: RUF012 Mutable class attributes should be annotated with `typing.ClassVar`
- analytics/migrations/0002_remove_huddlecount.py:5:20: RUF012 Mutable class attributes should be annotated with `typing.ClassVar`
- analytics/migrations/0002_remove_huddlecount.py:9:18: RUF012 Mutable class attributes should be annotated with `typing.ClassVar`
- analytics/migrations/0003_fillstate.py:5:20: RUF012 Mutable class attributes should be annotated with `typing.ClassVar`
- analytics/migrations/0003_fillstate.py:9:18: RUF012 Mutable class attributes should be annotated with `typing.ClassVar`
- analytics/migrations/0004_add_subgroup.py:5:20: RUF012 Mutable class attributes should be annotated with `typing.ClassVar`
- analytics/migrations/0004_add_subgroup.py:9:18: RUF012 Mutable class attributes should be annotated with `typing.ClassVar`
- analytics/migrations/0005_alter_field_size.py:5:20: RUF012 Mutable class attributes should be annotated with `typing.ClassVar`
- analytics/migrations/0005_alter_field_size.py:9:18: RUF012 Mutable class attributes should be annotated with `typing.ClassVar`
- analytics/migrations/0006_add_subgroup_to_unique_constraints.py:5:20: RUF012 Mutable class attributes should be annotated with `typing.ClassVar`
- analytics/migrations/0006_add_subgroup_to_unique_constraints.py:9:18: RUF012 Mutable class attributes should be annotated with `typing.ClassVar`
- analytics/migrations/0007_remove_interval.py:10:18: RUF012 Mutable class attributes should be annotated with `typing.ClassVar`
- analytics/migrations/0007_remove_interval.py:6:20: RUF012 Mutable class attributes should be annotated with `typing.ClassVar`
- analytics/migrations/0008_add_count_indexes.py:11:18: RUF012 Mutable class attributes should be annotated with `typing.ClassVar`
- analytics/migrations/0008_add_count_indexes.py:6:20: RUF012 Mutable class attributes should be annotated with `typing.ClassVar`
- analytics/migrations/0009_remove_messages_to_stream_stat.py:24:20: RUF012 Mutable class attributes should be annotated with `typing.ClassVar`
- analytics/migrations/0009_remove_messages_to_stream_stat.py:28:18: RUF012 Mutable class attributes should be annotated with `typing.ClassVar`
- analytics/migrations/0010_clear_messages_sent_values.py:24:20: RUF012 Mutable class attributes should be annotated with `typing.ClassVar`
- analytics/migrations/0010_clear_messages_sent_values.py:26:18: RUF012 Mutable class attributes should be annotated with `typing.ClassVar`
- analytics/migrations/0011_clear_analytics_tables.py:21:20: RUF012 Mutable class attributes should be annotated with `typing.ClassVar`
- analytics/migrations/0011_clear_analytics_tables.py:25:18: RUF012 Mutable class attributes should be annotated with `typing.ClassVar`
- analytics/migrations/0012_add_on_delete.py:12:18: RUF012 Mutable class attributes should be annotated with `typing.ClassVar`
- analytics/migrations/0012_add_on_delete.py:8:20: RUF012 Mutable class attributes should be annotated with `typing.ClassVar`
- analytics/migrations/0013_remove_anomaly.py:11:18: RUF012 Mutable class attributes should be annotated with `typing.ClassVar`
- analytics/migrations/0013_remove_anomaly.py:7:20: RUF012 Mutable class attributes should be annotated with `typing.ClassVar`
- analytics/migrations/0014_remove_fillstate_last_modified.py:11:18: RUF012 Mutable class attributes should be annotated with `typing.ClassVar`
- analytics/migrations/0014_remove_fillstate_last_modified.py:7:20: RUF012 Mutable class attributes should be annotated with `typing.ClassVar`
- analytics/migrations/0015_clear_duplicate_counts.py:58:20: RUF012 Mutable class attributes should be annotated with `typing.ClassVar`
- analytics/migrations/0015_clear_duplicate_counts.py:62:18: RUF012 Mutable class attributes should be annotated with `typing.ClassVar`
- analytics/migrations/0016_unique_constraint_when_subgroup_null.py:11:18: RUF012 Mutable class attributes should be annotated with `typing.ClassVar`
- analytics/migrations/0016_unique_constraint_when_subgroup_null.py:7:20: RUF012 Mutable class attributes should be annotated with `typing.ClassVar`
- analytics/migrations/0017_regenerate_partial_indexes.py:17:18: RUF012 Mutable class attributes should be annotated with `typing.ClassVar`
- analytics/migrations/0017_regenerate_partial_indexes.py:5:20: RUF012 Mutable class attributes should be annotated with `typing.ClassVar`
- analytics/models.py:106:23: RUF012 Mutable class attributes should be annotated with `typing.ClassVar`
- analytics/models.py:120:19: RUF012 Mutable class attributes should be annotated with `typing.ClassVar`
- analytics/models.py:138:23: RUF012 Mutable class attributes should be annotated with `typing.ClassVar`
- analytics/models.py:152:19: RUF012 Mutable class attributes should be annotated with `typing.ClassVar`
- analytics/models.py:53:23: RUF012 Mutable class attributes should be annotated with `typing.ClassVar`
... 1192 additional changes omitted for project

Changes by rule (2 rules affected)

code total + violation - violation + fix - fix
RUF012 1563 0 1563 0 0
RUF100 6 6 0 0 0

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
needs-decision Awaiting a decision from a maintainer
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants