Robot Framework
argumentconverter.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.variables import contains_variable
17 
18 from .typeconverters import TypeConverter
19 
20 
22 
23 
24  def __init__(self, argspec, converters, dry_run=False, languages=None):
25  self._argspec_argspec = argspec
26  self._converters_converters = converters
27  self._dry_run_dry_run = dry_run
28  self._languages_languages = languages
29 
30  def convert(self, positional, named):
31  return self._convert_positional_convert_positional(positional), self._convert_named_convert_named(named)
32 
33  def _convert_positional(self, positional):
34  names = self._argspec_argspec.positional
35  converted = [self._convert_convert(name, value)
36  for name, value in zip(names, positional)]
37  if self._argspec_argspec.var_positional:
38  converted.extend(self._convert_convert(self._argspec_argspec.var_positional, value)
39  for value in positional[len(names):])
40  return converted
41 
42  def _convert_named(self, named):
43  names = set(self._argspec_argspec.positional) | set(self._argspec_argspec.named_only)
44  var_named = self._argspec_argspec.var_named
45  return [(name, self._convert_convert(name if name in names else var_named, value))
46  for name, value in named]
47 
48  def _convert(self, name, value):
49  spec = self._argspec_argspec
50  if (spec.types is None
51  or self._dry_run_dry_run and contains_variable(value, identifiers='$@&%')):
52  return value
53  conversion_error = None
54  # Don't convert None if argument has None as a default value.
55  # Python < 3.11 adds None to type hints automatically when using None as
56  # a default value which preserves None automatically. This code keeps
57  # the same behavior also with newer Python versions.
58  if value is None and name in spec.defaults and spec.defaults[name] is None:
59  return value
60  if name in spec.types:
61  converter = TypeConverter.converter_for(spec.types[name], self._converters_converters,
62  self._languages_languages)
63  if converter:
64  try:
65  return converter.convert(name, value)
66  except ValueError as err:
67  conversion_error = err
68  if name in spec.defaults:
69  converter = TypeConverter.converter_for(type(spec.defaults[name]),
70  languages=self._languages_languages)
71  if converter:
72  try:
73  return converter.convert(name, value, explicit_type=False,
74  strict=bool(conversion_error))
75  except ValueError as err:
76  conversion_error = conversion_error or err
77  if conversion_error:
78  raise conversion_error
79  return value
def __init__(self, argspec, converters, dry_run=False, languages=None)
:type argspec: :py:class:robot.running.arguments.ArgumentSpec
def contains_variable(string, identifiers='$@&')
Definition: search.py:28