Skip to content

Merge stdlib/{2,3}/os/path.pyi #1150

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

Merged
merged 2 commits into from
Apr 10, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 29 additions & 16 deletions stdlib/2/os/path.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,14 @@

# based on http://docs.python.org/3.2/library/os.path.html
# adapted for 2.7 by Michal Pokorny
import sys
from typing import (
overload, List, Any, AnyStr, Sequence, Tuple, BinaryIO, TextIO,
TypeVar, Union, Text, Callable
)

from typing import overload, List, Any, Tuple, BinaryIO, TextIO, TypeVar, Callable, AnyStr
_T = TypeVar('_T')
_PathType = Union[bytes, Text]

# ----- os.path variables -----
supports_unicode_filenames = False
Expand All @@ -22,25 +28,32 @@ devnull = ... # type: str
def abspath(path: AnyStr) -> AnyStr: ...
def basename(path: AnyStr) -> AnyStr: ...

def commonprefix(list: List[AnyStr]) -> AnyStr: ...
if sys.version_info >= (3, 5):
def commonpath(paths: Sequence[AnyStr]) -> AnyStr: ...

# NOTE: Empty lists results in '' (str) regardless of contained type.
# Also, in Python 2 mixed sequences of Text and bytes results in either Text or bytes
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This type signature won't allow mixed lists, right? A Sequence[Union[bytes, Text]] is not a Sequence[AnyStr].

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sequence[AnyStr] works in python 2 because str gets promoted to Text

And sadly I can't overload where the argument varies by what's inside the Sequence.
Basically if I do in Python 2:

@overload
def commonprefix(list: Sequence[str]) -> str: ...
@overload
def commonprefix(list: Sequence[Text]) -> Any: ...

I get this error:
error: Overloaded function signatures 1 and 2 overlap with incompatible return types

It doesn't work with List[X] or with Sequence[bytes] in python 3. I even tried introducing a _Str = TypeVar("_Str", str) and separating using that, but that doesn't work either.

So I opted for the most generic thing.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh right, I forgot about that promotion. Seems like this is the best we can do then. Thanks for explaining!

# So, fall back to Any
def commonprefix(list: Sequence[AnyStr]) -> Any: ...

def dirname(path: AnyStr) -> AnyStr: ...
def exists(path: unicode) -> bool: ...
def lexists(path: unicode) -> bool: ...
def exists(path: _PathType) -> bool: ...
def lexists(path: _PathType) -> bool: ...
def expanduser(path: AnyStr) -> AnyStr: ...
def expandvars(path: AnyStr) -> AnyStr: ...

# These return float if os.stat_float_times() == True,
# but int is a subclass of float.
def getatime(path: unicode) -> float: ...
def getmtime(path: unicode) -> float: ...
def getctime(path: unicode) -> float: ...
def getatime(path: _PathType) -> float: ...
def getmtime(path: _PathType) -> float: ...
def getctime(path: _PathType) -> float: ...

def getsize(path: unicode) -> int: ...
def isabs(path: unicode) -> bool: ...
def isfile(path: unicode) -> bool: ...
def isdir(path: unicode) -> bool: ...
def islink(path: unicode) -> bool: ...
def ismount(path: unicode) -> bool: ...
def getsize(path: _PathType) -> int: ...
def isabs(path: _PathType) -> bool: ...
def isfile(path: _PathType) -> bool: ...
def isdir(path: _PathType) -> bool: ...
def islink(path: _PathType) -> bool: ...
def ismount(path: _PathType) -> bool: ...

def join(path: AnyStr, *paths: AnyStr) -> AnyStr: ...

Expand All @@ -49,7 +62,7 @@ def normpath(path: AnyStr) -> AnyStr: ...
def realpath(path: AnyStr) -> AnyStr: ...
def relpath(path: AnyStr, start: AnyStr = ...) -> AnyStr: ...

def samefile(path1: unicode, path2: unicode) -> bool: ...
def samefile(path1: _PathType, path2: _PathType) -> bool: ...
def sameopenfile(fp1: int, fp2: int) -> bool: ...
# TODO
# def samestat(stat1: stat_result,
Expand All @@ -61,5 +74,5 @@ def splitext(path: AnyStr) -> Tuple[AnyStr, AnyStr]: ...

def splitunc(path: AnyStr) -> Tuple[AnyStr, AnyStr]: ... # Windows only, deprecated

