Skip to content

Forward references are not supported #16

@azmeuk

Description

@azmeuk

Hello
I know the readme file indicates that the project is not mature/active enough for contributions to be pertinent, but I was testing the library and found issues anyways, so I thought it would be a shame to keep them for me :)

With two cross-referenced model, one needs to use PEP484 forward references, but that seems to not work at the moment.

This would fail either by using argname: "Ref" or argname: list["Ref"]:

Direct forward reference

from pydantic import BaseModel
from clidantic import Parser


class Foo(BaseModel):
    dummy: str | None
    ref: "Bar"


class Bar(BaseModel):
    dummy: str | None
    ref: "Foo"


cli = Parser()


@cli.command()
def command(args: Foo):
    print(args)

if __name__ == "__main__":
    cli()
Traceback (most recent call last):
  File "/home/eloi/test/test2.py", line 18, in <module>
    @cli.command()
     ^^^^^^^^^^^^^
  File "/home/eloi/.virtualenvs/test-cxcd/lib/python3.12/site-packages/clidantic/core.py", line 154, in decorator
    params = list(settings_to_options(cfg_class, delimiter, internal_delimiter))
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/eloi/.virtualenvs/test-cxcd/lib/python3.12/site-packages/clidantic/convert.py", line 115, in settings_to_options
    yield PydanticOption.from_field(field, params)
          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/eloi/.virtualenvs/test-cxcd/lib/python3.12/site-packages/clidantic/convert.py", line 30, in from_field
    return cls(
           ^^^^
  File "/home/eloi/.virtualenvs/test-cxcd/lib/python3.12/site-packages/clidantic/convert.py", line 16, in __init__
    super().__init__(*args, **kwargs, callback=allow_if_specified)
  File "/home/eloi/.virtualenvs/test-cxcd/lib/python3.12/site-packages/click/core.py", line 2536, in __init__
    super().__init__(param_decls, type=type, multiple=multiple, **attrs)
  File "/home/eloi/.virtualenvs/test-cxcd/lib/python3.12/site-packages/click/core.py", line 2114, in __init__
    self.type: types.ParamType = types.convert_type(type, default)
                                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/eloi/.virtualenvs/test-cxcd/lib/python3.12/site-packages/click/types.py", line 1056, in convert_type
    return FuncParamType(ty)
           ^^^^^^^^^^^^^^^^^
  File "/home/eloi/.virtualenvs/test-cxcd/lib/python3.12/site-packages/click/types.py", line 166, in __init__
    self.name: str = func.__name__
                     ^^^^^^^^^^^^^
AttributeError: 'ForwardRef' object has no attribute '__name__'. Did you mean: '__ne__'?

Forward reference in a list

from pydantic import BaseModel
from clidantic import Parser


class Foo(BaseModel):
    dummy: str | None
    ref: list["Bar"]


class Bar(BaseModel):
    dummy: str | None
    ref: list["Foo"]


cli = Parser()


@cli.command()
def command(args: Foo):
    print(args)

if __name__ == "__main__":
    cli()
Traceback (most recent call last):
  File "/home/eloi/test/test2.py", line 18, in <module>
    @cli.command()
     ^^^^^^^^^^^^^
  File "/home/eloi/.virtualenvs/test-cxcd/lib/python3.12/site-packages/clidantic/core.py", line 154, in decorator
    params = list(settings_to_options(cfg_class, delimiter, internal_delimiter))
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/eloi/.virtualenvs/test-cxcd/lib/python3.12/site-packages/clidantic/convert.py", line 115, in settings_to_options
    yield PydanticOption.from_field(field, params)
          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/eloi/.virtualenvs/test-cxcd/lib/python3.12/site-packages/clidantic/convert.py", line 26, in from_field
    click_type = parse_type(field.outer_type_)
                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/eloi/.virtualenvs/test-cxcd/lib/python3.12/site-packages/clidantic/click.py", line 51, in parse_type
    return parse_container_args(field_type)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/eloi/.virtualenvs/test-cxcd/lib/python3.12/site-packages/clidantic/click.py", line 221, in parse_container_args
    return parse_single_arg(args[0])
           ^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/eloi/.virtualenvs/test-cxcd/lib/python3.12/site-packages/clidantic/click.py", line 245, in parse_single_arg
    if is_container(arg) or issubclass(arg, BaseModel):
                            ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "<frozen abc>", line 123, in __subclasscheck__
TypeError: issubclass() arg 1 must be a class

Desktop (please complete the following information):

  • OS: Archlinux
  • Python Version 3.12.2
  • pip freeze
click==8.1.7
clidantic==0.1.0
pydantic==1.10.14
Pygments==2.17.2
typing_extensions==4.10.0

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions