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)