Skip to content

Commit

Permalink
CLI: Fix exception for verdi plugin list (#6560)
Browse files Browse the repository at this point in the history
In e952d77 a bug in `verdi plugin list`
was fixed where the conditional to check whether the plugin was a
process class would always raise an `AttributeError` if the plugin was
not a `Process` or a proces function. As a result, the code would never
get to the else-clause.

The else-clause contained itself another bug, which was now revealed by
the fixing of the bug in the conditional. The else-clause would call the
`get_description` classmethod of the plugin, but no classes in AiiDA
that are pluginnable even define such a class method. Probably, the
original author confused it with the instance method `get_description`
but the `verdi plugin list` command just deals with the class.

The `get_description` call is replaced with just getting `__doc__` which
returns the docstring of the class/function, or `None` if it is not
defined. In the latter case, a default message is displayed saying that
no description is available.

Since the else-clause code was never reached before the recent fix and
the `get_description` method was never supported officially by AiiDA's
pluginnable interfaces, it is fine to just change this behavior.
  • Loading branch information
sphuber authored Aug 19, 2024
1 parent fb36862 commit c3b10b7
Show file tree
Hide file tree
Showing 2 changed files with 17 additions and 21 deletions.
15 changes: 7 additions & 8 deletions src/aiida/cmdline/commands/cmd_plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,14 +47,13 @@ def plugin_list(entry_point_group, entry_point):
except EntryPointError as exception:
echo.echo_critical(str(exception))
else:
try:
if (inspect.isclass(plugin) and issubclass(plugin, Process)) or (
hasattr(plugin, 'is_process_function') and plugin.is_process_function
):
print_process_info(plugin)
else:
echo.echo(str(plugin.get_description()))
except AttributeError:
if (inspect.isclass(plugin) and issubclass(plugin, Process)) or (
hasattr(plugin, 'is_process_function') and plugin.is_process_function
):
print_process_info(plugin)
elif plugin.__doc__:
echo.echo(plugin.__doc__)
else:
echo.echo_error(f'No description available for {entry_point}')
else:
entry_points = get_entry_point_names(entry_point_group)
Expand Down
23 changes: 10 additions & 13 deletions tests/cmdline/commands/test_plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
import pytest
from aiida.cmdline.commands import cmd_plugin
from aiida.parsers import Parser
from aiida.plugins import CalculationFactory, ParserFactory, WorkflowFactory
from aiida.plugins import BaseFactory
from aiida.plugins.entry_point import ENTRY_POINT_GROUP_TO_MODULE_PATH_MAP


Expand Down Expand Up @@ -43,6 +43,7 @@ def test_plugin_list_non_existing(run_cli_command):
'entry_point_string',
(
'aiida.calculations:core.arithmetic.add',
'aiida.data:core.array',
'aiida.workflows:core.arithmetic.multiply_add',
'aiida.workflows:core.arithmetic.add_multiply',
),
Expand All @@ -52,24 +53,20 @@ def test_plugin_list_detail(run_cli_command, entry_point_string):
from aiida.plugins.entry_point import parse_entry_point_string

entry_point_group, entry_point_name = parse_entry_point_string(entry_point_string)
factory = CalculationFactory if entry_point_group == 'aiida.calculations' else WorkflowFactory
entry_point = factory(entry_point_name)
entry_point = BaseFactory(entry_point_group, entry_point_name)

result = run_cli_command(cmd_plugin.plugin_list, [entry_point_group, entry_point_name])
assert entry_point.__doc__ in result.output


class CustomParser(Parser):
@classmethod
def get_description(cls) -> str:
return 'str69'
class NoDocStringPluginParser(Parser):
pass


def test_plugin_description(run_cli_command, entry_points):
"""Test that ``verdi plugin list`` uses ``get_description`` if defined."""

entry_points.add(CustomParser, 'aiida.parsers:custom.parser')
assert ParserFactory('custom.parser') is CustomParser
def test_plugin_list_no_docstring(run_cli_command, entry_points):
"""Test ``verdi plugin list`` does not fail if the plugin does not define a docstring."""
entry_points.add(NoDocStringPluginParser, 'aiida.parsers:custom.parser')
assert BaseFactory('aiida.parsers', 'custom.parser') is NoDocStringPluginParser

result = run_cli_command(cmd_plugin.plugin_list, ['aiida.parsers', 'custom.parser'])
assert result.output.strip() == 'str69'
assert result.output.strip() == 'Error: No description available for custom.parser'

0 comments on commit c3b10b7

Please sign in to comment.