ruff icon indicating copy to clipboard operation
ruff copied to clipboard

Flag mutable defaults based on mutable annotations

Open charliermarsh opened this issue 1 year ago • 5 comments

Summary

We'll now flag def foo(a: list = LIST): ... as a mutable default based on the annotation. (If it is immutable, the annotation should be Sequence.)

I want to see what the ecosystem checks look like here. It might be too noisy.

Closes #11030.

charliermarsh avatar Apr 24 '24 03:04 charliermarsh

ruff-ecosystem results

Linter (stable)

ℹ️ ecosystem check detected linter changes. (+34 -0 violations, +0 -0 fixes in 4 projects; 40 projects unchanged)

commaai/openpilot (+2 -0 violations, +0 -0 fixes)

+ tools/lib/live_logreader.py:10:46: B006 Do not use mutable data structures for argument defaults
+ tools/lib/live_logreader.py:27:42: B006 Do not use mutable data structures for argument defaults
pandas-dev/pandas (+1 -0 violations, +0 -0 fixes)

+ pandas/io/formats/css.py:351:76: B006 Do not use mutable data structures for argument defaults
reflex-dev/reflex (+3 -0 violations, +0 -0 fixes)

+ reflex/app.py:418:38: B006 Do not use mutable data structures for argument defaults
+ reflex/app.py:571:38: B006 Do not use mutable data structures for argument defaults
+ reflex/utils/prerequisites.py:361:33: B006 Do not use mutable data structures for argument defaults
tiangolo/fastapi (+28 -0 violations, +0 -0 fixes)

+ docs_src/dependencies/tutorial001.py:15:38: B006 Do not use mutable data structures for argument defaults
+ docs_src/dependencies/tutorial001.py:20:38: B006 Do not use mutable data structures for argument defaults
+ docs_src/dependencies/tutorial001_py310.py:11:38: B006 Do not use mutable data structures for argument defaults
+ docs_src/dependencies/tutorial001_py310.py:16:38: B006 Do not use mutable data structures for argument defaults
+ docs_src/dependency_testing/tutorial001.py:16:38: B006 Do not use mutable data structures for argument defaults
+ docs_src/dependency_testing/tutorial001.py:21:38: B006 Do not use mutable data structures for argument defaults
+ docs_src/dependency_testing/tutorial001_py310.py:12:38: B006 Do not use mutable data structures for argument defaults
+ docs_src/dependency_testing/tutorial001_py310.py:17:38: B006 Do not use mutable data structures for argument defaults
+ docs_src/query_params_str_validations/tutorial012_py39.py:7:37: B006 Do not use mutable data structures for argument defaults
+ docs_src/query_params_str_validations/tutorial013.py:7:32: B006 Do not use mutable data structures for argument defaults
+ docs_src/request_files/tutorial002_py39.py:8:45: B006 Do not use mutable data structures for argument defaults
+ docs_src/request_files/tutorial003_py39.py:16:31: B006 Do not use mutable data structures for argument defaults
+ docs_src/request_files/tutorial003_py39.py:9:26: B006 Do not use mutable data structures for argument defaults
+ tests/test_dependency_contextmanager.py:125:39: B006 Do not use mutable data structures for argument defaults
+ tests/test_dependency_contextmanager.py:130:45: B006 Do not use mutable data structures for argument defaults
+ tests/test_dependency_contextmanager.py:137:66: B006 Do not use mutable data structures for argument defaults
+ tests/test_dependency_contextmanager.py:183:38: B006 Do not use mutable data structures for argument defaults
+ tests/test_dependency_contextmanager.py:188:44: B006 Do not use mutable data structures for argument defaults
+ tests/test_dependency_contextmanager.py:196:43: B006 Do not use mutable data structures for argument defaults
+ tests/test_dependency_contextmanager.py:74:35: B006 Do not use mutable data structures for argument defaults
+ tests/test_dependency_contextmanager.py:82:35: B006 Do not use mutable data structures for argument defaults
+ tests/test_dependency_normal_exceptions.py:30:50: B006 Do not use mutable data structures for argument defaults
+ tests/test_dependency_normal_exceptions.py:37:59: B006 Do not use mutable data structures for argument defaults
+ tests/test_dependency_overrides.py:18:40: B006 Do not use mutable data structures for argument defaults
+ tests/test_dependency_overrides.py:28:42: B006 Do not use mutable data structures for argument defaults
+ tests/test_dependency_overrides.py:50:53: B006 Do not use mutable data structures for argument defaults
+ tests/test_forms_from_non_typing_sequences.py:13:38: B006 Do not use mutable data structures for argument defaults
+ tests/test_forms_from_non_typing_sequences.py:8:40: B006 Do not use mutable data structures for argument defaults
Changes by rule (1 rules affected)

code total + violation - violation + fix - fix
B006 34 34 0 0 0

Linter (preview)

ℹ️ ecosystem check detected linter changes. (+34 -0 violations, +0 -0 fixes in 4 projects; 40 projects unchanged)

commaai/openpilot (+2 -0 violations, +0 -0 fixes)

ruff check --no-cache --exit-zero --ignore RUF9 --output-format concise --preview

