diff --git a/rally/common/plugin/info.py b/rally/common/plugin/info.py index b410f93008..f788930c24 100644 --- a/rally/common/plugin/info.py +++ b/rally/common/plugin/info.py @@ -80,11 +80,19 @@ def parse_docstring(docstring): class InfoMixin(object): + @classmethod + def _get_doc(cls): + """Return documentary of class + + By default it returns docstring of class, but it can be overridden + for example for cases like merging own docstring with parent + """ + return cls.__doc__ + @classmethod def get_info(cls): plugin_ = getattr(cls, "func_ref", cls) - doc_source = getattr(plugin_, "_doc_source_", plugin_) - doc = parse_docstring(doc_source.__doc__) + doc = parse_docstring(cls._get_doc()) return { "name": plugin_.get_name(), diff --git a/rally/task/scenario.py b/rally/task/scenario.py index 3fd0b06801..edca3443c9 100644 --- a/rally/task/scenario.py +++ b/rally/task/scenario.py @@ -50,8 +50,6 @@ def configure(name=None, namespace="default", context=None): scen.is_classbased = hasattr(scen, "run") and callable(scen.run) if not scen.is_classbased: plugin.from_func(Scenario)(scen) - else: - scen._doc_source_ = scen.run scen._meta_init() if name: @@ -261,3 +259,9 @@ class Scenario(plugin.Plugin, if message: raise exceptions.RallyException(message) self._output[key].append(value) + + @classmethod + def _get_doc(cls): + if cls.is_classbased: + return cls.run.__doc__ + return cls.__doc__