_T = TypeVar('_T')
def walk(path: AnyStr, visit: Callable[[_T, AnyStr, List[AnyStr]], Any], arg: _T) -> None: ...
if sys.version_info < (3,):
def walk(path: AnyStr, visit: Callable[[_T, AnyStr, List[AnyStr]], Any], arg: _T) -> None: ...
51 changes: 32 additions & 19 deletions stdlib/3/os/path.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,15 @@
# Ron Murawski <[email protected]>

# based on http://docs.python.org/3.2/library/os.path.html

# adapted for 2.7 by Michal Pokorny
import sys
from typing import overload, List, Any, AnyStr, Sequence, Tuple, BinaryIO, TextIO
from typing import (
overload, List, Any, AnyStr, Sequence, Tuple, BinaryIO, TextIO,
TypeVar, Union, Text, Callable
)

_T = TypeVar('_T')
_PathType = Union[bytes, Text]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

or os.PathLike

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll look at that.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looked into this I think it need more work. PathLike is 3.6 only and I imagine some methods support it. But I'm not sure this is the change to work on that.


# ----- os.path variables -----
supports_unicode_filenames = False
Expand All @@ -25,26 +31,29 @@ def basename(path: AnyStr) -> AnyStr: ...
if sys.version_info >= (3, 5):
def commonpath(paths: Sequence[AnyStr]) -> AnyStr: ...

# NOTE: Empty List[bytes] results in '' (str) => fall back to Any return type.
def commonprefix(list: List[AnyStr]) -> Any: ...
# NOTE: Empty lists results in '' (str) regardless of contained type.
# Also, in Python 2 mixed sequences of Text and bytes results in either Text or bytes
# So, fall back to Any
def commonprefix(list: Sequence[AnyStr]) -> Any: ...

def dirname(path: AnyStr) -> AnyStr: ...
def exists(path: AnyStr) -> bool: ...
def lexists(path: AnyStr) -> bool: ...
def exists(path: _PathType) -> bool: ...
def lexists(path: _PathType) -> bool: ...
def expanduser(path: AnyStr) -> AnyStr: ...
def expandvars(path: AnyStr) -> AnyStr: ...

# These return float if os.stat_float_times() == True,
# but int is a subclass of float.
def getatime(path: _PathType) -> float: ...
def getmtime(path: _PathType) -> float: ...
def getctime(path: _PathType) -> float: ...

# These return float if os.stat_float_times() == True
def getatime(path: AnyStr) -> Any: ...
def getmtime(path: AnyStr) -> Any: ...
def getctime(path: AnyStr) -> Any: ...

def getsize(path: AnyStr) -> int: ...
def isabs(path: AnyStr) -> bool: ...
def isfile(path: AnyStr) -> bool: ...
def isdir(path: AnyStr) -> bool: ...
def islink(path: AnyStr) -> bool: ...
def ismount(path: AnyStr) -> bool: ...
def getsize(path: _PathType) -> int: ...
def isabs(path: _PathType) -> bool: ...
def isfile(path: _PathType) -> bool: ...
def isdir(path: _PathType) -> bool: ...
def islink(path: _PathType) -> bool: ...
def ismount(path: _PathType) -> bool: ...

def join(path: AnyStr, *paths: AnyStr) -> AnyStr: ...

Expand All @@ -53,13 +62,17 @@ def normpath(path: AnyStr) -> AnyStr: ...
def realpath(path: AnyStr) -> AnyStr: ...
def relpath(path: AnyStr, start: AnyStr = ...) -> AnyStr: ...

def samefile(path1: AnyStr, path2: AnyStr) -> bool: ...
def samefile(path1: _PathType, path2: _PathType) -> bool: ...
def sameopenfile(fp1: int, fp2: int) -> bool: ...
# TODO
# def samestat(stat1: stat_result,
# stat2: stat_result) -> bool: ... # Unix only

def split(path: AnyStr) -> Tuple[AnyStr, AnyStr]: ...
def splitdrive(path: AnyStr) -> Tuple[AnyStr, AnyStr]: ...
def splitext(path: AnyStr) -> Tuple[AnyStr, AnyStr]: ...

# def splitunc(path: str) -> Tuple[str, str]: ... # Windows only, deprecated
def splitunc(path: AnyStr) -> Tuple[AnyStr, AnyStr]: ... # Windows only, deprecated

if sys.version_info < (3,):
def walk(path: AnyStr, visit: Callable[[_T, AnyStr, List[AnyStr]], Any], arg: _T) -> None: ...