From 5319bc8ffc451ef9d4a764a715b66a53247bbb9d Mon Sep 17 00:00:00 2001 From: Sebastiaan Huber Date: Thu, 2 May 2019 20:16:53 +0200 Subject: [PATCH] Use process function name and docstring as default label and description The function name and docstring will be set as the default for the label and description metadata inputs. If the docstring is not defined, or specific defaults are defined, the defaults are not overridden. --- .../tests/engine/test_process_function.py | 20 ++++++++++++++++++- aiida/engine/processes/functions.py | 10 ++++++++++ 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/aiida/backends/tests/engine/test_process_function.py b/aiida/backends/tests/engine/test_process_function.py index a0a96281e5b..f5ddda1a62a 100644 --- a/aiida/backends/tests/engine/test_process_function.py +++ b/aiida/backends/tests/engine/test_process_function.py @@ -36,7 +36,7 @@ class TestProcessFunction(AiidaTestCase): function would complain as the dummy node class is not recognized as a valid process node. """ - # pylint: disable=too-many-public-methods + # pylint: disable=too-many-public-methods,too-many-instance-attributes def setUp(self): super(TestProcessFunction, self).setUp() @@ -86,6 +86,11 @@ def function_defaults( }): # pylint: disable=unused-argument,dangerous-default-value,missing-docstring return data_a + @workfunction + def function_default_from_docs(): + """Description taken from the docs.""" + return + @workfunction def function_exit_code(exit_status, exit_message): return ExitCode(exit_status.value, exit_message.value) @@ -107,6 +112,7 @@ def function_out_unstored(): self.function_args_and_kwargs = function_args_and_kwargs self.function_args_and_default = function_args_and_default self.function_defaults = function_defaults + self.function_default_from_docs = function_default_from_docs self.function_exit_code = function_exit_code self.function_excepts = function_excepts self.function_out_unstored = function_out_unstored @@ -300,6 +306,18 @@ def test_function_defaults(self): self.assertEqual(node.label, CUSTOM_LABEL) self.assertEqual(node.description, CUSTOM_DESCRIPTION) + def test_function_default_label_description(self): + """Verify unless specified label and description are taken from function name and docstring respectively.""" + metadata = {'label': CUSTOM_LABEL, 'description': CUSTOM_DESCRIPTION} + + _, node = self.function_default_from_docs.run_get_node() + self.assertEqual(node.label, 'function_default_from_docs') + self.assertEqual(node.description, 'Description taken from the docs.') + + _, node = self.function_default_from_docs.run_get_node(metadata=metadata) + self.assertEqual(node.label, CUSTOM_LABEL) + self.assertEqual(node.description, CUSTOM_DESCRIPTION) + def test_launchers(self): """Verify that the various launchers are working.""" result = run(self.function_return_true) diff --git a/aiida/engine/processes/functions.py b/aiida/engine/processes/functions.py index b1a4d131ef6..2f97bd08292 100644 --- a/aiida/engine/processes/functions.py +++ b/aiida/engine/processes/functions.py @@ -221,6 +221,16 @@ def _define(cls, spec): spec.input(arg, valid_type=valid_type, default=default) + # Set defaults for label and description based on function name and docstring, if not explicitly defined + port_label = spec.inputs['metadata']['label'] + port_description = spec.inputs['metadata']['description'] + + if not port_label.has_default(): + port_label.default = func.__name__ + + if not port_description.has_default() and func.__doc__: + port_description.default = func.__doc__ + # If the function support kwargs then allow dynamic inputs, otherwise disallow spec.inputs.dynamic = keywords is not None