When use match-case pattern, I found that case typing.BinaryIO():
can not match object with type io.BytesIO
.
So I try this:
import io
import typing
assert issubclass(list, typing.Sequence)
assert issubclass(list, typing.List)
assert issubclass(dict, typing.Mapping)
assert issubclass(dict, typing.Dict)
# assert issubclass(io.StringIO, typing.TextIO) # failed!
# assert issubclass(io.BytesIO, typing.BinaryIO) # failed!
a = [1, 2, 3]
b = {"a": 1, "b": 2, "c": 3}
c = io.BytesIO(b"123123123")
d = io.StringIO("123123123")
assert isinstance(a, typing.List)
assert isinstance(a, typing.Sequence)
assert isinstance(b, typing.Dict)
assert isinstance(b, typing.Mapping)
# assert isinstance(c, typing.BinaryIO) # failed!
# assert isinstance(d, typing.TextIO) # failed!
It shows that io.BytesIO
and io.StringIO
are not subclass of typing.BinaryIO
and typing.TextIO
, which in my opinion is strange since official documents never hint me to be carefule about this behaviour (or at least I never found it).
What is more strange is a .pyi
stub file i found, its path is /data/users/XXXXXX/.vscode-server/extensions/ms-python.vscode-pylance-2024.11.1/dist/typeshed-fallback/stdlib/_io.pyi
.
I found this line in the stub file: class BytesIO(BufferedIOBase, _BufferedIOBase, BinaryIO):
, which implies that things should be as they should be for my intuition.
Is this intentional design or a bug? If is a design, why?
I'm using Python 3.12.3
with mypy 1.13.0
, under VSCode 1.93.1
with pylance 2024.11.1
extension.
Classes in the typing
module are not meant to be used for instance / subclass checks at runtime. Their purpose is type hinting.
If you want to use instance / subclass checks like that, check out collections.abc
, especially this overview. For io.StringIO
and io.BytesIO
, their abstract base classes are io.TextIOBase
and io.BufferedIOBase
. Their common base class is io.IOBase
.