Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Mypy: DictComponentsType["_help"] is not expressed in type declaration #626

Open
netanel-haber opened this issue Nov 18, 2024 · 4 comments
Labels
bug Something isn't working

Comments

@netanel-haber
Copy link

netanel-haber commented Nov 18, 2024

🐛 Bug report

The type for DictComponentsType doesn't allow the "_help": str entry:

ComponentType = Union[Callable, Type]
DictComponentsType = Dict[str, Union[ComponentType, "DictComponentsType"]]

To reproduce

from jsonargparse import CLI
CLI({"something": {"_help": "Help"}})
> python -m mypy .
...error: Dict entry 0 has incompatible type "str": "str"; expected "str": "Callable[..., Any] | type[Any] | DictComponentsType"
@netanel-haber netanel-haber added the bug Something isn't working label Nov 18, 2024
@mauvilsa
Copy link
Member

Thank you for reporting! Would you be interested in contributing the fix?

@netanel-haber
Copy link
Author

Sure, I'll do so tomorrow

@netanel-haber
Copy link
Author

netanel-haber commented Nov 19, 2024

Well, I took a look:

I think adding support for strictly Lireral["_help"]: str to the typing is currently literally impossible in the python typing realm [maybe if and when pep728 is accepted].

We can allow arbitrary string keys at all but the top level, and just asserting at runtime that only literally _help was passed for str: str entries, e.g.:

from typing import Union, Callable, Type, Dict

ComponentType = Union[Callable, Type]
WithStr = Union[ComponentType, str]
NestedComponentsType = Dict[str, Union[WithStr, "NestedComponentsType"]]
DictComponentsType = Dict[str, Union[ComponentType, NestedComponentsType]]

def tryme(components: DictComponentsType) -> None:
    print(components)
    
tryme({
    "A": {
        "B": "C", # mypy will allow any `str: str`
        "D": lambda: "E"
    }
    #, "F": "G" # mypy throws at top level as expected
})

That will stop mypy from complaining, at the cost of more complex typing, and possible errors that will only be discovered at runtime (non _help entries). I lean against typing improvements if it can incur a runtime penalty.

WDYT? I lean towards "won't fix".

@mauvilsa
Copy link
Member

Yes, tricky. I think better to not change anything until there is a more clean way to do it. A bit unfortunate. I did not think about this when I added the _help option.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants