Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
44 changes: 28 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,31 @@ 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: ...
if sys.version_info >= (3,):
# NOTE: Empty List[bytes] results in '' (str) => fall back to Any return type.
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

We could handle this with an overload instead.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Is there a way to describe the type of an empty list?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

You're right, we can't.

def commonprefix(list: List[AnyStr]) -> Any: ...
else:
def commonprefix(list: List[AnyStr]) -> AnyStr: ...
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Mixed lists actually work fine:

In [4]: os.path.commonprefix([u'hello', b'hello'])
Out[4]: u'hello'

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Looking at the python2 version (because python3 does not let you mix types) it looks like the return type is the type of the min element of the list, https://github.com/python/cpython/blob/2.7/Lib/genericpath.py#L76

So maybe I can do an overload like this:

@overload
def commonprefix(list: List[AnyStr]) -> AnyStr: ...
@overload
def commonprefix(list: List[Union[bytes], Union[Text]]) -> Union[bytes, Text]

But then you have the dreaded Union in a return value.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Do you mean List[Union[bytes, Text]] in the second overload?

I think we can just do def commonprefix(list: Sequence[Union[bytes, Text]]) -> Any: ... (not a List so we don't get hit by invariance).

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Ah I didn't want to use Sequence[Union[bytes, Text]] because in python3 it's not supported.

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 +61,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 +73,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: ...
52 changes: 32 additions & 20 deletions stdlib/3/os/path.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,15 @@
# Ron Murawski <ron@horizonchess.com>

# 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
Copy Markdown
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
Copy Markdown
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
Copy Markdown
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 @@ -24,27 +30,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: ...
if sys.version_info >= (3,):
# NOTE: Empty List[bytes] results in '' (str) => fall back to Any return type.
def commonprefix(list: List[AnyStr]) -> Any: ...
else:
def commonprefix(list: List[AnyStr]) -> AnyStr: ...
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 +61,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: ...