Revision: 2844
Author: KariHusa
Date: Wed Apr 7 02:16:21 2010
Log: Refactoring
http://code.google.com/p/robotframework/source/detail?r=2844
Added:
/trunk/src/robot/running/argtypes.py
Modified:
/trunk/src/robot/running/handlers.py
/trunk/src/robot/running/userkeyword.py
=======================================
--- /dev/null
+++ /trunk/src/robot/running/argtypes.py Wed Apr 7 02:16:21 2010
@@ -0,0 +1,73 @@
+# Copyright 2008-2009 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.
+
+class _ArgTypeResolver(object):
+
+ def __init__(self, names, values):
+ self._names = names
+ self._values = values
+ self.posargs, self.kwargs = self._resolve()
+
+ def _resolve(self):
+ posargs = []
+ kwargs = {}
+ kwargs_allowed = True
+ for arg in reversed(self._values):
+ if kwargs_allowed and self._is_kwarg(arg):
+ kwargs.update(self._parse_kwarg(arg))
+ else:
+ posargs.append(self._parse_posarg(arg))
+ kwargs_allowed = False
+ return reversed(posargs), kwargs
+
+ def _is_kwarg(self, arg):
+ if self._is_str_with_kwarg_sep(arg):
+ name, _ = self._split_from_kwarg_sep(arg)
+ return self._is_arg_name(name)
+ return False
+
+ def _is_str_with_kwarg_sep(self, arg):
+ if not isinstance(arg, basestring):
+ return False
+ if not '=' in arg:
+ return False
+ return True
+
+ def _split_from_kwarg_sep(self, arg):
+ return arg.split('=', 1)
+
+ def _parse_posarg(self, argstr):
+ if self._is_str_with_kwarg_sep(argstr):
+ name, _ = self._split_from_kwarg_sep(argstr)
+ if self._is_arg_name(name[:-1]):
+ return argstr.replace('\\=', '=')
+ return argstr
+
+class UserKeywordArgTypeResolver(_ArgTypeResolver):
+
+ def _is_arg_name(self, name):
+ return ('${%s}') % name in self._names
+
+ def _parse_kwarg(self, arg):
+ name, value = self._split_from_kwarg_sep(arg)
+ return {('${%s}') % name: value}
+
+class LibraryKeywordArgTypeResolver(_ArgTypeResolver):
+
+ def _is_arg_name(self, name):
+ return name in self._names
+
+ def _parse_kwarg(self, arg):
+ name, value = self._split_from_kwarg_sep(arg)
+ return {str(name): value}
=======================================
--- /trunk/src/robot/running/handlers.py Wed Apr 7 01:07:20 2010
+++ /trunk/src/robot/running/handlers.py Wed Apr 7 02:16:21 2010
@@ -19,7 +19,10 @@
from robot import utils
from robot.errors import FrameworkError
from robot.common import BaseHandler
+
from runkwregister import RUN_KW_REGISTER
+from argtypes import LibraryKeywordArgTypeResolver
+
if utils.is_jython:
from org.python.core import PyReflectedFunction, PyReflectedConstructor
@@ -125,52 +128,11 @@
return self.check_arg_limits(args)
def _run_handler(self, handler, args, output, timeout):
- posargs, kwargs = self._resolve_kwargs(args)
+ arg_resolver = LibraryKeywordArgTypeResolver(self.args, args)
+ posargs = arg_resolver.posargs
if timeout is not None and timeout.active():
return timeout.run(handler, args=posargs, logger=output)
- return handler(*posargs, **kwargs)
-
- def _resolve_kwargs(self, arguments):
- posargs = []
- kwargs = {}
- kwargs_allowed = True
- for arg in reversed(arguments):
- if kwargs_allowed and self._is_kwarg(arg):
- kwargs.update(self._parse_kwarg(arg))
- else:
- posargs.append(self._parse_posarg(arg))
- kwargs_allowed = False
- return reversed(posargs), kwargs
-
- def _is_kwarg(self, arg):
- if self._is_str_with_kwarg_sep(arg):
- name, _ = self._split_from_kwarg_sep(arg)
- return self._is_arg_name(name)
- return False
-
- def _is_arg_name(self, name):
- return name in self.args
-
- def _is_str_with_kwarg_sep(self, arg):
- if not isinstance(arg, basestring):
- return False
- if not '=' in arg:
- return False
- return True
-
- def _parse_kwarg(self, arg):
- name, value = self._split_from_kwarg_sep(arg)
- return {str(name): value}
-
- def _split_from_kwarg_sep(self, arg):
- return arg.split('=', 1)
-
- def _parse_posarg(self, argstr):
- if self._is_str_with_kwarg_sep(argstr):
- name, _ = self._split_from_kwarg_sep(argstr)
- if self._is_arg_name(name[:-1]):
- return argstr.replace('\\=', '=')
- return argstr
+ return handler(*posargs, **arg_resolver.kwargs)
def _get_timeout(self, namespace):
# Timeouts must not be active for run keyword variants, only for
=======================================
--- /trunk/src/robot/running/userkeyword.py Tue Apr 6 22:25:31 2010
+++ /trunk/src/robot/running/userkeyword.py Wed Apr 7 02:16:21 2010
@@ -23,6 +23,7 @@
from keywords import KeywordFactory
from timeouts import KeywordTimeout
+from argtypes import UserKeywordArgTypeResolver
def PublicUserLibrary(path):
@@ -109,9 +110,9 @@
self._libname = libname
self._set_variable_dependent_metadata(handlerdata.metadata)
self.keywords = [ KeywordFactory(kw) for kw in
handlerdata.keywords ]
- self.args = handlerdata.args
- self.defaults = handlerdata.defaults
- self.varargs = handlerdata.varargs
+ self.arguments = UserKeywordArguments(handlerdata.args,
+ handlerdata.defaults,
+ handlerdata.varargs)
self.minargs = handlerdata.minargs
self.maxargs = handlerdata.maxargs
self.return_value = handlerdata.return_value
@@ -130,57 +131,26 @@
def run(self, output, namespace, arguments):
namespace.start_user_keyword(self)
- vars = namespace.variables
- args = vars.replace_list(arguments)
- self._tracelog_args(output, args)
- self.check_arg_limits(args)
- self._set_args_to_namespace(args, vars)
+ variables = namespace.variables
+ argument_values = variables.replace_list(arguments)
+ self._tracelog_args(output, argument_values)
+ self.check_arg_limits(argument_values)
+ self.arguments.set_to(variables, argument_values)
self._verify_keyword_is_valid()
self.timeout.start()
self._run_kws(output, namespace)
- ret = self._get_return_value(vars)
+ ret = self._get_return_value(variables)
namespace.end_user_keyword()
output.trace('Return: %s' % utils.unic(ret))
return ret
- def _set_args_to_namespace(self, arguments, vars):
- signature = self._get_signature(vars)
- args = arguments
- if self.varargs:
- vars[self.varargs] = self._get_varargs(args)
- args = args[:len(signature)]
- args = self._replace_kwargs(signature, args)
- for name, value in zip(self.args, args):
- vars[name] = value
-
- def _get_signature(self, variables):
- return [ MissingArg() for _ in
range(len(self.args)-len(self.defaults)) ] +\
- list(variables.replace_list(self.defaults))
-
- def _replace_kwargs(self, signature, arguments):
- for arg in reversed(arguments):
- if self._is_str_with_kwarg_sep(arg):
- name, value = self._split_from_kwarg_sep(arg)
- name = '${%s}' % name
- if name in self.args:
- signature[self.args.index(name)] = value
- arguments.pop(-1)
- else:
- break
- for index, arg in enumerate(arguments):
- signature[index] = arg
- return signature
-
- def _is_str_with_kwarg_sep(self, arg):
- if not isinstance(arg, basestring):
- return False
- if not '=' in arg:
- return False
- return True
-
- def _split_from_kwarg_sep(self, arg):
- name, value = arg.split('=', 1)
- return str(name), value
+ def _verify_keyword_is_valid(self):
+ if self._errors:
+ raise DataError('User keyword initialization failed:\n%s'
+ % '\n'.join(self._errors))
+ if not (self.keywords or self.return_value):
+ raise DataError("User keyword '%s' contains no keywords"
+ % self.name)
def _run_kws(self, output, namespace):
for kw in self.keywords:
@@ -190,14 +160,6 @@
namespace.end_user_keyword()
raise
- def _verify_keyword_is_valid(self):
- if self._errors:
- raise DataError('User keyword initialization failed:\n%s'
- % '\n'.join(self._errors))
- if not (self.keywords or self.return_value):
- raise DataError("User keyword '%s' contains no keywords"
- % self.name)
-
def _get_return_value(self, variables):
if not self.return_value:
return None
@@ -206,15 +168,50 @@
return ret
return ret[0]
+
+class UserKeywordArguments(object):
+
+ def __init__(self, argnames, defaults, vararg):
+ self._names = argnames
+ self._defaults = defaults
+ self._vararg = vararg
+
+ def set_to(self, variables, argument_values):
+ template_with_defaults = self._template_for(variables)
+ argument_values =
self._set_possible_varargs(template_with_defaults,
+ variables,
argument_values)
+ self._set_variables(variables, self._fill(template_with_defaults,
+ argument_values))
+
+ def _template_for(self, variables):
+ return [ MissingArg() for _ in
range(len(self._names)-len(self._defaults)) ] +\
+ list(variables.replace_list(self._defaults))
+
+ def _set_possible_varargs(self, template, variables, argument_values):
+ if self._vararg:
+ variables[self._vararg] = self._get_varargs(argument_values)
+ argument_values = argument_values[:len(template)]
+ return argument_values
+
+ def _set_variables(self, variables, args):
+ for name, value in zip(self._names, args):
+ variables[name] = value
+
+ def _fill(self, template, arguments):
+ arg_resolver = UserKeywordArgTypeResolver(self._names, arguments)
+ for name, value in arg_resolver.kwargs.items():
+ template[self._names.index(name)] = value
+ for index, value in enumerate(arg_resolver.posargs):
+ template[index] = value
+ return template
+
def _get_varargs(self, args):
- """Returns args leftoever from argspec and thus belonging to
varargs"""
- vararg_count = len(args) - len(self.args)
- varargs = args[len(args)-vararg_count:]
- return varargs # Variables already replaced
+ return args[len(self._names):]
class MissingArg(object):
- pass
+ def __getattr__(self, name):
+ raise RuntimeError()
class EmbeddedArgsTemplate(UserHandler):
@@ -267,9 +264,7 @@
def _copy_attrs_from_template(self, template):
self._libname = template._libname
self.keywords = template.keywords
- self.args = template.args
- self.defaults = template.defaults
- self.varargs = template.varargs
+ self.arguments = template.arguments
self.minargs = template.minargs
self.maxargs = template.maxargs
self.return_value = template.return_value
--
To unsubscribe, reply using "remove me" as the subject.