Author: janne.t.harkonen
Date: Mon Nov 24 06:11:03 2008
New Revision: 1085

Modified:
   trunk/src/robot/running/handlers.py
   trunk/src/robot/running/testlibraries.py

Log:
added checking of Library constructor arguments, issue 155

Modified: trunk/src/robot/running/handlers.py
==============================================================================
--- trunk/src/robot/running/handlers.py (original)
+++ trunk/src/robot/running/handlers.py Mon Nov 24 06:11:03 2008
@@ -17,7 +17,7 @@
 from types import MethodType, FunctionType

 from robot import utils
-from robot.errors import FrameworkError
+from robot.errors import DataError, FrameworkError
 from robot.common import BaseHandler
 from runkwregister import RUN_KW_REGISTER

@@ -155,7 +155,7 @@
             func = handler
             first_arg = 0
         elif self._is_new_style_init_method(handler):
-            return [], [], '<unknown>'
+            return [], [], None
         else:
raise FrameworkError("Only MethodType and FunctionType accepted. "
                                  "Got '%s' instead." % type(handler))
@@ -173,7 +173,8 @@

     def _is_new_style_init_method(self, handler):
         return '__init__' in str(handler) and str(type(handler)) in \
- ["<type 'method-wrapper'>", "<type 'builtin_function_or_method'>"] + ["<type 'wrapper_descriptor'>", "<type 'builtin_function_or_method'>",
+            "<type 'methoddescr'>"]


 class JavaHandler(_RunnableHandler):
@@ -191,7 +192,10 @@
# Ignore methods only in 'java.lang.Object' (e.g. 'equals', 'wait').
         # Also ignore methods declared only in 'org.python.proxies' (there
         # seems to be 'clone' and 'finalize').
-        co = handler.im_func
+        if 'reflectedconstructor' in str(type(handler)):
+            co = handler
+        else:
+            co = handler.im_func
         # signature is an instance of org.python.ReflectedArgs
         for signature in co.argslist[:co.nargs]:
# 'getName' may raise an exception -- not sure why but that happens
@@ -208,7 +212,10 @@
         return False

     def _get_arg_limits(self, handler):
-        co = handler.im_func
+        if 'reflectedconstructor' in str(type(handler)):
+            co = handler
+        else:
+            co = handler.im_func
         signatures = co.argslist[:co.nargs]
         if len(signatures) == 1:
             return self._get_single_sig_arg_limits(signatures[0])
@@ -313,3 +320,49 @@
         self._copy_attributes(handler)
         handler._run_keyword_method_name = self._run_keyword_method_name
         return handler
+
+
+class InitHandler(PythonHandler):
+
+    def __init__(self, library, handler_method):
+        if handler_method is None:
+            self.library = library
+            self.minargs = 0
+            self.maxargs = 0
+        else:
+ PythonHandler.__init__(self, library, '__init__', handler_method)
+
+    def _raise_inv_args(self, args):
+        minend = utils.plural_or_not(self.minargs)
+        if self.minargs == self.maxargs:
+            exptxt = "%d argument%s" % (self.minargs, minend)
+        elif self.maxargs != sys.maxint:
+            exptxt = "%d to %d arguments" % (self.minargs, self.maxargs)
+        else:
+            exptxt = "at least %d argument%s" % (self.minargs, minend)
+        raise DataError("Test Library '%s' expected %s, got %d."
+                        % (self.library.name, exptxt, len(args)))
+
+
+class JavaInitHandler(JavaHandler):
+
+    def __init__(self, library, handler_method):
+        if handler_method is None:
+            self.library = library
+            self.minargs = 0
+            self.maxargs = 0
+        else:
+            JavaHandler.__init__(self, library, '__init__', handler_method)
+
+    def _raise_inv_args(self, args):
+        minend = utils.plural_or_not(self.minargs)
+        if self.minargs == self.maxargs:
+            exptxt = "%d argument%s" % (self.minargs, minend)
+        elif self.maxargs != sys.maxint:
+            exptxt = "%d to %d arguments" % (self.minargs, self.maxargs)
+        else:
+            exptxt = "at least %d argument%s" % (self.minargs, minend)
+        raise DataError("Test Library '%s' expected %s, got %d."
+                        % (self.library.name, exptxt, len(args)))
+
+

Modified: trunk/src/robot/running/testlibraries.py
==============================================================================
--- trunk/src/robot/running/testlibraries.py    (original)
+++ trunk/src/robot/running/testlibraries.py    Mon Nov 24 06:11:03 2008
@@ -21,7 +21,7 @@
 from robot.common import BaseLibrary
 from robot.output import SystemLogger

