4 new revisions:
Revision: 387e1cf4dc70
Branch: default
Author: Pekka Klärck
Date: Thu Nov 21 09:41:12 2013 UTC
Log: atests: Combined dynamic library invalid argpspec tests and
cleaned th...
http://code.google.com/p/robotframework/source/detail?r=387e1cf4dc70
Revision: 3d9d713eb6b1
Branch: default
Author: Pekka Klärck
Date: Thu Nov 21 10:05:15 2013 UTC
Log: Cleaned up dynamic library atests...
http://code.google.com/p/robotframework/source/detail?r=3d9d713eb6b1
Revision: 54ed6c9c33cf
Branch: default
Author: Pekka Klärck
Date: Thu Nov 21 12:26:42 2013 UTC
Log: Dynamic libs: return '*varargs' instead of '*unknown' when no arg
spec...
http://code.google.com/p/robotframework/source/detail?r=54ed6c9c33cf
Revision: e3ae9ca64a98
Branch: default
Author: Pekka Klärck
Date: Thu Nov 21 12:51:47 2013 UTC
Log: Dynamic libs: Refactored detecting does run_keyword support
**kwargs...
http://code.google.com/p/robotframework/source/detail?r=e3ae9ca64a98
==============================================================================
Revision: 387e1cf4dc70
Branch: default
Author: Pekka Klärck
Date: Thu Nov 21 09:41:12 2013 UTC
Log: atests: Combined dynamic library invalid argpspec tests and
cleaned them up in general.
Update issue 1500
Combined invalid argspec tests.
http://code.google.com/p/robotframework/source/detail?r=387e1cf4dc70
Added:
/atest/testdata/test_libraries/dynamic_libraries/InvalidArgSpecs.py
Deleted:
/atest/robot/test_libraries/dynamic_kwargs_support_with_invalid_argspec.txt
/atest/testdata/test_libraries/dynamic_kwargs_support_with_invalid_argspec.txt
/atest/testdata/test_libraries/dynamic_libraries/DynamicLibrary.py
/atest/testdata/test_libraries/dynamic_libraries/DynamicLibraryWithKwargsSupport.py
Modified:
/atest/robot/test_libraries/dynamic_libraries_with_invalid_argspec.txt
/atest/testdata/test_libraries/dynamic_libraries_with_invalid_argspec.txt
=======================================
--- /dev/null
+++ /atest/testdata/test_libraries/dynamic_libraries/InvalidArgSpecs.py Thu
Nov 21 09:41:12 2013 UTC
@@ -0,0 +1,20 @@
+KEYWORDS = [('argspec with other than strings', [1, 2]),
+ ('named args before positional', ['a=1', 'b']),
+ ('varargs before positional args', ['*varargs', 'a']),
+ ('varargs before named args', ['*varargs', 'a=1']),
+ ('kwargs before positional args', ['**kwargs', 'a']),
+ ('kwargs before named args', ['**kwargs', 'a=1']),
+ ('kwargs before varargs', ['**kwargs', '*varargs']),
+ ('valid argspec', ['a'])]
+
+
+class InvalidArgSpecs(object):
+
+ def get_keyword_names(self):
+ return [name for name, _ in KEYWORDS]
+
+ def run_keyword(self, name, args, kwargs):
+ return ''.join(args + tuple(kwargs)).upper()
+
+ def get_keyword_arguments(self, name):
+ return dict(KEYWORDS)[name]
=======================================
---
/atest/robot/test_libraries/dynamic_kwargs_support_with_invalid_argspec.txt
Wed Nov 20 17:05:12 2013 UTC
+++ /dev/null
@@ -1,28 +0,0 @@
-# TODO: Move these tests to dynamic_libraries_with_invalid_argspec.txt
-
-*** Settings ***
-Suite Setup Run Tests ${EMPTY}
test_libraries/dynamic_kwargs_support_with_invalid_argspec.txt
-Force Tags regression jybot pybot
-Resource atest_resource.txt
-
-*** Test Cases ***
-
-Argspec has kwargs before positional arguments
- Error message should be correct 1 kwargs before positional args
- ... Only last argument can be kwargs.
-
-Argspec has kwargs before named arguments
- Error message should be correct 0 kwargs before named args
- ... Only last argument can be kwargs.
-
-Argspec has kwargs before varargs
- Error message should be correct 2 kwargs before varargs
- ... Only last argument can be kwargs.
-
-
-*** Keywords ***
-
-Error message should be correct
- [Arguments] ${index} ${kw} ${msg}
- Check Test Case ${TESTNAME}
- Check Log Message ${ERRORS[${index}]} Adding keyword '${kw}' to
library 'DynamicLibraryWithKwargsSupport' failed: ${msg} WARN
=======================================
---
/atest/testdata/test_libraries/dynamic_kwargs_support_with_invalid_argspec.txt
Wed Nov 20 17:05:12 2013 UTC
+++ /dev/null
@@ -1,16 +0,0 @@
-*** Settings ***
-Library dynamic_libraries/DynamicLibraryWithKwargsSupport.py
-
-*** Test Cases ***
-
-Argspec has kwargs before positional arguments
- [Documentation] FAIL No keyword with name 'Kwargs Before Positional
Args' found.
- Kwargs Before Positional Args
-
-Argspec has kwargs before named arguments
- [Documentation] FAIL No keyword with name 'Kwargs Before Named
Args' found.
- Kwargs Before Named Args
-
-Argspec has kwargs before varargs
- [Documentation] FAIL No keyword with name 'Kwargs Before Varargs'
found.
- Kwargs Before Varargs
=======================================
--- /atest/testdata/test_libraries/dynamic_libraries/DynamicLibrary.py Wed
Nov 20 17:05:12 2013 UTC
+++ /dev/null
@@ -1,20 +0,0 @@
-# TODO: Move code to run_keyword
-
-KEYWORDS = {
- 'argspec with other than strings': (lambda a, *x: (a, x), [1, 2]),
- 'varargs before positional args': (lambda a, *x: (a, x),
['*varargs', 'a']),
- 'varargs before named args': (lambda a=1, *x: (a, x),
['*varargs', 'a=1']),
- 'named args before positional': (lambda a, b: (a, b), ['a=1', 'b']),
- 'method': (lambda a: a, ['a'])
-}
-
-class DynamicLibrary(object):
-
- def get_keyword_names(self):
- return sorted(KEYWORDS)
-
- def run_keyword(self, kw_name, args):
- KEYWORDS[kw_name][0](*args)
-
- def get_keyword_arguments(self, kw_name):
- return KEYWORDS[kw_name][1]
=======================================
---
/atest/testdata/test_libraries/dynamic_libraries/DynamicLibraryWithKwargsSupport.py
Wed Nov 20 17:05:12 2013 UTC
+++ /dev/null
@@ -1,18 +0,0 @@
-# TODO: Rename to DynamicLibraryWithInvalidArgSpec
-# Also, run_keyword can just pass...
-KEYWORDS = {
- 'kwargs before positional args': (lambda a, *x: (a, x),
['**kwargs', 'a']),
- 'kwargs before named args': (lambda a=1, *x: (a, x),
['**kwargs', 'a=1']),
- 'kwargs before varargs': (lambda a=1, *x: (a, x),
['**kwargs', '*varargs']),
-}
-
-class DynamicLibraryWithKwargsSupport(object):
-
- def get_keyword_names(self):
- return sorted(KEYWORDS)
-
- def run_keyword(self, kw_name, args, kwargs):
- return KEYWORDS[kw_name][0](*args, **kwargs)
-
- def get_keyword_arguments(self, kw_name):
- return KEYWORDS[kw_name][1]
=======================================
--- /atest/robot/test_libraries/dynamic_libraries_with_invalid_argspec.txt
Wed Aug 7 21:31:57 2013 UTC
+++ /atest/robot/test_libraries/dynamic_libraries_with_invalid_argspec.txt
Thu Nov 21 09:41:12 2013 UTC
@@ -4,27 +4,39 @@
Resource atest_resource.txt
*** Test Cases ***
-
Argspec consists of something else than strings
Error message should be correct 0 argspec with other than strings
... Calling dynamic method 'get_keyword_arguments' failed: Return
value must be list of strings.
+Argspec has named arguments before positional
+ Error message should be correct 1 named args before positional
+ ... Non-default argument after default arguments.
+
Argspec has varargs before positional arguments
- Error message should be correct 3 varargs before positional args
+ Error message should be correct 2 varargs before positional args
... Positional argument after varargs.
Argspec has varargs before named arguments
- Error message should be correct 2 varargs before named args
+ Error message should be correct 3 varargs before named args
... Positional argument after varargs.
-Argspec has named arguments before positional
- Error message should be correct 1 named args before positional
- ... Non-default argument after default arguments.
+Argspec has kwargs before positional arguments
+ Error message should be correct 4 kwargs before positional args
+ ... Only last argument can be kwargs.
+Argspec has kwargs before named arguments
+ Error message should be correct 5 kwargs before named args
+ ... Only last argument can be kwargs.
+
+Argspec has kwargs before varargs
+ Error message should be correct 6 kwargs before varargs
+ ... Only last argument can be kwargs.
+
+Keywords with valid arg spec can be used
+ Check Test Case
*** Keywords ***
-
Error message should be correct
[Arguments] ${index} ${kw} ${msg}
Check Test Case ${TESTNAME}
- Check Log Message ${ERRORS[${index}]} Adding keyword '${kw}' to
library 'DynamicLibrary' failed: ${msg} WARN
+ Check Log Message ${ERRORS[${index}]} Adding keyword '${kw}' to
library 'InvalidArgSpecs' failed: ${msg} WARN
=======================================
---
/atest/testdata/test_libraries/dynamic_libraries_with_invalid_argspec.txt
Thu Apr 25 11:35:28 2013 UTC
+++
/atest/testdata/test_libraries/dynamic_libraries_with_invalid_argspec.txt
Thu Nov 21 09:41:12 2013 UTC
@@ -1,5 +1,5 @@
*** Settings ***
-Library ${CURDIR}/dynamic_libraries/DynamicLibrary.py
+Library dynamic_libraries/InvalidArgSpecs.py
*** Test Cases ***
@@ -7,6 +7,10 @@
[Documentation] FAIL No keyword with name 'Argspec With Other Than
Strings' found.
Argspec With Other Than Strings
+Argspec has named arguments before positional
+ [Documentation] FAIL No keyword with name 'Named Args Before
Positional' found.
+ Named Args Before Positional
+
Argspec has varargs before positional arguments
[Documentation] FAIL No keyword with name 'Varargs Before
Positional Args' found.
Varargs Before Positional Args
@@ -15,6 +19,18 @@
[Documentation] FAIL No keyword with name 'Varargs Before Named
Args' found.
Varargs Before Named Args
-Argspec has named arguments before positional
- [Documentation] FAIL No keyword with name 'Named Args Before
Positional' found.
- Named Args Before Positional
+Argspec has kwargs before positional arguments
+ [Documentation] FAIL No keyword with name 'Kwargs Before Positional
Args' found.
+ Kwargs Before Positional Args
+
+Argspec has kwargs before named arguments
+ [Documentation] FAIL No keyword with name 'Kwargs Before Named
Args' found.
+ Kwargs Before Named Args
+
+Argspec has kwargs before varargs
+ [Documentation] FAIL No keyword with name 'Kwargs Before Varargs'
found.
+ Kwargs Before Varargs
+
+Keywords with valid arg spec can be used
+ ${ret} = Valid argspec Hello!
+ Should be equal ${ret} HELLO!
==============================================================================
Revision: 3d9d713eb6b1
Branch: default
Author: Pekka Klärck
Date: Thu Nov 21 10:05:15 2013 UTC
Log: Cleaned up dynamic library atests
Update issue 1500
Further test cleanup
http://code.google.com/p/robotframework/source/detail?r=3d9d713eb6b1
Deleted:
/atest/testdata/keywords/named_args/dynamic_library_impl.py
Modified:
/atest/testdata/keywords/named_args/DynamicLibrary.py
/atest/testdata/keywords/named_args/DynamicLibraryWithKwargsSupport.py
/atest/testdata/keywords/named_args/with_dynamic_keywords.txt
/atest/testdata/test_libraries/dynamic_libraries/DynamicLibraryWithKwargsSupportWithoutArgspec.py
/atest/testdata/test_libraries/dynamic_libraries/DynamicLibraryWithoutArgspec.py
=======================================
--- /atest/testdata/keywords/named_args/dynamic_library_impl.py Wed Nov 20
17:05:12 2013 UTC
+++ /dev/null
@@ -1,12 +0,0 @@
-from helper import pretty
-
-# TODO: This file is not really needed. Dynamic libs should do this
themselves.
-
-def var_args(*varargs, **kwargs):
- return pretty(*varargs, **kwargs)
-
-def return_argument(arg):
- return arg
-
-def return_arguments(*args):
- return args
=======================================
--- /atest/testdata/keywords/named_args/DynamicLibrary.py Wed Nov 20
17:05:12 2013 UTC
+++ /atest/testdata/keywords/named_args/DynamicLibrary.py Thu Nov 21
10:05:15 2013 UTC
@@ -1,20 +1,19 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
+from helper import pretty
-from dynamic_library_impl import var_args, return_argument,
return_arguments
-
KEYWORDS = {
- 'Escaped Default Value': (var_args,
['d1=${notvariable}', 'd2=\\\\', 'd3=\n', 'd4=\t']),
- 'Four Kw Args': (var_args,
['a=default', 'b=default', 'c=default', 'd=default']),
- 'Mandatory, Named And Varargs': (var_args,
['a', 'b=default', '*varargs']),
- 'Mandatory And Kwargs': (var_args, ['man1', 'man2', 'kwarg=KWARG
VALUE']),
- 'Mandatory And Named': (var_args, ['a', 'b=default']),
- 'Named Arguments With Varargs': (return_arguments,
['a=default', 'b=default', '*varargs']),
- 'One Kwarg Returned': (return_argument, ['kwarg=']),
- 'Two Kwargs': (var_args, ['first=', 'second=']),
- u'Nön äscii named args': (var_args, [u'nönäscii=', u'官话=']),
- 'three named': (var_args, ['a=a', 'b=b', 'c=c'])
+ 'Escaped Default Value':
['d1=${notvariable}', 'd2=\\\\', 'd3=\n', 'd4=\t'],
+ 'Four Kw Args': ['a=default', 'b=default', 'c=default', 'd=default'],
+ 'Mandatory, Named And Varargs': ['a', 'b=default', '*varargs'],
+ 'Mandatory And Kwargs': ['man1', 'man2', 'kwarg=KWARG VALUE'],
+ 'Mandatory And Named': ['a', 'b=default'],
+ 'Named Arguments With Varargs': ['a=default', 'b=default', '*varargs'],
+ 'One Kwarg Returned': ['kwarg='],
+ 'Two Kwargs': ['first=', 'second='],
+ u'Nön äscii named args': [u'nönäscii=', u'官话='],
+ 'three named': ['a=a', 'b=b', 'c=c']
}
@@ -27,7 +26,12 @@
return self.keywords.keys()
def run_keyword(self, kw_name, args):
- return self.keywords[kw_name][0](*args)
+ return self._pretty(*args)
+
+ def _pretty(self, *args, **kwargs):
+ if all(isinstance(a, basestring) for a in args):
+ return pretty(*args, **kwargs)
+ return args[0] if len(args) == 1 else args
def get_keyword_arguments(self, kw_name):
- return self.keywords[kw_name][1]
+ return self.keywords[kw_name]
=======================================
--- /atest/testdata/keywords/named_args/DynamicLibraryWithKwargsSupport.py
Wed Nov 20 17:05:12 2013 UTC
+++ /atest/testdata/keywords/named_args/DynamicLibraryWithKwargsSupport.py
Thu Nov 21 10:05:15 2013 UTC
@@ -1,9 +1,8 @@
-from dynamic_library_impl import var_args
from DynamicLibrary import DynamicLibrary
KEYWORDS = {
- 'Mandatory, Named And Kwargs': (var_args,
['a', 'b=default', '**kwargs']),
- 'Mandatory, Named, Varargs And Kwargs': (var_args,
['a', 'b=default', '*varargs', '**kwargs']),
+ 'Mandatory, Named And Kwargs': ['a', 'b=default', '**kwargs'],
+ 'Mandatory, Named, Varargs And Kwargs':
['a', 'b=default', '*varargs', '**kwargs'],
}
@@ -13,4 +12,4 @@
DynamicLibrary.__init__(self, **KEYWORDS)
def run_keyword(self, name, args, kwargs):
- return self.keywords[name][0](*args, **kwargs)
+ return self._pretty(*args, **kwargs)
=======================================
--- /atest/testdata/keywords/named_args/with_dynamic_keywords.txt Tue Sep
24 09:38:39 2013 UTC
+++ /atest/testdata/keywords/named_args/with_dynamic_keywords.txt Thu Nov
21 10:05:15 2013 UTC
@@ -45,16 +45,16 @@
Should Be Equal ${ret} \${notvariable}, \\\\, \n, \${nv}
Varargs without naming arguments works
- @{ret} = Named arguments with varargs foo bar dar
- Should be equal @{ret}[0] foo
- @{ret} = Named arguments with varargs foo bar=bar dar
- Should be equal @{ret}[1] bar=bar
- @{ret} = Named arguments with varargs foo b\=bar dar
- Should be equal @{ret}[1] b=bar
+ ${ret} = Named arguments with varargs foo bar dar
+ Should be equal ${ret} foo, bar, dar
+ ${ret} = Named arguments with varargs foo bar=bar dar
+ Should be equal ${ret} foo, bar=bar, dar
+ ${ret} = Named arguments with varargs foo b\=bar dar
+ Should be equal ${ret} foo, b=bar, dar
Naming without the varargs works
- @{ret} = Named arguments with varargs foo b=bar
- Should be equal @{ret}[1] bar
+ ${ret} = Named arguments with varargs foo b=bar
+ Should be equal ${ret} foo, bar
Varargs with naming does not work
[documentation] FAIL Keyword '${DynamicLibrary}.Named Arguments
With Varargs' got positional argument after named arguments.
=======================================
---
/atest/testdata/test_libraries/dynamic_libraries/DynamicLibraryWithKwargsSupportWithoutArgspec.py
Wed Nov 20 17:05:12 2013 UTC
+++
/atest/testdata/test_libraries/dynamic_libraries/DynamicLibraryWithKwargsSupportWithoutArgspec.py
Thu Nov 21 10:05:15 2013 UTC
@@ -1,23 +1,10 @@
-import sys
-import os
+from DynamicLibraryWithoutArgspec import DynamicLibraryWithoutArgspec
-# TODO: 1) Is sys.path.insert really needed?
-# TODO: 2) Should not update KEYWORDS without copying it first.
-# TODO: 3) See also DynamicLibraryWithoutArgspec
-sys.path.insert(0, os.path.dirname(__file__))
-from DynamicLibraryWithoutArgspec import (
- KEYWORDS, DynamicLibraryWithoutArgspec)
+class
DynamicLibraryWithKwargsSupportWithoutArgspec(DynamicLibraryWithoutArgspec):
+ def run_keyword(self, name, args, kwargs):
+ return getattr(self, name)(*args, **kwargs)
-def do_something_with_kwargs(a, b=2, c=3, **kwargs):
- print a, b, c, ' '.join('%s:%s' % (k, v) for k, v in kwargs.items())
-
-KEYWORDS.update({
- 'do_something_with_kwargs': do_something_with_kwargs,
-})
-
-class
DynamicLibraryWithKwargsSupportWithoutArgspec(DynamicLibraryWithoutArgspec):
-
- def run_keyword(self, kw_name, args, kwargs):
- return KEYWORDS[kw_name](*args, **kwargs)
+ def do_something_with_kwargs(self, a, b=2, c=3, **kwargs):
+ print a, b, c, ' '.join('%s:%s' % (k, v) for k, v in
kwargs.items())
=======================================
---
/atest/testdata/test_libraries/dynamic_libraries/DynamicLibraryWithoutArgspec.py
Wed Nov 20 17:05:12 2013 UTC
+++
/atest/testdata/test_libraries/dynamic_libraries/DynamicLibraryWithoutArgspec.py
Thu Nov 21 10:05:15 2013 UTC
@@ -1,22 +1,16 @@
-# TODO: Move actual code to run_keyword
-def do_something(x):
- print x
+class DynamicLibraryWithoutArgspec(object):
-def do_something_else(x, y=0):
- print 'x: %s, y: %s' % (x, y)
+ def get_keyword_names(self):
+ return [name for name in dir(self) if name.startswith('do_')]
-def do_something_third(a, b=2, c=3):
- print a, b, c
+ def run_keyword(self, name, args):
+ return getattr(self, name)(*args)
-KEYWORDS = {
- 'do_something': do_something,
- 'do_something_else': do_something_else,
- 'do_something_third': do_something_third
-}
+ def do_something(self, x):
+ print x
-class DynamicLibraryWithoutArgspec(object):
- def get_keyword_names(self):
- return KEYWORDS.keys()
+ def do_something_else(self, x, y=0):
+ print 'x: %s, y: %s' % (x, y)
- def run_keyword(self, kw_name, args):
- KEYWORDS[kw_name](*args)
+ def do_something_third(self, a, b=2, c=3):
+ print a, b, c
==============================================================================
Revision: 54ed6c9c33cf
Branch: default
Author: Pekka Klärck
Date: Thu Nov 21 12:26:42 2013 UTC
Log: Dynamic libs: return '*varargs' instead of '*unknown' when no arg
spec.
Also tested this better.
Update issue 1500
Return '*varargs, **kwargs' and not '*unknown, **kwargs' if there is no arg
spec.
http://code.google.com/p/robotframework/source/detail?r=54ed6c9c33cf
Modified:
/atest/robot/libdoc/dynamic_library_with_args.txt
/atest/testdata/libdoc/DynamicLibrary.py
/src/robot/running/dynamicmethods.py
/utest/running/test_handlers.py
=======================================
--- /atest/robot/libdoc/dynamic_library_with_args.txt Mon May 6 12:19:31
2013 UTC
+++ /atest/robot/libdoc/dynamic_library_with_args.txt Thu Nov 21 12:26:42
2013 UTC
@@ -47,4 +47,7 @@
Keyword Doc Should Start With 2 Dummy documentation for `KW2`.
Non ASCII
- Keyword Doc Should Be 3 Hyvää yötä.\n\nСпасибо!
+ Keyword Doc Should Be 4 Hyvää yötä.\n\nСпасибо!
+
+No Argspec
+ Keyword Arguments Should be 3 *varargs **kwargs
=======================================
--- /atest/testdata/libdoc/DynamicLibrary.py Tue Feb 14 11:59:52 2012 UTC
+++ /atest/testdata/libdoc/DynamicLibrary.py Thu Nov 21 12:26:42 2013 UTC
@@ -8,12 +8,14 @@
"""This is overwritten and not shown in docs"""
def get_keyword_names(self):
- return ['0', 'Keyword 1', 'KW2', 'non ascii doc 42']
+ return ['0', 'Keyword 1', 'KW2', 'non ascii doc 42', 'no arg spec']
- def run_keyword(self, name, args):
+ def run_keyword(self, name, args, kwargs):
print name, args
def get_keyword_arguments(self, name):
+ if name == 'no arg spec':
+ return None
return ['arg%d' % (i+1) for i in range(int(name[-1]))]
def get_keyword_documentation(self, name):
=======================================
--- /src/robot/running/dynamicmethods.py Wed Nov 20 17:05:12 2013 UTC
+++ /src/robot/running/dynamicmethods.py Thu Nov 21 12:26:42 2013 UTC
@@ -102,8 +102,7 @@
def _handle_return_value(self, value):
if value is None:
- # TODO: Use *varargs, **kwargs or *unknown, **unknown
if self._kwargs_support:
- return ['*unknown', '**kwargs']
- return ['*unknown']
+ return ['*varargs', '**kwargs']
+ return ['*varargs']
return self._to_list_of_strings(value)
=======================================
--- /utest/running/test_handlers.py Wed Nov 20 17:05:12 2013 UTC
+++ /utest/running/test_handlers.py Thu Nov 21 12:26:42 2013 UTC
@@ -93,7 +93,10 @@
self._assert_fails('Return value must be string.', doc=True)
def test_none_argspec(self):
- self._assert_spec(None, maxargs=sys.maxint,vararg='unknown')
+ self._assert_spec(None, maxargs=sys.maxint, vararg='varargs',
kwarg=False)
+
+ def test_none_argspec_when_kwargs_supported(self):
+ self._assert_spec(None, maxargs=sys.maxint, vararg='varargs',
kwarg='kwargs')
def test_empty_argspec(self):
self._assert_spec([])
@@ -160,7 +163,14 @@
def _assert_spec(self, argspec, minargs=0, maxargs=0, positional=[],
defaults=[], vararg=None, kwarg=None):
- for kwargs_support in [True, False] if not kwarg else [True]:
+ if kwarg is None:
+ kwargs_support_modes = [True, False]
+ elif kwarg is False:
+ kwargs_support_modes = [False]
+ kwarg = None
+ else:
+ kwargs_support_modes = [True]
+ for kwargs_support in kwargs_support_modes:
arguments = self._create_handler(argspec,
kwargs_support=kwargs_support
).arguments
@@ -176,14 +186,14 @@
self._create_handler, argspec, doc)
def _create_handler(self, argspec=None, doc=None,
kwargs_support=False):
- doc = GetKeywordDocumentation(lib=None)._handle_return_value(doc)
- argspec =
GetKeywordArguments(lib=None)._handle_return_value(argspec)
+ lib = LibraryMock('TEST CASE')
if kwargs_support:
- handler_func = lambda name, args, kwargs: None
+ lib.run_keyword = lambda name, args, kwargs: None
else:
- handler_func = lambda name, args: None
- return DynamicHandler(LibraryMock('TEST CASE'), 'mock',
handler_func,
- doc, argspec)
+ lib.run_keyword = lambda name, args: None
+ doc = GetKeywordDocumentation(lib)._handle_return_value(doc)
+ argspec = GetKeywordArguments(lib)._handle_return_value(argspec)
+ return DynamicHandler(lib, 'mock', lib.run_keyword, doc, argspec)
if utils.is_jython:
@@ -209,7 +219,7 @@
def test_arg_limits_with_defaults(self):
# defaults i.e. multiple signatures
- for mina, maxa in [(0,1), (1,3)]:
+ for mina, maxa in [(0, 1), (1, 3)]:
method = handlers['a_%d_%d' % (mina, maxa)]
handler = _JavaHandler(LibraryMock(), method.__name__,
method)
assert_equals(handler.arguments.minargs, mina)
==============================================================================
Revision: e3ae9ca64a98
Branch: default
Author: Pekka Klärck
Date: Thu Nov 21 12:51:47 2013 UTC
Log: Dynamic libs: Refactored detecting does run_keyword support
**kwargs
Update issue 1500
Refactored detecting does run_keyword support **kwargs. Now RunKeyword
knows it and we also got rid off DynamicMethodArgumentParser.
We did some changes to internal APIs to make the code cleaner, but those
changes should not matter to anyone using Robot.
We have now gone through all the TODOs we added to tests and code while
merging in the original code. Next up is reviewing the docs. After that
this issue ought to be done. Comments from Stefan regarding to our changes
are obviously welcome.
http://code.google.com/p/robotframework/source/detail?r=e3ae9ca64a98
Added:
/src/robot/utils/robotinspect.py
Modified:
/atest/testresources/testlibs/classes.py
/src/robot/running/arguments/__init__.py
/src/robot/running/arguments/argumentparser.py
/src/robot/running/dynamicmethods.py
/src/robot/running/handlers.py
/src/robot/running/testlibraries.py
/src/robot/running/userkeyword.py
/src/robot/utils/__init__.py
/utest/running/test_handlers.py
/utest/running/test_userhandlers.py
=======================================
--- /dev/null
+++ /src/robot/utils/robotinspect.py Thu Nov 21 12:51:47 2013 UTC
@@ -0,0 +1,34 @@
+# Copyright 2008-2013 Nokia Siemens Networks Oyj
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import sys
+
+
+if sys.platform.startswith('java'):
+ from org.python.core import PyReflectedFunction, PyReflectedConstructor
+
+ def is_java_init(init):
+ return isinstance(init, PyReflectedConstructor)
+
+ def is_java_method(method):
+ return hasattr(method, 'im_func') \
+ and isinstance(method.im_func, PyReflectedFunction)
+
+else:
+
+ def is_java_init(init):
+ return False
+
+ def is_java_method(method):
+ return False
=======================================
--- /atest/testresources/testlibs/classes.py Wed Nov 20 17:05:12 2013 UTC
+++ /atest/testresources/testlibs/classes.py Thu Nov 21 12:51:47 2013 UTC
@@ -158,7 +158,7 @@
('Varargs and Kwargs',
['*args', '**kwargs'])]:
self._keywords[name] = _KeywordInfo(name, argspec)
- def run_keyword(self, name, args, kwargs):
+ def run_keyword(self, name, args, kwargs={}):
argstr = ' '.join([str(a) for a in args] +
['%s:%s' % kv for kv in sorted(kwargs.items())])
print '*INFO* Executed keyword %s with arguments %s' % (name,
argstr)
=======================================
--- /src/robot/running/arguments/__init__.py Tue Oct 1 09:50:04 2013 UTC
+++ /src/robot/running/arguments/__init__.py Thu Nov 21 12:51:47 2013 UTC
@@ -16,8 +16,7 @@
from .argumentmapper import ArgumentMapper
from .argumentparser import (PythonArgumentParser,
UserKeywordArgumentParser,
- DynamicArgumentParser, JavaArgumentParser,
- DynamicMethodArgumentParser)
+ DynamicArgumentParser, JavaArgumentParser)
from .argumentresolver import ArgumentResolver
from .argumentvalidator import ArgumentValidator
if sys.platform.startswith('java'):
=======================================
--- /src/robot/running/arguments/argumentparser.py Wed Nov 20 17:05:12 2013
UTC
+++ /src/robot/running/arguments/argumentparser.py Thu Nov 21 12:51:47 2013
UTC
@@ -25,7 +25,7 @@
def __init__(self, type='Keyword'):
self._type = type
- def parse(self, name, source):
+ def parse(self, source, name=None):
return ArgumentSpec(name, self._type, *self._get_arg_spec(source))
def _get_arg_spec(self, source):
@@ -77,33 +77,9 @@
return positional, defaults, varargs
-# TODO: Could this be implemented as a helper method instead of a class?
-# Current name isn't ideal anyway.
-class DynamicMethodArgumentParser(PythonArgumentParser,
JavaArgumentParser):
- """A generic argument parser for Dynamic Test Library API methods
- like run(_k|K)eyword, which can be either Python or Java based.
- """
- def __init__(self):
- _ArgumentParser.__init__(self, 'DynamicMethod')
-
- def _get_arg_spec(self, method):
- try:
- return PythonArgumentParser._get_arg_spec(self, method)
- except TypeError, err:
- if sys.platform.startswith('java'):
- try:
- # Adapted from _JavaHandler._get_signatures():
- func = method.im_func
- signatures = func.argslist[:func.nargs]
- except AttributeError:
- raise err
- return JavaArgumentParser._get_arg_spec(self, signatures)
- raise err
-
-
class _ArgumentSpecParser(_ArgumentParser):
- def parse(self, name, argspec):
+ def parse(self, argspec, name=None):
result = ArgumentSpec(name, self._type)
for arg in argspec:
if result.kwargs:
=======================================
--- /src/robot/running/dynamicmethods.py Thu Nov 21 12:26:42 2013 UTC
+++ /src/robot/running/dynamicmethods.py Thu Nov 21 12:51:47 2013 UTC
@@ -13,9 +13,9 @@
# limitations under the License.
from robot.errors import DataError
-from robot.utils import get_error_message, unic
+from robot.utils import get_error_message, unic, is_java_method
-from .arguments import DynamicMethodArgumentParser
+from .arguments import JavaArgumentParser, PythonArgumentParser
def no_dynamic_method(*args):
@@ -40,6 +40,10 @@
tokens = self._underscore_name.split('_')
return ''.join([tokens[0]] + [t.capitalize() for t in tokens[1:]])
+ @property
+ def name(self):
+ return self.method.__name__
+
def __call__(self, *args):
try:
return self._handle_return_value(self.method(*args))
@@ -75,6 +79,18 @@
class RunKeyword(_DynamicMethod):
_underscore_name = 'run_keyword'
+ def __init__(self, lib):
+ _DynamicMethod.__init__(self, lib)
+ argspec = self._parse_argspec(self.method)
+ self.kwargs_supported = len(argspec.positional) == 3
+
+ def _parse_argspec(self, method):
+ if not is_java_method(method):
+ return PythonArgumentParser().parse(method)
+ func = method.im_func
+ signatures = func.argslist[:func.nargs]
+ return JavaArgumentParser().parse(signatures)
+
class GetKeywordDocumentation(_DynamicMethod):
_underscore_name = 'get_keyword_documentation'
@@ -88,21 +104,11 @@
def __init__(self, lib):
_DynamicMethod.__init__(self, lib)
- # Check if the lib's run_keyword method supports **kwargs
- # (self, name, args, kwargs)
- # TODO: Extract method
- run_keyword_method = RunKeyword(lib).method
- if run_keyword_method is not no_dynamic_method:
- argspec = DynamicMethodArgumentParser().parse(
- 'run_keyword', run_keyword_method)
- if len(argspec.positional) > 2:
- self._kwargs_support = True
- return
- self._kwargs_support = False
+ self._kwargs_supported = RunKeyword(lib).kwargs_supported
def _handle_return_value(self, value):
if value is None:
- if self._kwargs_support:
+ if self._kwargs_supported:
return ['*varargs', '**kwargs']
return ['*varargs']
return self._to_list_of_strings(value)
=======================================
--- /src/robot/running/handlers.py Wed Nov 20 17:05:12 2013 UTC
+++ /src/robot/running/handlers.py Thu Nov 21 12:51:47 2013 UTC
@@ -20,30 +20,19 @@
from .arguments import (PythonArgumentParser, JavaArgumentParser,
DynamicArgumentParser, ArgumentResolver,
- ArgumentMapper, JavaArgumentCoercer,
- DynamicMethodArgumentParser)
+ ArgumentMapper, JavaArgumentCoercer)
from .keywords import Keywords, Keyword
from .outputcapture import OutputCapturer
from .runkwregister import RUN_KW_REGISTER
from .signalhandler import STOP_SIGNAL_MONITOR
-if utils.is_jython:
- from org.python.core import PyReflectedFunction, PyReflectedConstructor
- def _is_java_init(init):
- return isinstance(init, PyReflectedConstructor)
- def _is_java_method(method):
- return hasattr(method, 'im_func') \
- and isinstance(method.im_func, PyReflectedFunction)
-else:
- _is_java_init = _is_java_method = lambda item: False
-
def Handler(library, name, method):
if RUN_KW_REGISTER.is_run_keyword(library.orig_name, name):
return _RunKeywordHandler(library, name, method)
- if _is_java_method(method):
+ if utils.is_java_method(method):
return _JavaHandler(library, name, method)
else:
return _PythonHandler(library, name, method)
@@ -56,7 +45,7 @@
def InitHandler(library, method, docgetter=None):
- Init = _PythonInitHandler if not _is_java_init(method) else
_JavaInitHandler
+ Init = _PythonInitHandler if not utils.is_java_init(method) else
_JavaInitHandler
return Init(library, '__init__', method, docgetter)
@@ -177,7 +166,7 @@
self._doc = utils.getdoc(handler_method)
def _parse_arguments(self, handler_method):
- return PythonArgumentParser().parse(self.longname, handler_method)
+ return PythonArgumentParser().parse(handler_method, self.longname)
class _JavaHandler(_RunnableHandler):
@@ -189,7 +178,7 @@
def _parse_arguments(self, handler_method):
signatures = self._get_signatures(handler_method)
- return JavaArgumentParser().parse(self.longname, signatures)
+ return JavaArgumentParser().parse(signatures, self.longname)
def _get_argument_resolver(self, argspec):
return ArgumentResolver(argspec, resolve_named=False)
@@ -206,28 +195,21 @@
class _DynamicHandler(_RunnableHandler):
- def __init__(self, library, handler_name, handler_method, doc='',
+ def __init__(self, library, handler_name, dynamic_method, doc='',
argspec=None):
self._argspec = argspec
- _RunnableHandler.__init__(self, library, handler_name,
handler_method)
- self._run_keyword_method_name = handler_method.__name__
+ _RunnableHandler.__init__(self, library, handler_name,
+ dynamic_method.method)
+ self._run_keyword_method_name = dynamic_method.name
self._doc = doc is not None and utils.unic(doc) or ''
- # TODO: Extract method. Also store only info are kwargs supported
or not.
- # Check **kwargs handling requirements:
- self._handler_argspec = DynamicMethodArgumentParser().parse(
- handler_name, handler_method)
+ self._kwargs_supported = dynamic_method.kwargs_supported
if argspec and argspec[-1].startswith('**'):
- # --> Keyword has **kwargs
- handler_args = self._handler_argspec.positional
- # --> Handler method needs (self, name, args, kwargs)
- if len(handler_args) < 3:
- raise DataError(
- "Too few '%s' method parameters"
- " for **kwargs support."
- % self._run_keyword_method_name)
+ if not self._kwargs_supported:
+ raise DataError("Too few '%s' method parameters for
**kwargs "
+ "support." % self._run_keyword_method_name)
def _parse_arguments(self, handler_method):
- return DynamicArgumentParser().parse(self.longname, self._argspec)
+ return DynamicArgumentParser().parse(self._argspec, self.longname)
def resolve_arguments(self, arguments, variables=None):
positional, named = _RunnableHandler.resolve_arguments(self,
arguments, variables)
@@ -244,9 +226,7 @@
def _get_dynamic_handler(self, runner, name):
def handler(*positional, **kwargs):
- # Does the runner have enough parameters for **kwargs support?
- # (self, name, args, kwargs)
- if len(self._handler_argspec.positional) > 2:
+ if self._kwargs_supported:
return runner(name, positional, kwargs)
else:
return runner(name, positional)
@@ -400,7 +380,7 @@
def _parse_arguments(self, handler_method):
parser = PythonArgumentParser(type='Test Library')
- return parser.parse(self.library.name, handler_method)
+ return parser.parse(handler_method, self.library.name)
class _JavaInitHandler(_JavaHandler):
@@ -419,4 +399,4 @@
def _parse_arguments(self, handler_method):
parser = JavaArgumentParser(type='Test Library')
signatures = self._get_signatures(handler_method)
- return parser.parse(self.library.name, signatures)
+ return parser.parse(signatures, self.library.name)
=======================================
--- /src/robot/running/testlibraries.py Wed Nov 13 08:14:41 2013 UTC
+++ /src/robot/running/testlibraries.py Thu Nov 21 12:51:47 2013 UTC
@@ -315,7 +315,7 @@
return GetKeywordNames(instance)()
def _get_handler_method(self, instance, name):
- return RunKeyword(instance).method
+ return RunKeyword(instance)
def _create_handler(self, name, method):
doc = self._get_kw_doc(name)
=======================================
--- /src/robot/running/userkeyword.py Wed Nov 20 17:05:12 2013 UTC
+++ /src/robot/running/userkeyword.py Thu Nov 21 12:51:47 2013 UTC
@@ -116,8 +116,8 @@
self.teardown = keyword.teardown
self.libname = libname
self.doc = self._doc = unicode(keyword.doc)
- self.arguments = UserKeywordArgumentParser().parse(self.longname,
-
tuple(keyword.args))
+ self.arguments =
UserKeywordArgumentParser().parse(tuple(keyword.args),
+ self.longname)
self._timeout = keyword.timeout
@property
=======================================
--- /src/robot/utils/__init__.py Tue Nov 19 13:19:28 2013 UTC
+++ /src/robot/utils/__init__.py Thu Nov 21 12:51:47 2013 UTC
@@ -49,6 +49,7 @@
from .misc import plural_or_not, printable_name, seq2str, seq2str2,
getdoc, isatty
from .normalizing import lower, normalize, NormalizedDict
from .robotenv import get_env_var, set_env_var, del_env_var, get_env_vars
+from .robotinspect import is_java_init, is_java_method
from .robotpath import abspath, find_file, get_link_path, normpath
from .robottime import (get_timestamp, get_start_timestamp, format_time,
get_time, get_elapsed_time, elapsed_time_to_string,
=======================================
--- /utest/running/test_handlers.py Thu Nov 21 12:26:42 2013 UTC
+++ /utest/running/test_handlers.py Thu Nov 21 12:51:47 2013 UTC
@@ -6,7 +6,8 @@
from robot import utils
from robot.utils.asserts import *
from robot.running.testlibraries import TestLibrary
-from robot.running.dynamicmethods import GetKeywordArguments,
GetKeywordDocumentation
+from robot.running.dynamicmethods import (
+ GetKeywordArguments, GetKeywordDocumentation, RunKeyword)
from robot.errors import DataError
from classes import NameLibrary, DocLibrary, ArgInfoLibrary
@@ -193,7 +194,7 @@
lib.run_keyword = lambda name, args: None
doc = GetKeywordDocumentation(lib)._handle_return_value(doc)
argspec = GetKeywordArguments(lib)._handle_return_value(argspec)
- return DynamicHandler(lib, 'mock', lib.run_keyword, doc, argspec)
+ return DynamicHandler(lib, 'mock', RunKeyword(lib), doc, argspec)
if utils.is_jython:
=======================================
--- /utest/running/test_userhandlers.py Thu May 16 13:01:15 2013 UTC
+++ /utest/running/test_userhandlers.py Thu Nov 21 12:51:47 2013 UTC
@@ -153,7 +153,7 @@
assert_equals(argspec.varargs, exp_varargs)
def _parse(self, in_args):
- return UserKeywordArgumentParser().parse('Name', in_args.split())
+ return UserKeywordArgumentParser().parse(in_args.split())
def test_many_varargs_raises(self):
assert_raises(DataError, self._parse, '@{varargs} @{varargs2}')
--
---
You received this message because you are subscribed to the Google Groups "robotframework-commit" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/groups/opt_out.