Mark Shannon pointed out a problem with recursive types:
from typing import D
D = Dict[str, 'D']
assert isinstance({}, D) # OK
assert isinstance({'':{}}, D) # Fails
This is because _ForwardRef doesn't defines __instancecheck__ or __subclasscheck__, so it inherits default implementations that always return False. I can fix this (though a clever programmer might lure isinstance() into an infinite loop by making a recursive _value_ -- that's fixable too but I'm not sure I care).
Do we have real-world use cases for recursive types?
I'm not sure -- I think you could model a tree this way if you really didn't want to define a class. It's probably just a classic test case for type systems. ("Can it represent recursive types? if not, it's an automatic reject." :-) FWIW I'm running into some issues implementing this; there is some code somewhere that seems to depend on _ForwardRef's instance check returning False at some point where the names used in the expression aren't defined yet. My work-around is a bit ugly.
What direction did you take regarding this issue? Have recursive types been discussed after this?
A real world usecase would be modeling JSON serialization, like below.
from __future__ import annotations
from typing import Dict, Union
from typing_extensions import Protocol
JSONSerializableDict = Dict[
Union[str, int], Union[str, float, int, bool, JSONSerializableDict]]
class JSONSerializableImplementation(Protocol):
def json_serializable(self) -> Union[
JSONSerializableDict, JSONSerializableImplementation]:
pass
JSONSerializable = Union[JSONSerializableDict, JSONSerializableImplementation]
(Obviously this example isn't accurate, but I hope you understand the usage)
We are working on this.
https://github.com/python/mypy/issues/731#issuecomment-587795867
@ir4y There are only sad updates: I am no longer working on this, and likely will not work on this in foreseeable future. You can try pushing it yourself, but it is not an easy task, and I can't guide you, sorry (others may still have time for this).
Most helpful comment
We are working on this.