-from handlers import PythonHandler, JavaHandler, DynamicHandler
+from handlers import PythonHandler, JavaHandler, DynamicHandler, InitHandler, JavaInitHandler


 def TestLibrary(name, args=None, syslog=None):
@@ -72,9 +72,9 @@
             self.doc = utils.get_doc(libcode)
             self.scope = self._get_scope(libcode)
             self._libcode = libcode
+            self.init =  self._get_init(libcode)
             self._libinst = self.get_instance()
             self.handlers = self._create_handlers(self._libinst, syslog)
-            self.init =  self._get_init(self._libinst)
             self._init_scope_handling()

     def _get_version(self, code):
@@ -103,6 +103,7 @@
         lib.scope = self.scope
         lib._libcode = self._libcode
         lib._libinst = self._libinst
+        lib.init = self.init
         lib._init_scope_handling()
         lib.handlers = utils.NormalizedDict(ignore=['_'])
         for handler_name, handler in self.handlers.items():
@@ -145,17 +146,19 @@
         return self._libinst

     def _get_instance(self):
-        try:
+        if self.init:
+            self.init._check_arg_limits(self.args)
+        try:
             return self._libcode(*self.args)
         except:
             self._raise_creating_instance_failed()

     def _get_init(self, libinst):
-        if hasattr(libinst, '__init__'):
-            try:
-                return self._create_handler('__init__', libinst.__init__)
-            except TypeError:
-                pass
+        init =  getattr(libinst, '__init__', None)
+        if callable(init):
+            return self._create_init_handler(init)
+        else:
+            return self._create_init_handler(None)
         return None

     def _create_handlers(self, libinst, syslog):
@@ -210,7 +213,23 @@
         msg += "failed: " + error_msg
         msg += "\n" + error_details
         raise DataError(msg)
-
+
+    def _create_init_handler(self, init_method):
+        if self._is_java_method(init_method):
+            return JavaInitHandler(self, init_method)
+        return InitHandler(self, init_method)
+
+    def _is_java_method(self, method):
+        if not utils.is_jython:
+            return False
+        try:
+            return 'reflectedfunction' in str(type(method.im_func))
+        except AttributeError:
+            try:
+                return 'reflectedconstructor' in str(type(method))
+            except AttributeError:
+                return False
+

 class ModuleLibrary(_BaseTestLibrary):

@@ -233,15 +252,6 @@
         if self._is_java_method(handler_method):
             return JavaHandler(self, handler_name, handler_method)
         return PythonHandler(self, handler_name, handler_method)
-
-    def _is_java_method(self, method):
-        if not utils.is_jython:
-            return False
-        try:
-            return 'reflectedfunction' in str(type(method.im_func)) or \
-                   'reflectedconstructor' in str(type(method.im_func))
-        except AttributeError:
-            return False


 class HybridLibrary(PythonLibrary):
@@ -269,16 +279,13 @@
self._get_keyword_arguments = self._get_method(libcode, *self._get_kw_args_names) _BaseTestLibrary.__init__(self, libcode, source, name, args, syslog)

-    def _get_method(self, libcode, name, alternative):
-        try:
-            code = getattr(libcode, name)
-            return code
-        except AttributeError:
-            try:
-                code = getattr(libcode, alternative)
-                return code
-            except:
-                return None
+    def _get_method(self, libcode, *names):
+        for name in names:
+            if hasattr(libcode, name):
+                method = getattr(libcode, name)
+                if callable(method):
+                    return method
+        return None

     def _get_handler_names(self, instance):
         try:
@@ -299,12 +306,18 @@

     def _get_kw_doc(self, name):
         if self._get_keyword_documentation is not None:
-            return self._get_keyword_documentation(self._libinst, name)
+            try:
+                return self._get_keyword_documentation(self._libinst, name)
+            except TypeError:
+                pass
         return ''

     def _get_kw_argspec(self, name):
         if self._get_keyword_arguments is not None:
-            return self._get_keyword_arguments(self._libinst, name)
+            try:
+                return self._get_keyword_arguments(self._libinst, name)
+            except TypeError:
+                pass
         return None


@@ -312,4 +325,7 @@

     def _create_handler(self, handler_name, handler_method):
         return JavaHandler(self, handler_name, handler_method)
+
+    def _create_init_handler(self, init_method):
+        return JavaInitHandler(self, init_method)

Reply via email to