Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
def _ParseFn(args):
"""Parses the list of `args` into (varargs, kwargs), remaining_args."""
kwargs, remaining_kwargs, remaining_args = _ParseKeywordArgs(args, fn_spec)
# Note: _ParseArgs modifies kwargs.
parsed_args, kwargs, remaining_args, capacity = _ParseArgs(
fn_spec.args, fn_spec.defaults, num_required_args, kwargs,
remaining_args, metadata)
if fn_spec.varargs or fn_spec.varkw:
# If we're allowed *varargs or **kwargs, there's always capacity.
capacity = True
extra_kw = set(kwargs) - set(fn_spec.kwonlyargs)
if fn_spec.varkw is None and extra_kw:
raise FireError('Unexpected kwargs present:', extra_kw)
missing_kwonly = set(required_kwonly) - set(kwargs)
if missing_kwonly:
raise FireError('Missing required flags:', missing_kwonly)
# If we accept *varargs, then use all remaining arguments for *varargs.
if fn_spec.varargs is not None:
varargs, remaining_args = remaining_args, []
else:
varargs = []
for index, value in enumerate(varargs):
varargs[index] = _ParseValue(value, None, None, metadata)
varargs = parsed_args + varargs
remaining_args += remaining_kwargs
except FireError as error:
candidate_errors.append((error, initial_args))
if handled and last_component is initial_component:
# If the initial component is a class, keep an instance for use with -i.
instance = component
if not handled and is_sequence and remaining_args:
# The component is a tuple or list; we'll try to access a member.
arg = remaining_args[0]
try:
index = int(arg)
component = component[index]
handled = True
except (ValueError, IndexError):
error = FireError(
'Unable to index into component with argument:', arg)
candidate_errors.append((error, initial_args))
if handled:
remaining_args = remaining_args[1:]
filename = None
lineno = None
component_trace.AddAccessedProperty(
component, index, [arg], filename, lineno)
if not handled and is_map and remaining_args:
# The component is a dict or other key-value map; try to access a member.
target = remaining_args[0]
# Treat namedtuples as dicts when handling them as a map.
if inspectutils.IsNamedTuple(component):
is_bool_syntax = (not contains_equals and
(index + 1 == len(args) or _IsFlag(args[index + 1])))
# Determine the keyword.
keyword = '' # Indicates no valid keyword has been found yet.
if (key in fn_args
or (is_bool_syntax and key.startswith('no') and key[2:] in fn_args)
or fn_keywords):
keyword = key
elif len(key) == 1:
# This may be a shortcut flag.
matching_fn_args = [arg for arg in fn_args if arg[0] == key]
if len(matching_fn_args) == 1:
keyword = matching_fn_args[0]
elif len(matching_fn_args) > 1:
raise FireError("The argument '{}' is ambiguous as it could "
"refer to any of the following arguments: {}".format(
argument, matching_fn_args))
# Determine the value.
if not keyword:
got_argument = False
elif contains_equals:
# Already got the value above.
got_argument = True
elif is_bool_syntax:
# There's no next arg or the next arg is a Flag, so we consider this
# flag to be a boolean.
got_argument = True
if keyword in fn_args:
value = 'True'
elif keyword.startswith('no'):
# a key as another type.
# TODO(dbieber): Consider alternatives for accessing non-string keys.
for key, value in component_dict.items():
if target == str(key):
component = value
handled = True
break
if handled:
remaining_args = remaining_args[1:]
filename = None
lineno = None
component_trace.AddAccessedProperty(
component, target, [target], filename, lineno)
else:
error = FireError('Cannot find key:', target)
candidate_errors.append((error, initial_args))
if not handled and remaining_args:
# Object handler. We'll try to access a member of the component.
try:
target = remaining_args[0]
component, consumed_args, remaining_args = _GetMember(
component, remaining_args)
handled = True
filename, lineno = inspectutils.GetFileAndLine(component)
component_trace.AddAccessedProperty(
component, target, consumed_args, filename, lineno)
or inspect.isroutine(last_component)):
remaining_args = saved_args
component_trace.AddSeparator()
elif component is not last_component:
remaining_args = [separator] + saved_args
else:
# It was an unnecessary separator.
remaining_args = saved_args
if component is last_component and remaining_args == initial_args:
# We're making no progress.
break
if remaining_args:
component_trace.AddError(
FireError('Could not consume arguments:', remaining_args),
initial_args)
return component_trace
if show_completion is not None:
if name is None:
raise ValueError('Cannot make completion script without command name')
script = CompletionScript(name, initial_component, shell=show_completion)
component_trace.AddCompletionScript(script)
if interactive:
variables = context.copy()
if name is not None:
variables[name] = initial_component
variables['component'] = initial_component
variables['result'] = component
# Note: _ParseArgs modifies kwargs.
parsed_args, kwargs, remaining_args, capacity = _ParseArgs(
fn_spec.args, fn_spec.defaults, num_required_args, kwargs,
remaining_args, metadata)
if fn_spec.varargs or fn_spec.varkw:
# If we're allowed *varargs or **kwargs, there's always capacity.
capacity = True
extra_kw = set(kwargs) - set(fn_spec.kwonlyargs)
if fn_spec.varkw is None and extra_kw:
raise FireError('Unexpected kwargs present:', extra_kw)
missing_kwonly = set(required_kwonly) - set(kwargs)
if missing_kwonly:
raise FireError('Missing required flags:', missing_kwonly)
# If we accept *varargs, then use all remaining arguments for *varargs.
if fn_spec.varargs is not None:
varargs, remaining_args = remaining_args, []
else:
varargs = []
for index, value in enumerate(varargs):
varargs[index] = _ParseValue(value, None, None, metadata)
varargs = parsed_args + varargs
remaining_args += remaining_kwargs
consumed_args = args[:len(args) - len(remaining_args)]
return (varargs, kwargs), consumed_args, remaining_args, capacity
remaining_args: The remaining args that haven't been consumed yet.
Raises:
FireError: If we cannot consume an argument to get a member.
"""
members = dict(inspect.getmembers(component))
arg = args[0]
arg_names = [
arg,
arg.replace('-', '_'), # treat '-' as '_'.
]
for arg_name in arg_names:
if arg_name in members:
return members[arg_name], [arg], args[1:]
raise FireError('Could not consume arg:', arg)