To add some more input about forward references, here are couple of thoughts:

1. I think ideally we should support forward references to the same extent they are currently supported:
i.e. Union[None, "ForwardRef"], Union["OtherForwardRef", None], and Union["ForwardRef", "OtherForwardRef"]
should all be supported. The last one looks the hardest, in the sense that it looks like we will need
to add `str.__or__()` to support these forms.

2. Forward references to type variables were never supported and we shouldn't start supporting this
(even if it accidentally worked in some situations). Type variables should always be defined before use.
So I think we should not worry about point 3 in Richard's e-mail.

Philippe, I think it makes sense to reflect these points to the PEP draft.


On Thu, 14 Nov 2019 at 02:23, Richard Eames <> wrote:
Thanks for the encouragement!

I've been working some more on it since I had some more free cycles in the last few days and I think I've got to the limit of my capabilities. I think I've got it to a point where it needs more eyes because my experience level writing code in the python interpreter is pretty low, so I know that I have holes in there, especially around using INCREF/DECREF.
I'm currently stuck on 3 things:

1. repr( pickle.loads( pickle.dumps(int | str) ) ) causes an infinite recursion that I can't figure out. I might end up re-specializing `repr()` again since it isn't defined in the PEP.

- `None | "forwardref"` and `None | None`
- `"forwardref" | None` and `"forwardRefA" | "forwardRefB"`
I've had a go at adding a `type.__ror__` as suggested by GvR, but I think I'm missing something.

3. type parameters
- I'm not sure how to handle this:
MaybeT = None | "T" # creates shadow union
T = TypeVar('T')
maybe_int = MaybeT[int] # should this stay in shadow land, or go back to
isinstance(1, maybe_int)
isinstance(1, MaybeT[int])
I have a couple options for this:
- implement the type substitution in c; which can be done, but feels like overkill?
- store the type parameters on the shadow object and vivify when needed (which will end up being in the isinstance call)
- implement the __getitem__ as a call into the library and promote as it's requested. This is how I've currently implemented it.

I'm happy to keep going on this if/when needed,

Python-Dev mailing list --
To unsubscribe send an email to
Message archived at
Code of Conduct: