classification
Title: More differences in instance and subclass checks between typing.Union and types.Union
Type: behavior Stage:
Components: Library (Lib) Versions: Python 3.11, Python 3.10
process
Status: open Resolution:
Dependencies: Superseder:
Assigned To: Nosy List: gvanrossum, kj, serhiy.storchaka
Priority: normal Keywords:

Created on 2021-07-18 17:21 by serhiy.storchaka, last changed 2021-07-19 17:57 by gvanrossum.

Messages (4)
msg397757 - (view) Author: Serhiy Storchaka (serhiy.storchaka) * (Python committer) Date: 2021-07-18 17:21
1. Checks for types.Union ignore any non-type args. Checks for typing.Union require fail on first checked non-type (but it can short circuit).

>>> import typing
>>> T = typing.TypeVar('T')
>>> issubclass(int, int | T | str)
True
>>> issubclass(int, str | T | int)
True
>>> issubclass(int, typing.Union[int, T, str])
True
>>> issubclass(int, typing.Union[str, T, int])
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/home/serhiy/py/cpython/Lib/typing.py", line 1208, in __subclasscheck__
    if issubclass(cls, arg):
       ^^^^^^^^^^^^^^^^^^^^
TypeError: issubclass() arg 2 must be a class, a tuple of classes, or a union.
>>> isinstance(1, int | T | str)
True
>>> isinstance(1, str | T | int)
True
>>> isinstance(1, typing.Union[int, T, str])
True
>>> isinstance(1, typing.Union[str, T, int])
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/home/serhiy/py/cpython/Lib/typing.py", line 1204, in __instancecheck__
    return self.__subclasscheck__(type(obj))
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/serhiy/py/cpython/Lib/typing.py", line 1208, in __subclasscheck__
    if issubclass(cls, arg):
       ^^^^^^^^^^^^^^^^^^^^
TypeError: issubclass() arg 2 must be a class, a tuple of classes, or a union.

2. __instancecheck__ of typing.Union uses __subclasscheck__ of args instead of __instancecheck__. In normal cases the result should be the same, but there should be a reason of having two different special methods.
msg397775 - (view) Author: Guido van Rossum (gvanrossum) * (Python committer) Date: 2021-07-19 01:05
This seems a low-priority issue to me. The code is invalid, but I don't think it's very important to raise an exception (typing.Union is also inconsistent). Static type checkers will flag all these as errors. (Or perhaps none of them? It may depend on the meaning of T in the current scope.)
msg397778 - (view) Author: Serhiy Storchaka (serhiy.storchaka) * (Python committer) Date: 2021-07-19 06:02
It is easy to fix once we define the correct behavior in corner cases.
msg397823 - (view) Author: Guido van Rossum (gvanrossum) * (Python committer) Date: 2021-07-19 17:57
Sure.
History
Date User Action Args
2021-07-19 17:57:02gvanrossumsetmessages: + msg397823
2021-07-19 06:02:17serhiy.storchakasetmessages: + msg397778
2021-07-19 01:05:10gvanrossumsetmessages: + msg397775
2021-07-18 17:21:45serhiy.storchakasettype: behavior
components: + Library (Lib)
versions: + Python 3.10, Python 3.11
2021-07-18 17:21:30serhiy.storchakacreate