7

I have an alias for a type in Python:

from typing import Tuple, Dict, Union

SelectedModelArgs = Dict[
    str,
    Union[
        str,
        float,
        Tuple[float, float],
        Dict[str, Union[str, float, Tuple[float, float]]],
    ],
]

At present this allows for a dictionary with str to str, float, a tuple of floats or a nested dictionary of the same type. Is there a way to define this recursively to allow arbitrary nesting?

e.g.

SelectedModelArgs = Dict[
    str,
    Union[
        str,
        float,
        Tuple[float, float],
        SelectedModelArgs,
    ],
]

When I try this I get IDE errors:

  • Pylance: "SelectedModelArgs" is not defined
  • Mypy: Cannot resolve now "SelectedModelArgs" (possible cyclic definition)

Adding from __future__ import annotations to the top of the file does not resolve these (as it does with using a class name within a class definition).

I have also tried using the code example above but with the nested "SelectedModelArgs" as a string (as noted in this answer). This resolves the pylance error, but not the mypy error.

buhtz
  • 10,774
  • 18
  • 76
  • 149
ChrisProsser
  • 12,598
  • 6
  • 35
  • 44
  • 1
    The immediate issue is that the definition is an ordinary Python assignment, not an annotation, with an expression that depends on calls to `type.__get_class_item__`. Like any other expression, you can't use the name `SelectedModelArgs` on the right if it hasn't been defined yet. – chepner Jul 21 '22 at 14:14
  • 2
    Assuming you can get the definition, *then* you run into the next problem of `mypy` not handling recursive type definitions (yet). – chepner Jul 21 '22 at 14:14
  • [very similar question](https://stackoverflow.com/q/58377361/5986907) – joel Jul 21 '22 at 17:07
  • Thanks @joe, yes those questions are pretty similar. Assuming nothing has changed it looks like mypy still doesn't support this. – ChrisProsser Jul 22 '22 at 09:08

0 Answers0