aboutsummaryrefslogtreecommitdiff
path: root/mesonbuild/interpreterbase.py
diff options
context:
space:
mode:
authorDylan Baker <dylan@pnwbakers.com>2021-06-01 15:48:23 -0700
committerDylan Baker <dylan@pnwbakers.com>2021-06-04 20:10:05 -0700
commitb107171307505e1493f76b53ace7db1ac070e819 (patch)
treedf6053ee1233a2439e21b4759dbbdf59d476921d /mesonbuild/interpreterbase.py
parent8890a624997a9cf56ead08bda03e9b46803986ad (diff)
downloadmeson-b107171307505e1493f76b53ace7db1ac070e819.zip
meson-b107171307505e1493f76b53ace7db1ac070e819.tar.gz
meson-b107171307505e1493f76b53ace7db1ac070e819.tar.bz2
interpreterbase: Allow safely using mutable default values with typed_kwargs
It's really inconvenient to want a thing that is always a list, but not be able to provide a default value of a list because of mutation. To that end the typed_kwargs method now makes a shallow copy of the default when using a `ContainerTypeInfo` as the type. This mean that using a default of `[]` is perfectly safe.
Diffstat (limited to 'mesonbuild/interpreterbase.py')
-rw-r--r--mesonbuild/interpreterbase.py15
1 files changed, 13 insertions, 2 deletions
diff --git a/mesonbuild/interpreterbase.py b/mesonbuild/interpreterbase.py
index 750101e..c887115 100644
--- a/mesonbuild/interpreterbase.py
+++ b/mesonbuild/interpreterbase.py
@@ -419,7 +419,9 @@ class KwargInfo(T.Generic[_T]):
:param listify: If true, then the argument will be listified before being
checked. This is useful for cases where the Meson DSL allows a scalar or
a container, but internally we only want to work with containers
- :param default: A default value to use if this isn't set. defaults to None
+ :param default: A default value to use if this isn't set. defaults to None,
+ this may be safely set to a mutable type, as long as that type does not
+ itself contain mutable types, typed_kwargs will copy the default
:param since: Meson version in which this argument has been added. defaults to None
:param deprecated: Meson version in which this argument has been deprecated. defaults to None
"""
@@ -444,6 +446,9 @@ def typed_kwargs(name: str, *types: KwargInfo) -> T.Callable[..., T.Any]:
information. For non-required values it sets the value to a default, which
means the value will always be provided.
+ If type tyhpe is a :class:ContainerTypeInfo, then the default value will be
+ passed as an argument to the container initializer, making a shallow copy
+
:param name: the name of the function, including the object it's attached ot
(if applicable)
:param *types: KwargInfo entries for each keyword argument.
@@ -491,7 +496,13 @@ def typed_kwargs(name: str, *types: KwargInfo) -> T.Callable[..., T.Any]:
else:
# set the value to the default, this ensuring all kwargs are present
# This both simplifies the typing checking and the usage
- kwargs[info.name] = info.default
+ # Create a shallow copy of the container (and do a type
+ # conversion if necessary). This allows mutable types to
+ # be used safely as default values
+ if isinstance(info.types, ContainerTypeInfo):
+ kwargs[info.name] = info.types.container(info.default)
+ else:
+ kwargs[info.name] = info.default
return f(*wrapped_args, **wrapped_kwargs)
return T.cast(TV_func, wrapper)