On 2019-11-17 20:09, Ivan Levkivskyi wrote:
To add some more input about forward references, here are couple of thoughts:
- 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.
I'm not sure I like the thought of adding `str.__or__()` because it would mean that "Foo" | "Bar" becomes valid and returns a type, which is unexpected.
Perhaps an alternative would be to add 'Forward' to make it explicit:
Forward("ForwardRef") | Forward("OtherForwardRef")
Forward("ForwardRef") | "OtherForwardRef"
- 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 <firstname.lastname@example.org mailto:email@example.com> 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. 2. - `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 typing.py 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 typing.py 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,