Revision: 7aa0ceef81e7
Branch:   default
Author:   Pekka Klärck
Date:     Mon Dec  2 21:31:37 2013 UTC
Log:      Cleaned up static and dynamic java kwargs code.

Update issue 1583
Cleanup.

This issue has turned out to be a can of worms. Had we know all the corner cases, this would have waited until the next release. We ought to be pretty ready now, though.
http://code.google.com/p/robotframework/source/detail?r=7aa0ceef81e7

Modified:
 /src/robot/running/arguments/argumentresolver.py
 /src/robot/running/dynamicmethods.py
 /src/robot/running/handlers.py
 /src/robot/utils/islike.py

=======================================
--- /src/robot/running/arguments/argumentresolver.py Mon Dec 2 20:38:01 2013 UTC +++ /src/robot/running/arguments/argumentresolver.py Mon Dec 2 21:31:37 2013 UTC
@@ -15,11 +15,6 @@
 from robot.errors import DataError
 from robot.utils import is_dict_like

-try:
-    from java.util import Map
-except:
-    Map = None
-
 from .argumentvalidator import ArgumentValidator


@@ -30,27 +25,18 @@
         self._named_resolver = NamedArgumentResolver(argspec) \
             if resolve_named else NullNamedArgumentResolver()
         self._variable_replacer = VariableReplacer(resolve_variables_until)
+        self._kwargs_handler = KwArgsHandler(argspec)
         self._argument_validator = ArgumentValidator(argspec)
-        self._maxargs = argspec.maxargs

     def resolve(self, arguments, variables=None):
         positional, named = self._named_resolver.resolve(arguments)
positional, named = self._variable_replacer.replace(positional, named,
                                                             variables)
-        if self._last_positional_is_kw_map(positional, named):
-            named = positional.pop()
+        positional, name = self._kwargs_handler.handle(positional, named)
         self._argument_validator.validate(positional, named,
                                           dryrun=not variables)
         return positional, named

-    def _last_positional_is_kw_map(self, positional, named):
-        if named:
-            return False
-        if not len(positional) == self._maxargs + 1:
-            return False
-        last = positional[-1]
-        return is_dict_like(last) or Map and isinstance(last, Map)
-

 class NamedArgumentResolver(object):

@@ -110,6 +96,25 @@

     def resolve(self, arguments):
         return arguments, {}
+
+
+class KwArgsHandler(object):
+
+    def __init__(self, argspec):
+        self._maxargs = argspec.maxargs
+        self._supports_kwargs = bool(argspec.kwargs)
+
+    def handle(self, positional, named):
+        if self._extra_arg_has_kwargs(positional, named):
+            named = positional.pop()
+        return positional, named
+
+    def _extra_arg_has_kwargs(self, positional, named):
+        if named or not self._supports_kwargs:
+            return False
+        if len(positional) != self._maxargs + 1:
+            return False
+        return is_dict_like(positional[-1], allow_java=True)


 class VariableReplacer(object):
=======================================
--- /src/robot/running/dynamicmethods.py        Mon Dec  2 20:38:01 2013 UTC
+++ /src/robot/running/dynamicmethods.py        Mon Dec  2 21:31:37 2013 UTC
@@ -80,19 +80,27 @@
     _underscore_name = 'run_keyword'

     @property
-    def kwargs_supported(self):
+    def supports_kwargs(self):
         if is_java_method(self.method):
-            return self._is_java_runkw_with_kwargs(self.method)
-        return self._is_python_runkw_with_kwargs(self.method)
+            return self._supports_java_kwargs(self.method)
+        return self._supports_python_kwargs(self.method)

-    def _is_python_runkw_with_kwargs(self, method):
-        return len(PythonArgumentParser().parse(method).positional) == 3
+    def _supports_python_kwargs(self, method):
+        spec = PythonArgumentParser().parse(method)
+        return len(spec.positional) == 3

-    def _is_java_runkw_with_kwargs(self, method):
+    def _supports_java_kwargs(self, method):
func = self.method.im_func if hasattr(method, 'im_func') else method
         signatures = func.argslist[:func.nargs]
         spec = JavaArgumentParser().parse(signatures)
-        return len(spec.positional) == 3 or spec.kwargs
+        return (self._java_single_signature_kwargs(spec) or
+                self._java_multi_signature_kwargs(spec))
+
+    def _java_single_signature_kwargs(self, spec):
+        return len(spec.positional) == 1 and spec.varargs and spec.kwargs
+
+    def _java_multi_signature_kwargs(self, spec):
+ return len(spec.positional) == 3 and not (spec.varargs or spec.kwargs)


 class GetKeywordDocumentation(_DynamicMethod):
@@ -107,11 +115,11 @@

     def __init__(self, lib):
         _DynamicMethod.__init__(self, lib)
-        self._kwargs_supported = RunKeyword(lib).kwargs_supported
+        self._supports_kwargs = RunKeyword(lib).supports_kwargs

     def _handle_return_value(self, value):
         if value is None:
-            if self._kwargs_supported:
+            if self._supports_kwargs:
                 return ['*varargs', '**kwargs']
             return ['*varargs']
         return self._to_list_of_strings(value)
=======================================
--- /src/robot/running/handlers.py      Fri Nov 29 12:25:23 2013 UTC
+++ /src/robot/running/handlers.py      Mon Dec  2 21:31:37 2013 UTC
@@ -200,9 +200,9 @@
                                   dynamic_method.method)
         self._run_keyword_method_name = dynamic_method.name
         self._doc = doc is not None and utils.unic(doc) or ''
-        self._kwargs_supported = dynamic_method.kwargs_supported
+        self._supports_kwargs = dynamic_method.supports_kwargs
         if argspec and argspec[-1].startswith('**'):
-            if not self._kwargs_supported:
+            if not self._supports_kwargs:
raise DataError("Too few '%s' method parameters for **kwargs "
                                 "support." % self._run_keyword_method_name)

@@ -224,7 +224,7 @@

     def _get_dynamic_handler(self, runner, name):
         def handler(*positional, **kwargs):
-            if self._kwargs_supported:
+            if self._supports_kwargs:
                 return runner(name, positional, kwargs)
             else:
                 return runner(name, positional)
=======================================
--- /src/robot/utils/islike.py  Fri Nov 29 12:29:11 2013 UTC
+++ /src/robot/utils/islike.py  Mon Dec  2 21:31:37 2013 UTC
@@ -12,6 +12,11 @@
 #  See the License for the specific language governing permissions and
 #  limitations under the License.

+import sys
+if sys.platform.startswith('java'):
+    from java.util import Map
+else:
+    Map = ()
 try:
     from collections import Mapping
 except ImportError:  # New in 2.6
@@ -35,5 +40,6 @@
         return True


-def is_dict_like(item):
-    return isinstance(item, (Mapping, UserDict))
+def is_dict_like(item, allow_java=False):
+    return (isinstance(item, (Mapping, UserDict)) or
+            allow_java and isinstance(item, Map))

--

--- 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 robotframework-commit+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.

Reply via email to