Robot Framework Integrated Development Environment (RIDE)
argumentresolver.py
Go to the documentation of this file.
1 # Copyright 2008-2015 Nokia Networks
2 # Copyright 2016- Robot Framework Foundation
3 #
4 # Licensed under the Apache License, Version 2.0 (the "License");
5 # you may not use this file except in compliance with the License.
6 # You may obtain a copy of the License at
7 #
8 # http://www.apache.org/licenses/LICENSE-2.0
9 #
10 # Unless required by applicable law or agreed to in writing, software
11 # distributed under the License is distributed on an "AS IS" BASIS,
12 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 # See the License for the specific language governing permissions and
14 # limitations under the License.
15 
16 from robotide.lib.robot.errors import DataError
17 from robotide.lib.robot.utils import is_string, is_dict_like, split_from_equals
18 from robotide.lib.robot.variables import VariableSplitter
19 
20 from .argumentvalidator import ArgumentValidator
21 
22 
24 
25  def __init__(self, argspec, resolve_named=True,
26  resolve_variables_until=None, dict_to_kwargs=False):
27  self._named_resolver_named_resolver = NamedArgumentResolver(argspec) \
28  if resolve_named else NullNamedArgumentResolver()
29  self._variable_replacer_variable_replacer = VariableReplacer(resolve_variables_until)
30  self._dict_to_kwargs_dict_to_kwargs = DictToKwargs(argspec, dict_to_kwargs)
31  self._argument_validator_argument_validator = ArgumentValidator(argspec)
32 
33  def resolve(self, arguments, variables=None):
34  positional, named = self._named_resolver_named_resolver.resolve(arguments, variables)
35  positional, named = self._variable_replacer_variable_replacer.replace(positional, named,
36  variables)
37  positional, named = self._dict_to_kwargs_dict_to_kwargs.handle(positional, named)
38  self._argument_validator_argument_validator.validate(positional, named,
39  dryrun=variables is None)
40  return positional, named
41 
42 
44 
45  def __init__(self, argspec):
46  self._argspec_argspec = argspec
47 
48  def resolve(self, arguments, variables=None):
49  positional = []
50  named = []
51  for arg in arguments:
52  if self._is_dict_var_is_dict_var(arg):
53  named.append(arg)
54  elif self._is_named_is_named(arg, named, variables):
55  named.append(split_from_equals(arg))
56  elif named:
57  self._raise_positional_after_named_raise_positional_after_named()
58  else:
59  positional.append(arg)
60  return positional, named
61 
62  def _is_dict_var(self, arg):
63  return (is_string(arg) and arg[:2] == '&{' and arg[-1] == '}' and
64  VariableSplitter(arg).is_dict_variable())
65 
66  def _is_named(self, arg, previous_named, variables=None):
67  name, value = split_from_equals(arg)
68  if value is None:
69  return False
70  if variables:
71  name = variables.replace_scalar(name)
72  argspec = self._argspec_argspec
73  if previous_named or name in argspec.kwonlyargs or argspec.kwargs:
74  return True
75  return argspec.supports_named and name in argspec.positional
76 
78  raise DataError("%s '%s' got positional argument after named arguments."
79  % (self._argspec_argspec.type, self._argspec_argspec.name))
80 
81 
83 
84  def resolve(self, arguments, variables=None):
85  return arguments, {}
86 
87 
88 class DictToKwargs():
89 
90  def __init__(self, argspec, enabled=False):
91  self._maxargs_maxargs = argspec.maxargs
92  self._enabled_enabled = enabled and bool(argspec.kwargs)
93 
94  def handle(self, positional, named):
95  if self._enabled_enabled and self._extra_arg_has_kwargs_extra_arg_has_kwargs(positional, named):
96  named = positional.pop().items()
97  return positional, named
98 
99  def _extra_arg_has_kwargs(self, positional, named):
100  if named or len(positional) != self._maxargs_maxargs + 1:
101  return False
102  return is_dict_like(positional[-1])
103 
104 
106 
107  def __init__(self, resolve_until=None):
108  self._resolve_until_resolve_until = resolve_until
109 
110  def replace(self, positional, named, variables=None):
111  # `variables` is None in dry-run mode and when using Libdoc.
112  if variables:
113  positional = variables.replace_list(positional, self._resolve_until_resolve_until)
114  named = list(self._replace_named_replace_named(named, variables.replace_scalar))
115  else:
116  positional = list(positional)
117  named = [item for item in named if isinstance(item, tuple)]
118  return positional, named
119 
120  def _replace_named(self, named, replace_scalar):
121  for item in named:
122  for name, value in self._get_replaced_named_get_replaced_named(item, replace_scalar):
123  if not is_string(name):
124  raise DataError('Argument names must be strings.')
125  yield name, value
126 
127  def _get_replaced_named(self, item, replace_scalar):
128  if not isinstance(item, tuple):
129  return replace_scalar(item).items()
130  name, value = item
131  return [(replace_scalar(name), replace_scalar(value))]
Used when variable does not exist.
Definition: errors.py:67
def __init__(self, argspec, resolve_named=True, resolve_variables_until=None, dict_to_kwargs=False)