Open layday opened 11 hours ago
Also appears to be the case for tuple
, and only if they are parametrised, i.e. frozenset()
is accepted but not frozenset[type]()
.
Conversely, the error is silenced if the context var is an annotated mutable type:
$ cat foo.py
from contextvars import ContextVar
foo = ContextVar[set[str]]('foo', default=set()) # No error
bar = ContextVar('bar', default=set())
$ ruff check --select B039 foo.py
foo.py:4:33: B039 Do not use mutable data structures for `ContextVar` defaults
|
3 | foo = ContextVar[set[str]]('foo', default=set()) # No error
4 | bar = ContextVar('bar', default=set())
| ^^^^^ B039
|
= help: Replace with `None`; initialize with `.set()``
Found 1 error.
To recap:
from contextvars import ContextVar
# All of these should produce an error but foo3 and foo4 don't.
foo1 = ContextVar('foo1', default=set())
foo2 = ContextVar('foo2', default=set[object]())
foo3 = ContextVar[set[object]]('foo3', default=set())
foo4 = ContextVar[set[object]]('foo4', default=set[object]())
foo5: ContextVar[set[object]] = ContextVar('foo5', default=set())
foo6: ContextVar[set[object]] = ContextVar('foo6', default=set[object]())
# None of these should produce an error but bar2 and bar6 do.
bar1 = ContextVar('bar1', default=frozenset())
bar2 = ContextVar('bar2', default=frozenset[object]())
bar3 = ContextVar[frozenset[object]]('bar3', default=frozenset())
bar4 = ContextVar[frozenset[object]]('bar4', default=frozenset[object]())
bar5: ContextVar[frozenset[object]] = ContextVar('bar5', default=frozenset())
bar6: ContextVar[frozenset[object]] = ContextVar('bar6', default=frozenset[object]())
@AlexWaygood can I work on this?
@harupy sure!
@harupy this function will probably be helpful in fixing some of the issues here: https://github.com/astral-sh/ruff/blob/b80de52592f7b4c9854a454e2b7a0121fe2862e4/crates/ruff_python_ast/src/helpers.rs#L660-L670
@AlexWaygood Thanks!
Filed #14532