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.

Reply via email to