On Thu, Sep 05, 2019 at 05:41:50PM -0700, Andrew Barnert wrote:
Are runtime union types actually types, unlike the things in typing, or are they still non-type values that just have special handling as the second argument of isinstance and issubclass and maybe except statements?
Union, and unions, are currently types: py> isinstance(Union, type) True py> isinstance(Union[int, str], type) True and I don't think that should change. I don't think you should be able to instantiate a Union (that's the current behaviour too). A Union of two types is not the same as inheriting from both types.
I’d expect issubclass(int|str, int|str|bytes) to be true, and issubclass(int|str, int) to be false, not for both of them to raise exceptions about the first argument not being a type.
Currently, issubclass accepts unions without raising, and that shouldn't change either. But I disagree that int|str is a subclass of int|str|bytes. There's no subclass relationship between the two: the (int|str).__bases__ won't include (int|str|bytes), and instances of int|str don't inherit from all three of int, str, bytes. Currently unions inherit from typing.Final, and that *may* change, but it surely won't change in such a way that Union[str|int] is equivalent to ``class Str_Int(str, int)``.
While we’re at it:
issubclass(int|str, types.UnionType)
I think this should be false
I have no opinion on that one :-)
Finally, do we still need the existing Generic, typing.Union, at all?
typing.Union will probably just become an alias to the (proposed) built-in types.Union. However, backwards compatibility requires that Union[int, str] is still supported, even if int|str is prefered. -- Steven