Skip to content

Commit 2ccc4c0

Browse files
committed
Support for keyword only arguments
1 parent 7506771 commit 2ccc4c0

File tree

3 files changed

+29
-4
lines changed

3 files changed

+29
-4
lines changed

atest/DynamicTypesAnnotationsLibrary.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,3 +73,7 @@ def keyword_robot_types_and_bool_defaults(self, arg1, arg2=False):
7373
@keyword
7474
def keyword_exception_annotations(self, arg: 'NotHere'):
7575
return arg
76+
77+
@keyword
78+
def keyword_only_arguments(self, *varargs, some='value'):
79+
return f'{some}: {type(some)}, {varargs}: {type(varargs)}'

src/robotlibcore.py

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ def get_keyword_arguments(self, name):
101101
kw_method = self.__get_keyword(name)
102102
if kw_method is None:
103103
return None
104-
args, defaults, varargs, kwargs = self.__get_arg_spec(kw_method)
104+
args, defaults, varargs, kwargs, kwonlydefaults = self.__get_arg_spec(kw_method)
105105
if robot_version >= '3.2':
106106
args += self.__new_default_spec(defaults)
107107
else:
@@ -110,6 +110,9 @@ def get_keyword_arguments(self, name):
110110
args.append('*%s' % varargs)
111111
if kwargs:
112112
args.append('**%s' % kwargs)
113+
if kwonlydefaults:
114+
for argument, default_value in kwonlydefaults.items():
115+
args.append((argument, default_value))
113116
return args
114117

115118
def __new_default_spec(self, defaults):
@@ -122,15 +125,17 @@ def __get_arg_spec(self, kw):
122125
if PY2:
123126
spec = inspect.getargspec(kw)
124127
keywords = spec.keywords
128+
kwonlydefaults = {}
125129
else:
126130
spec = inspect.getfullargspec(kw)
127131
keywords = spec.varkw
132+
kwonlydefaults = spec.kwonlydefaults
128133
args = spec.args[1:] if inspect.ismethod(kw) else spec.args # drop self
129134
defaults = spec.defaults or ()
130135
nargs = len(args) - len(defaults)
131136
mandatory = args[:nargs]
132137
defaults = zip(args[nargs:], defaults)
133-
return mandatory, defaults, spec.varargs, keywords
138+
return mandatory, defaults, spec.varargs, keywords, kwonlydefaults
134139

135140
def get_keyword_tags(self, name):
136141
self.__get_keyword_tags_supported = True
@@ -181,7 +186,7 @@ def __get_typing_hints(self, method):
181186
return hints
182187

183188
def __join_defaults_with_types(self, method, types):
184-
_, defaults, _, _ = self.__get_arg_spec(method)
189+
_, defaults, _, _, _ = self.__get_arg_spec(method)
185190
for name, value in defaults:
186191
if name not in types and isinstance(value, (bool, type(None))):
187192
types[name] = type(value)

utest/test_robotlibcore.py

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,11 @@
33
import pytest
44
from robot import __version__ as robot__version
55

6-
from robotlibcore import HybridCore
6+
from robotlibcore import HybridCore, PY2
77
from HybridLibrary import HybridLibrary
88
from DynamicLibrary import DynamicLibrary
9+
if not PY2:
10+
from DynamicTypesAnnotationsLibrary import DynamicTypesAnnotationsLibrary
911

1012

1113
def test_keyword_names():
@@ -124,6 +126,20 @@ def test_get_keyword_arguments_rf32():
124126
assert args('__foobar__') is None
125127

126128

129+
@pytest.mark.skipif(PY2, reason='Only for Python 3')
130+
@pytest.mark.skipif(robot__version < '3.2', reason='For RF 3.2 or greater')
131+
def test_keyword_only_arguments_for_get_keyword_arguments_rf32():
132+
args = DynamicTypesAnnotationsLibrary(1).get_keyword_arguments
133+
assert args('keyword_only_arguments') == ['*varargs', ('some', 'value')]
134+
135+
136+
@pytest.mark.skipif(PY2, reason='Only for Python 3')
137+
@pytest.mark.skipif(robot__version > '3.2', reason='For RF 3.1')
138+
def test_keyword_only_arguments_for_get_keyword_arguments_rf31():
139+
args = DynamicTypesAnnotationsLibrary(1).get_keyword_arguments
140+
assert args('keyword_only_arguments') == ['*varargs', 'some=value']
141+
142+
127143
def test_get_keyword_documentation():
128144
doc = DynamicLibrary().get_keyword_documentation
129145
assert doc('function') == ''

0 commit comments

Comments
 (0)