Revision: 20ce1f994a33
Author: Janne Härkönen <[email protected]>
Date: Fri Sep 16 03:36:56 2011
Log: handlers: made doc a property
Now documentation for handlers is resoved dynamically.
This reduces risk of runtime failures in dynamic libraries
because get_keyword_documentation is no longer called
with __init__ as argument during runtime.
http://code.google.com/p/robotframework/source/detail?r=20ce1f994a33
Modified:
/atest/testresources/testlibs/dynlibs.py
/src/robot/running/handlers.py
/src/robot/running/testlibraries.py
/utest/running/test_testlibrary.py
=======================================
--- /atest/testresources/testlibs/dynlibs.py Fri Sep 16 00:41:42 2011
+++ /atest/testresources/testlibs/dynlibs.py Fri Sep 16 03:36:56 2011
@@ -37,5 +37,5 @@
def __init__(self):
"""initoo-o-o"""
def get_keyword_documentation(self, name):
- raise RuntimeError('This should be ignored')
-
+ raise RuntimeError('Failing in get_keyword_documentation')
+
=======================================
--- /src/robot/running/handlers.py Fri Sep 16 00:41:42 2011
+++ /src/robot/running/handlers.py Fri Sep 16 03:36:56 2011
@@ -54,14 +54,14 @@
return _DynamicHandler(library, name, method, doc, argspec)
-def InitHandler(library, method, doc=''):
+def InitHandler(library, method, docgetter=None):
Init = _PythonInitHandler if not _is_java_init(method) else
_JavaInitHandler
- return Init(library, '__init__', method, doc)
+ return Init(library, '__init__', method, docgetter)
class _BaseHandler(object):
type = 'library'
- doc = ''
+ _doc = ''
def __init__(self, library, handler_name, handler_method):
self.library = library
@@ -71,6 +71,10 @@
def _parse_arguments(self, handler_method):
raise NotImplementedError(self.__class__.__name__)
+ @property
+ def doc(self):
+ return self._doc
+
@property
def longname(self):
return '%s.%s' % (self.library.name, self.name)
@@ -169,7 +173,7 @@
def __init__(self, library, handler_name, handler_method):
_RunnableHandler.__init__(self, library, handler_name,
handler_method)
- self.doc = utils.getdoc(handler_method)
+ self._doc = utils.getdoc(handler_method)
def _parse_arguments(self, handler_method):
return PythonKeywordArguments(handler_method, self.longname)
@@ -188,7 +192,7 @@
self._argspec = argspec
_RunnableHandler.__init__(self, library, handler_name,
handler_method)
self._run_keyword_method_name = handler_method.__name__
- self.doc = doc is not None and utils.unic(doc) or ''
+ self._doc = doc is not None and utils.unic(doc) or ''
def _parse_arguments(self, handler_method):
return DynamicKeywordArguments(self._argspec, self.longname)
@@ -262,7 +266,7 @@
_RunKeywordHandler.__init__(self, handler.library, handler.name,
handler._handler_method)
self.name = name
- self.doc = "*DEPRECATED* Replace X times syntax with 'Repeat
Keyword'."
+ self._doc = "*DEPRECATED* Replace X times syntax with 'Repeat
Keyword'."
def run(self, context, args):
resolved_times =
context.namespace.variables.replace_string(self.name)
@@ -280,9 +284,15 @@
class _PythonInitHandler(_PythonHandler):
- def __init__(self, library, handler_name, handler_method, doc):
+ def __init__(self, library, handler_name, handler_method, docgetter):
_PythonHandler.__init__(self, library, handler_name,
handler_method)
- self.doc = doc or self.doc
+ self._docgetter = docgetter
+
+ @property
+ def doc(self):
+ if self._docgetter():
+ return self._docgetter() or self._doc
+ return self._doc
def _parse_arguments(self, handler_method):
return PythonInitArguments(handler_method, self.library.name)
@@ -290,9 +300,15 @@
class _JavaInitHandler(_BaseHandler):
- def __init__(self, library, handler_name, handler_method, doc):
+ def __init__(self, library, handler_name, handler_method, docgetter):
_BaseHandler.__init__(self, library, handler_name, handler_method)
- self.doc = doc or ''
+ self._docgetter = docgetter
+
+ @property
+ def doc(self):
+ if self._docgetter():
+ return self._docgetter() or self._doc
+ return self._doc
def _parse_arguments(self, handler_method):
return JavaInitArguments(handler_method, self.library.name)
=======================================
--- /src/robot/running/testlibraries.py Fri Sep 16 00:41:42 2011
+++ /src/robot/running/testlibraries.py Fri Sep 16 03:36:56 2011
@@ -323,15 +323,15 @@
_log_failure = LOGGER.warn
def __init__(self, libcode, source, name, args, variables=None):
+ _BaseTestLibrary.__init__(self, libcode, source, name, args,
variables)
self._get_kw_doc = \
_DynamicMethod(libcode, 'get_keyword_documentation',
default='')
self._get_kw_args = \
_DynamicMethod(libcode, 'get_keyword_arguments', default=None)
- _BaseTestLibrary.__init__(self, libcode, source, name, args,
variables)
@property
def doc(self):
- return self._get_special_documentation('__intro__') or self._doc
+ return self._get_kw_doc(self.get_instance(), '__intro__') or
self._doc
def _get_handler_names(self, instance):
try:
@@ -351,11 +351,5 @@
return DynamicHandler(self, handler_name, handler_method, doc,
argspec)
def _create_init_handler(self, libcode):
- return InitHandler(self, self._resolve_init_method(libcode),
- self._get_special_documentation('__init__'))
-
- def _get_special_documentation(self, doc_type):
- try:
- return self._get_kw_doc(self.get_instance(), doc_type)
- except DataError:
- return ''
+ docgetter = lambda:
self._get_kw_doc(self.get_instance(), '__init__')
+ return InitHandler(self, self._resolve_init_method(libcode),
docgetter)
=======================================
--- /utest/running/test_testlibrary.py Fri Sep 16 00:41:42 2011
+++ /utest/running/test_testlibrary.py Fri Sep 16 03:36:56 2011
@@ -496,9 +496,13 @@
self._assert_intro_doc('dynlibs.StaticAndDynamicDocsLib',
'dynamic override')
- def test_failure_in_dynamic_resolving_of_doc_ignored(self):
- self._assert_intro_doc('dynlibs.FailingDynamicDocLib',
- 'intro-o-o')
+ def test_failure_in_dynamic_resolving_of_doc(self):
+ try:
+ TestLibrary('dynlibs.FailingDynamicDocLib').doc
+ except DataError:
+ pass
+ else:
+ raise AssertionError()
def _assert_intro_doc(self, library_name, expected_doc):
assert_equals(TestLibrary(library_name).doc, expected_doc)
@@ -521,9 +525,13 @@
self._assert_init_doc('dynlibs.StaticAndDynamicDocsLib',
'dynamic override')
- def test_failure_in_dynamic_resolving_of_doc_ignored(self):
- self._assert_init_doc('dynlibs.FailingDynamicDocLib',
- 'initoo-o-o')
+ def test_failure_in_dynamic_resolving_of_doc(self):
+ try:
+ TestLibrary('dynlibs.FailingDynamicDocLib').init.doc
+ except DataError:
+ pass
+ else:
+ raise AssertionError()
def _assert_init_doc(self, library_name, expected_doc):
assert_equals(TestLibrary(library_name).init.doc, expected_doc)