I am trying to create a typealias for all the types that can be passed as the first argument of open(). MyPy reveals the type to be Union[builtins.str, builtins.bytes, builtins.int, builtins._PathLike[Any]].
My first attempt at this is:
Openable = Union[str, bytes, int, os.PathLike[Any]]
MyPy is happy with this, but alas Python is not:
TypeError: 'ABCMeta' object is not subscriptable
Trying this, then:
Openable = Union[str, bytes, int, os.PathLike]
But now MyPy is unhappy:
error: Missing type parameters for generic type
What is the correct way of using os.PathLike here? There is no typing.PathLike yet. Do I have to create my own generic version of os.PathLike?
I think the fix is to quote the type so that it is not evaluated at runtime:
Openable = Union[str, bytes, int, 'os.PathLike[Any]']
Another solution is to use if TYPE_CHECKING: ....
This problem appeared several times. It would be great to create a documentation entry about this.
Oh of course, how could I have forgotten about the string version of annotations!?
+1 to a mention in documentation
Another example is when the class that is generic in typeshed is not generic at runtime appears as a base class. This case is even more important, since one can't use quotes and if TYPE_CHECKING: ... is the only way.
Most helpful comment
I think the fix is to quote the type so that it is not evaluated at runtime: