sourcery
sourcery copied to clipboard
Replace mutable default arguments doesn't respect type annotations
Checklist
- [x] I have searched the Sourcery documentation for the issue, and found nothing
- [x] I have checked there are no open bugs referencing the same bug or problem
Description
The annotation for the parameter that is a Mapping, Sequence or Set aren't expected to support mutation so I think this is a false positive.
Code snippet that reproduces issue
from collections.abc import Mapping
def foo(
self,
passwords: Mapping[int, str] = {},
) -> None:
...
# We suggest making the following changes to Function foo:
# Replace mutable default arguments with None (default-mutable-arg)
Debug Information
Sourcery Version:
v1.0.3
Thanks for reporting it, this is a great question. :+1:
I'm not sure what the right behavior here is. :thinking:
- The type annotation
collections.abc.Mappingindicates thatpasswordsshouldn't be mutated. - The
{}literal creates adict. It can be mutated, even if the type annotation iscollections.abc.Mapping.
For example, this is possible:
In [1]: from collections.abc import Mapping
In [2]: nrs: Mapping[int, str] = {}
In [3]: type(nrs)
Out[3]: dict
In [4]: nrs[3] = "tres"
In [5]: nrs
Out[5]: {3: 'tres'}
I think if the annotation says it shouldn't be mutated this wouldn't type check without narrowing the type to dict inside the function but I feel like that would never actually be a source of bugs.
As a bit of prior art, dataclasses checks if an argument is "mutable" by checking for a __hash__ method
https://github.com/python/cpython/blob/main/Lib/dataclasses.py#L829-L834