I have a function wrapper like this
def fun(arg, kwarg=None): # in my code the function is imported from a package
return None
def mywrap(myarg, funkwargs={"kwarg": "default"}):
return fun(myarg, **funkwargs)
If I run flake8 including Bugbear, I get the B006 warning:
$ flake8 above_example.py
above_example.py:5:29: B006 Do not use mutable data structures for argument defaults. They are created during function definition time. All calls to the function reuse this one instance of that data structure, persisting changes between them.
In the case above, where I like to have some default settings provided to fun
, what is the intended way to do this?
Version:
$ flake8 --version
3.7.9 (flake8-bugbear: 19.8.0, mccabe: 0.6.1, pycodestyle: 2.5.0, pyflakes: 2.1.1) CPython 3.7.3 on Linux
If the answer is "use None
", would the following be the "proper" way?
def mywrap(myarg: Any, funkwargs: Optional[Dict[Any, Any]]=None) -> None:
"""MyWrap.
Parameters
----------
myarg : Any
funkwargs : Dict[Any, Any], Optional
Default `{"kwarg": "default"}`.
"""
if not funkwargs:
funkwargs = {"kwarg": "default"}
return fun(myarg, **funkwargs)
The "right" answer is types.MappingProxyType
. This creates a read-only view on the original dictionary.
def mywrap(myarg, funkwargs=types.MappingProxyType({"kwarg": "default"})):
return fun(myarg, **funkwargs)
Much better than using None
as the default.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With