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)

Reply via email to