+ tools/lib/live_logreader.py:10:46: B006 Do not use mutable data structures for argument defaults
+ tools/lib/live_logreader.py:27:42: B006 Do not use mutable data structures for argument defaults
pandas-dev/pandas (+1 -0 violations, +0 -0 fixes)

ruff check --no-cache --exit-zero --ignore RUF9 --output-format concise --preview

+ pandas/io/formats/css.py:351:76: B006 Do not use mutable data structures for argument defaults
reflex-dev/reflex (+3 -0 violations, +0 -0 fixes)

ruff check --no-cache --exit-zero --ignore RUF9 --output-format concise --preview

+ reflex/app.py:418:38: B006 Do not use mutable data structures for argument defaults
+ reflex/app.py:571:38: B006 Do not use mutable data structures for argument defaults
+ reflex/utils/prerequisites.py:361:33: B006 Do not use mutable data structures for argument defaults
tiangolo/fastapi (+28 -0 violations, +0 -0 fixes)

ruff check --no-cache --exit-zero --ignore RUF9 --output-format concise --preview

+ docs_src/dependencies/tutorial001.py:15:38: B006 Do not use mutable data structures for argument defaults
+ docs_src/dependencies/tutorial001.py:20:38: B006 Do not use mutable data structures for argument defaults
+ docs_src/dependencies/tutorial001_py310.py:11:38: B006 Do not use mutable data structures for argument defaults
+ docs_src/dependencies/tutorial001_py310.py:16:38: B006 Do not use mutable data structures for argument defaults
+ docs_src/dependency_testing/tutorial001.py:16:38: B006 Do not use mutable data structures for argument defaults
+ docs_src/dependency_testing/tutorial001.py:21:38: B006 Do not use mutable data structures for argument defaults
+ docs_src/dependency_testing/tutorial001_py310.py:12:38: B006 Do not use mutable data structures for argument defaults
+ docs_src/dependency_testing/tutorial001_py310.py:17:38: B006 Do not use mutable data structures for argument defaults
+ docs_src/query_params_str_validations/tutorial012_py39.py:7:37: B006 Do not use mutable data structures for argument defaults
+ docs_src/query_params_str_validations/tutorial013.py:7:32: B006 Do not use mutable data structures for argument defaults
+ docs_src/request_files/tutorial002_py39.py:8:45: B006 Do not use mutable data structures for argument defaults
+ docs_src/request_files/tutorial003_py39.py:16:31: B006 Do not use mutable data structures for argument defaults
+ docs_src/request_files/tutorial003_py39.py:9:26: B006 Do not use mutable data structures for argument defaults
+ tests/test_dependency_contextmanager.py:125:39: B006 Do not use mutable data structures for argument defaults
+ tests/test_dependency_contextmanager.py:130:45: B006 Do not use mutable data structures for argument defaults
+ tests/test_dependency_contextmanager.py:137:66: B006 Do not use mutable data structures for argument defaults
+ tests/test_dependency_contextmanager.py:183:38: B006 Do not use mutable data structures for argument defaults
+ tests/test_dependency_contextmanager.py:188:44: B006 Do not use mutable data structures for argument defaults
+ tests/test_dependency_contextmanager.py:196:43: B006 Do not use mutable data structures for argument defaults
+ tests/test_dependency_contextmanager.py:74:35: B006 Do not use mutable data structures for argument defaults
+ tests/test_dependency_contextmanager.py:82:35: B006 Do not use mutable data structures for argument defaults
+ tests/test_dependency_normal_exceptions.py:30:50: B006 Do not use mutable data structures for argument defaults
+ tests/test_dependency_normal_exceptions.py:37:59: B006 Do not use mutable data structures for argument defaults
+ tests/test_dependency_overrides.py:18:40: B006 Do not use mutable data structures for argument defaults
+ tests/test_dependency_overrides.py:28:42: B006 Do not use mutable data structures for argument defaults
+ tests/test_dependency_overrides.py:50:53: B006 Do not use mutable data structures for argument defaults
+ tests/test_forms_from_non_typing_sequences.py:13:38: B006 Do not use mutable data structures for argument defaults
+ tests/test_forms_from_non_typing_sequences.py:8:40: B006 Do not use mutable data structures for argument defaults
Changes by rule (1 rules affected)

code total + violation - violation + fix - fix
B006 34 34 0 0 0

github-actions[bot] avatar Apr 24 '24 03:04 github-actions[bot]

Just gonna mark as draft since I haven’t had a chance to review the ecosystem results and I’m going to bed.

charliermarsh avatar Apr 24 '24 03:04 charliermarsh

I haven't looked at the code nor the ecosystem checks, but I think my suggestion was to use the TypeChecker to determine if the variable is assigned to a mutable type

https://github.com/astral-sh/ruff/blob/f5c7a62aa65decb9e286bd65ba17f1a3bd1f91e6/crates/ruff_python_semantic/src/analyze/typing.rs#L421-L427

But, I think this could be fine as well.

dhruvmanila avatar Apr 24 '24 05:04 dhruvmanila

The ecosystem checks look good to me, except the FastAPI ones which are... hard to comment on. I'm not sure if they can use this rule?

I'd gate this with preview.

zanieb avatar Apr 24 '24 13:04 zanieb

(I think we generally recommend adding Query to extend-immutable-types or whatever the setting is called.)

charliermarsh avatar Apr 24 '24 13:04 charliermarsh