in metaflow/util.py [0:0]
def dict_to_cli_options(params):
# Prevent circular imports
from .user_configs.config_options import ConfigInput
for k, v in params.items():
# Omit boolean options set to false or None, but preserve options with an empty
# string argument.
if v is not False and v is not None:
# we need special handling for 'with' since it is a reserved
# keyword in Python, so we call it 'decospecs' in click args
if k == "decospecs":
k = "with"
if k in ("config", "config_value"):
# Special handling here since we gather them all in one option but actually
# need to send them one at a time using --config-value <name> kv.<name>
# Note it can be either config or config_value depending
# on click processing order.
for config_name in v.keys():
yield "--config-value"
yield to_unicode(config_name)
yield to_unicode(ConfigInput.make_key_name(config_name))
continue
if k == "local_config_file":
# Skip this value -- it should only be used locally and never when
# forming another command line
continue
k = k.replace("_", "-")
v = v if isinstance(v, (list, tuple, set)) else [v]
for value in v:
yield "--%s" % k
if not isinstance(value, bool):
value = to_unicode(value)
# Of the value starts with $, assume the caller wants shell variable
# expansion to happen, so we pass it as is.
# NOTE: We strip '\' to allow for various storages to use escaped
# shell variables as well.
if value.lstrip("\\").startswith("$"):
yield value
else:
# Otherwise, assume it is a literal value and quote it safely
yield _quote(value)