Inside dataclasses, fields with mutable default values are quite tricky. They suffer the same issue as mutable default arguments
Consider the following code:
from typing import List
from dataclasses import dataclass
@dataclass
class Inner:
name: str = ""
@dataclass
class Foo:
inner: Inner = Inner()
items: List[str] = []
foo1 = Foo()
foo1.inner.name = "Hello"
foo1.items.append("World")
print(f"{foo1.inner.name=} {foo1.items=}")
foo2 = Foo()
print(f"{foo2.inner.name=} {foo2.items=}")
This will print:
foo1.inner.name='Hello' foo1.items=['World']
foo2.inner.name='Hello' foo2.items=['World']
i.e. Foo members default values are mutable and shared between all instances!
So, my question is:
Is there any static analysis tool and or tool configuration that can reliably warn against dataclasses fields using mutable default values?
Here is the current status I found:
Concerning the member that was built via a function/constructor call ("inner: Inner = Inner()"):
mypy
,pyright
,pylint
,flake8-bugbear
,CLion
(and probably pycharm) will miss itConcerning the member that is a list ("items: List[str] = []"):
CLion
(and probably pycharm) will catch it. It is missed bymypy
,pyright
,pylint
,flake8-bugbear
Note: I already asked a similar question concerning function parameters with mutable default argument and found a static analysis tool that can detect them (I selected flake8-bugbear)