Unfortunately, mypy, and the Python typing ecosystem, currently doesn't support recursive types.
You can find the issue for it here: https://github.com/python/mypy/issues/731 (though you should ignore some of the posts in the middle because they were posted by people who ended up having an unrelated issue).
The main blocker in the thread (e.g. "we should implement structural subtyping first") is under active development and hopefully should become a part of at least mypy in the next few months, so perhaps it might be worth reviving the discussion.
The current workaround many people tend to use (especially when trying to type JSON, which your types resemble) is to manually expand the recursive type to the desired level and eventually bottom out with Any
. For example:
from typing import Union, Dict, List, Any
KRPCTypes = Union[int, bytes, list, Dict[bytes, Union[int, bytes, list, Any]]]
KRPCDict = Dict[bytes, KRPCTypes]
Incidentally, you may want to use typing.List[T]
and specify what type the list is supposed to contain -- if you do just list
, it defaults to typing.List[Any]
, which is less precise then it could be.
An alternate approach may be to use the experimental TypedDict
type, which lets you define the exact types and structure of a given dictionary. This is less useful in that TypedDict can't represent every single kind of KRPCDict
, but does come in handy if you expect to handle only a finite number of different kinds of KRPCDict
types.
There's no documentation regarding TypedDict
yet (the devs want to work out all the major bugs first before publicizing it), but if you want to try tinkering with it, I wrote an example of how you would use it at the bottom of this (largely unrelated) answer.