Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

os.PathLike should be a protocol #2808

Closed
catern opened this issue Feb 21, 2019 · 3 comments
Closed

os.PathLike should be a protocol #2808

catern opened this issue Feb 21, 2019 · 3 comments

Comments

@catern
Copy link

catern commented Feb 21, 2019

os.PathLike is a special class which overrides __subclasshook__ so that isinstance(x, os.PathLike) returns true if x has an __fspath__ method.

To achieve equivalent behavior when typechecking, os.PathLike should be treated as a protocol.

@srittau
Copy link
Collaborator

srittau commented Feb 22, 2019

Interesting idea. Could you provide a PR so that we can explore this approach and see whether it causes any problems?

@bluetech
Copy link
Contributor

I also think it makes sense, os.PathLike is exactly the use case for Protocols IMO.

I tried this patch:

diff --git a/stdlib/2and3/builtins.pyi b/stdlib/2and3/builtins.pyi
index 63b3b04d..6c721d02 100644
--- a/stdlib/2and3/builtins.pyi
+++ b/stdlib/2and3/builtins.pyi
@@ -7,7 +7,7 @@ from typing import (
     Set, AbstractSet, FrozenSet, MutableSet, Sized, Reversible, SupportsInt, SupportsFloat, SupportsAbs,
     SupportsComplex, IO, BinaryIO, Union,
     ItemsView, KeysView, ValuesView, ByteString, Optional, AnyStr, Type, Text,
-    Protocol,
+    Protocol, runtime_checkable
 )
 from abc import abstractmethod, ABCMeta
 from ast import mod, AST
@@ -1153,7 +1153,8 @@ if sys.version_info >= (3, 6):
     # This class is to be exported as PathLike from os,
     # but we define it here as _PathLike to avoid import cycle issues.
     # See https://github.com/python/typeshed/pull/991#issuecomment-288160993
-    class _PathLike(Generic[AnyStr]):
+    @runtime_checkable
+    class _PathLike(Protocol, Generic[AnyStr]):
         def __fspath__(self) -> AnyStr: ...
     def compile(source: Union[str, bytes, mod, AST], filename: Union[str, bytes, _PathLike[Any]], mode: str, flags: int = ..., dont_inherit: int = ..., optimize: int = ...)>
 elif sys.version_info >= (3,):

but this seems not possible as is:

error: Invariant type variable 'AnyStr' used in protocol where covariant one is expected

@hauntsaninja
Copy link
Collaborator

I changed this in #4447

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants