diff --git a/src/snakemake_interface_common/plugin_registry/plugin.py b/src/snakemake_interface_common/plugin_registry/plugin.py index 4c4a232..d240f8b 100644 --- a/src/snakemake_interface_common/plugin_registry/plugin.py +++ b/src/snakemake_interface_common/plugin_registry/plugin.py @@ -335,6 +335,10 @@ def _get_prefixed_name(self, field_name: str) -> str: def _parse_type(self, thefield: Field, value: Any, thetype: Any) -> Any: def apply_type(value: Any, thetype: Any) -> Any: try: + if typing.get_origin(thetype) is list: + thetype = typing.get_args(thetype)[0] + if isinstance(value, list) and thetype is not list: + return [thetype(item) for item in value] return thetype(value) except Exception as e: raise WorkflowError( diff --git a/tests/tests.py b/tests/tests.py index b17bb84..7a47d5c 100644 --- a/tests/tests.py +++ b/tests/tests.py @@ -1,5 +1,5 @@ -from dataclasses import dataclass -from typing import Optional +from dataclasses import dataclass, field +from typing import List, Optional import pytest from snakemake_interface_common import at_least_snakemake_version @@ -140,6 +140,35 @@ def __init__(self): assert settings.optional_int is None +@dataclass +class ListSettings(SettingsBase): + mounts: Optional[List[str]] = field( + default=None, metadata={"help": "mounts", "nargs": "+"} + ) + ints: List[int] = field( + default_factory=list, metadata={"help": "ints", "nargs": "+"} + ) + + +class ListPlugin(TestPlugin): + @property + def settings_cls(self): + return ListSettings + + +@pytest.mark.parametrize( + "mounts, ints", [(["/a:/a", "/b:/b"], [1, 2]), (["/a:/a"], ["1", "2"])] +) +def test_settings_list_nargs(mounts, ints): + class MockArgs: + test_mounts = mounts + test_ints = ints + + settings = ListPlugin().get_settings(MockArgs()) + assert settings.mounts == mounts + assert settings.ints == [1, 2] + + def test_access_pattern_str(): from snakemake_interface_common.io import AccessPattern