Skip to content

Forward references are not resolved.

Hi!

When I tried the pytest example and added from __futures__ import annotations to the top of the file, I received the following error.

Code
from __future__ import annotations

from typing import Tuple

import click

import typed_settings as ts
from typed_settings.cli_click import OptionGroupFactory


@ts.settings
class Coverage:
    """
    Coverage settings
    """

    src: str = ts.option(default="", click={"param_decls": ("--cov", "src")})
    report: str = ""


@ts.settings
class Emoji:
    """
    Emoji settings
    """

    enable: bool = True


@ts.settings
class Base:
    """
    Main settings
    """

    marker: str = ts.option(
        default="",
        help="only run tests which macht the given substring expression",
        click={"param_decls": ("-m",)},
    )
    exitfirst: bool = ts.option(
        default=False,
        help="Exit instantly on first error or failed test",
        click={"param_decls": ("--exitfirst", "-x"), "is_flag": True},
    )
    stepwise: bool = ts.option(
        default=False,
        help=("Exit on test failure and continue from last failing test next " "time"),
        click={"param_decls": ("--stepwise", "--sw"), "is_flag": True},
    )


Settings = ts.combine(
    "Settings",
    Base,
    {
        # Imagine, this dict comes from a "load_plugins()" function :)
        "cov": Coverage(),
        "emoji": Emoji(),
    },
)


@click.command()
@click.argument("file_or_dir", nargs=-1)
@ts.click_options(Settings, "pytest", decorator_factory=OptionGroupFactory())
def cli(
    settings: Settings,  # type: ignore[valid-type]
    file_or_dir: Tuple[str, ...],
):
    print(settings)


if __name__ == "__main__":
    cli()
❯ python pytest.py --help
Traceback (most recent call last):
  File "/home/tobia/mambaforge/envs/pytask/lib/python3.12/site-packages/typed_settings/cli_utils.py", line 431, in get_default
    default = converter.structure(default, option_info.cls)
              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/tobia/mambaforge/envs/pytask/lib/python3.12/site-packages/cattrs/converters.py", line 332, in structure
    return self._structure_func.dispatch(cl)(obj, cl)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/tobia/mambaforge/envs/pytask/lib/python3.12/site-packages/cattrs/fns.py", line 17, in raise_error
    raise StructureHandlerNotFoundError(msg, type_=cl)
cattrs.errors.StructureHandlerNotFoundError: Unsupported type: 'bool'. Register a structure hook for it.

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/home/tobia/git/pytask/prog2.py", line 66, in <module>
    @ts.click_options(Settings, "pytest", decorator_factory=OptionGroupFactory())
     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/tobia/mambaforge/envs/pytask/lib/python3.12/site-packages/typed_settings/cli_click.py", line 258, in wrap
    default = get_default(oinfo, merged_settings, state.converter)
              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/tobia/mambaforge/envs/pytask/lib/python3.12/site-packages/typed_settings/cli_utils.py", line 433, in get_default
    raise ValueError(
ValueError: Invalid default for type bool: False

I believe the forward references from Base are unresolved, which is why the unsupported type is a string 'bool'.