Robot Framework
argumentvalidator.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 robot.errors import DataError
17 from robot.utils import plural_or_not, seq2str
18 from robot.variables import is_dict_variable, is_list_variable
19 
20 
22 
23 
24  def __init__(self, argspec):
25  self._argspec_argspec = argspec
26 
27  def validate(self, positional, named, dryrun=False):
28  named = set(name for name, value in named)
29  if dryrun and (any(is_list_variable(arg) for arg in positional) or
30  any(is_dict_variable(arg) for arg in named)):
31  return
32  self._validate_no_multiple_values_validate_no_multiple_values(positional, named, self._argspec_argspec)
33  self._validate_no_positional_only_as_named_validate_no_positional_only_as_named(named, self._argspec_argspec)
34  self._validate_positional_limits_validate_positional_limits(positional, named, self._argspec_argspec)
35  self._validate_no_mandatory_missing_validate_no_mandatory_missing(positional, named, self._argspec_argspec)
36  self._validate_no_named_only_missing_validate_no_named_only_missing(named, self._argspec_argspec)
37  self._validate_no_extra_named_validate_no_extra_named(named, self._argspec_argspec)
38 
39  def _validate_no_multiple_values(self, positional, named, spec):
40  for name in spec.positional[:len(positional)]:
41  if name in named and name not in spec.positional_only:
42  self._raise_error_raise_error("got multiple values for argument '%s'" % name)
43 
44  def _raise_error(self, message):
45  raise DataError("%s '%s' %s." % (self._argspec_argspec.type.capitalize(),
46  self._argspec_argspec.name, message))
47 
48  def _validate_no_positional_only_as_named(self, named, spec):
49  if not spec.var_named:
50  for name in named:
51  if name in spec.positional_only:
52  self._raise_error_raise_error("does not accept argument '%s' as named "
53  "argument" % name)
54 
55  def _validate_positional_limits(self, positional, named, spec):
56  count = len(positional) + self._named_positionals_named_positionals(named, spec)
57  if not spec.minargs <= count <= spec.maxargs:
58  self._raise_wrong_count_raise_wrong_count(count, spec)
59 
60  def _named_positionals(self, named, spec):
61  return sum(1 for n in named if n in spec.positional_or_named)
62 
63  def _raise_wrong_count(self, count, spec):
64  minend = plural_or_not(spec.minargs)
65  if spec.minargs == spec.maxargs:
66  expected = '%d argument%s' % (spec.minargs, minend)
67  elif not spec.var_positional:
68  expected = '%d to %d arguments' % (spec.minargs, spec.maxargs)
69  else:
70  expected = 'at least %d argument%s' % (spec.minargs, minend)
71  if spec.var_named or spec.named_only:
72  expected = expected.replace('argument', 'non-named argument')
73  self._raise_error_raise_error("expected %s, got %d" % (expected, count))
74 
75  def _validate_no_mandatory_missing(self, positional, named, spec):
76  for name in spec.positional[len(positional):]:
77  if name not in spec.defaults and name not in named:
78  self._raise_error_raise_error("missing value for argument '%s'" % name)
79 
80  def _validate_no_named_only_missing(self, named, spec):
81  defined = set(named) | set(spec.defaults)
82  missing = [arg for arg in spec.named_only if arg not in defined]
83  if missing:
84  self._raise_error_raise_error("missing named-only argument%s %s"
85  % (plural_or_not(missing), seq2str(sorted(missing))))
86 
87  def _validate_no_extra_named(self, named, spec):
88  if not spec.var_named:
89  extra = set(named) - set(spec.positional_or_named) - set(spec.named_only)
90  if extra:
91  self._raise_error_raise_error("got unexpected named argument%s %s"
92  % (plural_or_not(extra), seq2str(sorted(extra))))
def _validate_positional_limits(self, positional, named, spec)
def _validate_no_multiple_values(self, positional, named, spec)
def validate(self, positional, named, dryrun=False)
def __init__(self, argspec)
:type argspec: :py:class:robot.running.arguments.ArgumentSpec
def _validate_no_mandatory_missing(self, positional, named, spec)
def seq2str(sequence, quote="'", sep=', ', lastsep=' and ')
Returns sequence in format ‘'item 1’, 'item 2' and 'item 3'`.
Definition: misc.py:79
def plural_or_not(item)
Definition: misc.py:73
def is_list_variable(string)
Definition: search.py:42
def is_dict_variable(string)
Definition: search.py:46