dict-typer icon indicating copy to clipboard operation
dict-typer copied to clipboard

Fix max recursion error

Open ikornaselur opened this issue 4 years ago • 0 comments

This "fixes" the issue of having recursive types, such as

{
    "foo": {
        "bar": {
            "foo": 10
        }
    }
}

which resulted in max recursion error. Now it produces code successfully:

-> % echo '{"foo": {"bar": {"foo": 10}}}' | poetry run dict-typer
from typing import Union

from typing_extensions import TypedDict


class Foo(TypedDict):
    bar: Bar


class Bar(TypedDict):
    foo: Union[Foo, int]

But, unfortunately, recursive types are not supported by mypy, giving the following error

[mypy error] [E] Cannot resolve name "Bar" (possible cyclic definition)

I'm not entirely sure what's the best way to support this. A minimal example of the issue would be

X = Union[int, List[X]]

which is valid for list of ints and nested lists of the same type, but this isn't supported by mypy. Currently dict-typer will handle the input [1, [1]] as

-> % echo '[1, [1]]' | poetry run dict-typer
from typing import List, Union


Root = List[Union[List[int], int]]

which is.. valid, it's a list of either int or list of int. It's more explicit (plus the rule might be in this case that there can only be one level down nested ints).

Wondering if some handling like that would be required here? I guess the example from above could be

-> % echo '{"foo": {"bar": {"foo": 10}}}' | poetry run dict-typer
from typing import Union

from typing_extensions import TypedDict

class Bar(TypedDict):
    foo: int

class Foo(TypedDict):
    bar: Bar

class Root(TypedDict):   # "Bar1" if not "Root"
    foo: Bar

but that will likely require some refactoring, as I try to discover and combine the typed dicts based on the keys.

TODO

One of the fixes involved changing the depends_on functionality for ordering of the definitions, which unfortunately seems to have broken one of the snapshot tests.

ikornaselur avatar Jun 23 '20 12:06 ikornaselur