Skip to content

Commit 803b32a

Browse files
committed
make python 2 and 3 os stubs identical
In preparation for merging. I avoided making other changes to the bugs but added some TODOs for missing stuff that I noticed.
1 parent 254c52c commit 803b32a

File tree

2 files changed

+312
-62
lines changed

2 files changed

+312
-62
lines changed

stdlib/2/os/__init__.pyi

Lines changed: 231 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
1+
# Stubs for os
2+
# Ron Murawski <[email protected]>
3+
14
# created from https://docs.python.org/2/library/os.html
25

36
from builtins import OSError as error
7+
from io import TextIOWrapper as _TextIOWrapper
48
import sys
59
from typing import (
610
Mapping, MutableMapping, Dict, List, Any, Tuple, Iterator, overload, Union, AnyStr,
@@ -11,11 +15,21 @@ from mypy_extensions import NoReturn
1115

1216
_T = TypeVar('_T')
1317

18+
# ----- os variables -----
19+
20+
if sys.version_info >= (3, 2):
21+
supports_bytes_environ: bool
22+
23+
if sys.version_info >= (3, 3):
24+
supports_dir_fd: Set[Callable[..., Any]]
25+
supports_fd: Set[Callable[..., Any]]
26+
supports_effective_ids: Set[Callable[..., Any]]
27+
supports_follow_symlinks: Set[Callable[..., Any]]
28+
1429
SEEK_SET: int
1530
SEEK_CUR: int
1631
SEEK_END: int
1732

18-
# More constants, copied from stdlib/3/os/__init__.pyi
1933
O_RDONLY: int
2034
O_WRONLY: int
2135
O_RDWR: int
@@ -65,6 +79,8 @@ class _Environ(MutableMapping[AnyStr, AnyStr], Generic[AnyStr]):
6579
def copy(self) -> Dict[AnyStr, AnyStr]: ...
6680

6781
environ: _Environ[str]
82+
if sys.version_info >= (3, 2):
83+
environb: _Environ[bytes]
6884

6985
confstr_names: Dict[str, int] # Unix only
7086
pathconf_names: Dict[str, int] # Unix only
@@ -86,6 +102,8 @@ EX_TEMPFAIL: int # Unix only
86102
EX_PROTOCOL: int # Unix only
87103
EX_NOPERM: int # Unix only
88104
EX_CONFIG: int # Unix only
105+
EX_NOTFOUND: int # Unix only
106+
89107
P_NOWAIT: int
90108
P_NOWAITO: int
91109
P_WAIT: int
@@ -99,11 +117,118 @@ WCONTINUED: int # some Unix systems
99117
WUNTRACED: int # Unix only
100118

101119
TMP_MAX: int # Undocumented, but used by tempfile
102-
_PathType = Union[bytes, Text]
103-
_StatVFS = NamedTuple('_StatVFS', [('f_bsize', int), ('f_frsize', int), ('f_blocks', int),
104-
('f_bfree', int), ('f_bavail', int), ('f_files', int),
105-
('f_ffree', int), ('f_favail', int), ('f_flag', int),
106-
('f_namemax', int)])
120+
121+
# ----- os classes (structures) -----
122+
if sys.version_info >= (3, 6):
123+
from builtins import _PathLike as PathLike # See comment in builtins
124+
125+
_PathType = path._PathType
126+
127+
if sys.version_info >= (3, 6):
128+
class DirEntry(PathLike[AnyStr]):
129+
# This is what the scandir interator yields
130+
# The constructor is hidden
131+
132+
name: AnyStr
133+
path: AnyStr
134+
def inode(self) -> int: ...
135+
def is_dir(self, follow_symlinks: bool = ...) -> bool: ...
136+
def is_file(self, follow_symlinks: bool = ...) -> bool: ...
137+
def is_symlink(self) -> bool: ...
138+
def stat(self) -> stat_result: ...
139+
140+
def __fspath__(self) -> AnyStr: ...
141+
elif sys.version_info >= (3, 5):
142+
class DirEntry(Generic[AnyStr]):
143+
# This is what the scandir interator yields
144+
# The constructor is hidden
145+
146+
name: AnyStr
147+
path: AnyStr
148+
def inode(self) -> int: ...
149+
def is_dir(self, follow_symlinks: bool = ...) -> bool: ...
150+
def is_file(self, follow_symlinks: bool = ...) -> bool: ...
151+
def is_symlink(self) -> bool: ...
152+
def stat(self) -> stat_result: ...
153+
154+
155+
class stat_result:
156+
# For backward compatibility, the return value of stat() is also
157+
# accessible as a tuple of at least 10 integers giving the most important
158+
# (and portable) members of the stat structure, in the order st_mode,
159+
# st_ino, st_dev, st_nlink, st_uid, st_gid, st_size, st_atime, st_mtime,
160+
# st_ctime. More items may be added at the end by some implementations.
161+
162+
st_mode: int # protection bits,
163+
st_ino: int # inode number,
164+
st_dev: int # device,
165+
st_nlink: int # number of hard links,
166+
st_uid: int # user id of owner,
167+
st_gid: int # group id of owner,
168+
st_size: int # size of file, in bytes,
169+
st_atime: float # time of most recent access,
170+
st_mtime: float # time of most recent content modification,
171+
st_ctime: float # platform dependent (time of most recent metadata change on Unix, or the time of creation on Windows)
172+
173+
if sys.version_info >= (3, 3):
174+
st_atime_ns: int # time of most recent access, in nanoseconds
175+
st_mtime_ns: int # time of most recent content modification in nanoseconds
176+
st_ctime_ns: int # platform dependent (time of most recent metadata change on Unix, or the time of creation on Windows) in nanoseconds
177+
178+
# not documented
179+
def __init__(self, tuple: Tuple[int, ...]) -> None: ...
180+
181+
# On some Unix systems (such as Linux), the following attributes may also
182+
# be available:
183+
st_blocks: int # number of blocks allocated for file
184+
st_blksize: int # filesystem blocksize
185+
st_rdev: int # type of device if an inode device
186+
st_flags: int # user defined flags for file
187+
188+
# On other Unix systems (such as FreeBSD), the following attributes may be
189+
# available (but may be only filled out if root tries to use them):
190+
st_gen: int # file generation number
191+
st_birthtime: int # time of file creation
192+
193+
# On Mac OS systems, the following attributes may also be available:
194+
st_rsize: int
195+
st_creator: int
196+
st_type: int
197+
198+
class statvfs_result: # Unix only
199+
f_bsize: int
200+
f_frsize: int
201+
f_blocks: int
202+
f_bfree: int
203+
f_bavail: int
204+
f_files: int
205+
f_ffree: int
206+
f_favail: int
207+
f_flag: int
208+
f_namemax: int
209+
210+
# ----- os function stubs -----
211+
if sys.version_info >= (3, 6):
212+
def fsencode(filename: Union[str, bytes, PathLike]) -> bytes: ...
213+
elif sys.version_info >= (3, 2):
214+
def fsencode(filename: Union[str, bytes]) -> bytes: ...
215+
216+
if sys.version_info >= (3, 6):
217+
def fsdecode(filename: Union[str, bytes, PathLike]) -> str: ...
218+
elif sys.version_info >= (3, 2):
219+
def fsdecode(filename: Union[str, bytes]) -> str: ...
220+
221+
if sys.version_info >= (3, 6):
222+
@overload
223+
def fspath(path: str) -> str: ...
224+
@overload
225+
def fspath(path: bytes) -> bytes: ...
226+
@overload
227+
def fspath(path: PathLike) -> Any: ...
228+
229+
if sys.version_info >= (3, 2):
230+
def get_exec_path(env: Optional[Mapping[str, str]] = ...) -> List[str]: ...
231+
# NOTE: get_exec_path(): returns List[bytes] when env not None
107232
def ctermid() -> str: ... # Unix only
108233
def getegid() -> int: ... # Unix only
109234
def geteuid() -> int: ... # Unix only
@@ -139,20 +264,28 @@ def uname() -> Tuple[str, str, str, str, str]: ... # Unix only
139264
def getenv(key: Text) -> Optional[str]: ...
140265
@overload
141266
def getenv(key: Text, default: _T) -> Union[str, _T]: ...
267+
if sys.version_info >= (3, 2):
268+
def getenvb(key: bytes, default: bytes = ...) -> bytes: ...
142269
def putenv(key: Union[bytes, Text], value: Union[bytes, Text]) -> None: ...
143270
def unsetenv(key: Union[bytes, Text]) -> None: ...
144271

145-
def fdopen(fd: int, *args, **kwargs) -> IO[Any]: ...
272+
if sys.version_info >= (3, 0):
273+
def fdopen(fd: int, mode: str = ..., buffering: int = ..., encoding: str = ...,
274+
errors: str = ..., newline: str = ..., closefd: bool = ...) -> IO[Any]: ...
275+
else:
276+
def fdopen(fd: int, mode: str = ..., bufsize: int = ...) -> IO[Any]: ...
146277
def close(fd: int) -> None: ...
147278
def closerange(fd_low: int, fd_high: int) -> None: ...
279+
if sys.version_info >= (3, 0):
280+
def device_encoding(fd: int) -> Optional[str]: ...
148281
def dup(fd: int) -> int: ...
149282
def dup2(fd: int, fd2: int) -> None: ...
150283
def fchmod(fd: int, mode: int) -> None: ... # Unix only
151284
def fchown(fd: int, uid: int, gid: int) -> None: ... # Unix only
152285
def fdatasync(fd: int) -> None: ... # Unix only, not Mac
153286
def fpathconf(fd: int, name: Union[str, int]) -> int: ... # Unix only
154287
def fstat(fd: int) -> Any: ...
155-
def fstatvfs(fd: int) -> _StatVFS: ... # Unix only
288+
def fstatvfs(fd: int) -> statvfs_result: ... # Unix only
156289
def fsync(fd: int) -> None: ...
157290
def ftruncate(fd: int, length: int) -> None: ... # Unix only
158291
def isatty(fd: int) -> bool: ... # Unix only
@@ -169,7 +302,10 @@ def access(path: _PathType, mode: int) -> bool: ...
169302
def chdir(path: _PathType) -> None: ...
170303
def fchdir(fd: int) -> None: ...
171304
def getcwd() -> str: ...
172-
def getcwdu() -> unicode: ...
305+
if sys.version_info >= (3, 0):
306+
def getcwdb() -> bytes: ...
307+
else:
308+
def getcwdu() -> unicode: ...
173309
def chflags(path: _PathType, flags: int) -> None: ... # Unix only
174310
def chroot(path: _PathType) -> None: ... # Unix only
175311
def chmod(path: _PathType, mode: int) -> None: ...
@@ -178,36 +314,73 @@ def lchflags(path: _PathType, flags: int) -> None: ... # Unix only
178314
def lchmod(path: _PathType, mode: int) -> None: ... # Unix only
179315
def lchown(path: _PathType, uid: int, gid: int) -> None: ... # Unix only
180316
def link(src: _PathType, link_name: _PathType) -> None: ...
181-
def listdir(path: AnyStr) -> List[AnyStr]: ...
317+
318+
# TODO: support PathLike and fd arguments
319+
if sys.version_info >= (3, 2):
320+
@overload
321+
def listdir(path: str = ...) -> List[str]: ...
322+
@overload
323+
def listdir(path: bytes) -> List[bytes]: ...
324+
else:
325+
def listdir(path: AnyStr) -> List[AnyStr]: ...
326+
182327
def lstat(path: _PathType) -> Any: ...
183328
def mkfifo(path: _PathType, mode: int = ...) -> None: ... # Unix only
184329
def mknod(filename: _PathType, mode: int = ..., device: int = ...) -> None: ...
185330
def major(device: int) -> int: ...
186331
def minor(device: int) -> int: ...
187332
def makedev(major: int, minor: int) -> int: ...
188333
def mkdir(path: _PathType, mode: int = ...) -> None: ...
189-
def makedirs(path: _PathType, mode: int = ...) -> None: ...
334+
if sys.version_info >= (3, 2):
335+
def makedirs(path: _PathType, mode: int = ...,
336+
exist_ok: bool = ...) -> None: ...
337+
else:
338+
def makedirs(path: _PathType, mode: int = ...) -> None: ...
190339
def pathconf(path: _PathType, name: Union[str, int]) -> int: ... # Unix only
191340
def readlink(path: AnyStr) -> AnyStr: ...
192341
def remove(path: _PathType) -> None: ...
193342
def removedirs(path: _PathType) -> None: ...
194343
def rename(src: _PathType, dst: _PathType) -> None: ...
195344
def renames(old: _PathType, new: _PathType) -> None: ...
345+
if sys.version_info >= (3, 3):
346+
def replace(src: _PathType, dst: _PathType) -> None: ...
196347
def rmdir(path: _PathType) -> None: ...
348+
if sys.version_info >= (3, 5):
349+
@overload
350+
def scandir(path: str = ...) -> Iterator[DirEntry[str]]: ...
351+
@overload
352+
def scandir(path: bytes) -> Iterator[DirEntry[bytes]]: ...
353+
# This cannot return stat_result because of the issues discussed in
354+
# https://github.com/python/typeshed/pull/1103
197355
def stat(path: _PathType) -> Any: ...
198356
@overload
199357
def stat_float_times(newvalue: bool = ...) -> None: ...
200358
@overload
201359
def stat_float_times() -> bool: ...
202-
def statvfs(path: _PathType) -> _StatVFS: ... # Unix only
203-
def symlink(source: _PathType, link_name: _PathType) -> None: ...
360+
def statvfs(path: _PathType) -> statvfs_result: ... # Unix only
361+
# TODO add dir_fd argument
362+
if sys.version_info >= (3, 0):
363+
def symlink(source: _PathType, link_name: _PathType,
364+
target_is_directory: bool = ...) -> None:
365+
... # final argument in Windows only
366+
else:
367+
def symlink(source: _PathType, link_name: _PathType) -> None: ...
204368
def unlink(path: _PathType) -> None: ...
205-
def utime(path: _PathType, times: Optional[Tuple[float, float]]) -> None: ...
369+
# TODO: add ns, dir_fd, follow_symlinks argument
370+
if sys.version_info >= (3, 0):
371+
def utime(path: _PathType, times: Optional[Tuple[float, float]] = ...) -> None: ...
372+
else:
373+
def utime(path: _PathType, times: Optional[Tuple[float, float]]) -> None: ...
206374

207-
# TODO onerror: function from OSError to void
208-
def walk(top: AnyStr, topdown: bool = ..., onerror: Any = ...,
209-
followlinks: bool = ...) -> Iterator[Tuple[AnyStr, List[AnyStr],
210-
List[AnyStr]]]: ...
375+
if sys.version_info >= (3, 6):
376+
def walk(top: Union[AnyStr, PathLike[AnyStr]], topdown: bool = ...,
377+
onerror: Optional[Callable[[OSError], Any]] = ...,
378+
followlinks: bool = ...) -> Iterator[Tuple[AnyStr, List[AnyStr],
379+
List[AnyStr]]]: ...
380+
else:
381+
def walk(top: AnyStr, topdown: bool = ..., onerror: Optional[Callable[[OSError], Any]] = ...,
382+
followlinks: bool = ...) -> Iterator[Tuple[AnyStr, List[AnyStr],
383+
List[AnyStr]]]: ...
211384

212385
def abort() -> NoReturn: ...
213386
# These are defined as execl(file, *args) but the first *arg is mandatory.
@@ -232,11 +405,19 @@ def forkpty() -> Tuple[int, int]: ... # some flavors of Unix
232405
def kill(pid: int, sig: int) -> None: ...
233406
def killpg(pgid: int, sig: int) -> None: ... # Unix only
234407
def nice(increment: int) -> int: ... # Unix only
235-
# TODO: plock, popen*, P_*
236-
def popen(command: str, *args, **kwargs) -> Optional[IO[Any]]: ...
237-
def popen2(cmd: str, *args, **kwargs) -> Tuple[IO[Any], IO[Any]]: ...
238-
def popen3(cmd: str, *args, **kwargs) -> Tuple[IO[Any], IO[Any], IO[Any]]: ...
239-
def popen4(cmd: str, *args, **kwargs) -> Tuple[IO[Any], IO[Any]]: ...
408+
def plock(op: int) -> None: ... # Unix only ???op is int?
409+
410+
if sys.version_info >= (3, 0):
411+
class popen(_TextIOWrapper):
412+
# TODO 'b' modes or bytes command not accepted?
413+
def __init__(self, command: str, mode: str = ...,
414+
bufsize: int = ...) -> None: ...
415+
def close(self) -> Any: ... # may return int
416+
else:
417+
def popen(command: str, *args, **kwargs) -> Optional[IO[Any]]: ...
418+
def popen2(cmd: str, *args, **kwargs) -> Tuple[IO[Any], IO[Any]]: ...
419+
def popen3(cmd: str, *args, **kwargs) -> Tuple[IO[Any], IO[Any], IO[Any]]: ...
420+
def popen4(cmd: str, *args, **kwargs) -> Tuple[IO[Any], IO[Any]]: ...
240421

241422
def spawnl(mode: int, path: _PathType, arg0: Union[bytes, Text], *args: Union[bytes, Text]) -> int: ...
242423
def spawnle(mode: int, path: _PathType, arg0: Union[bytes, Text],
@@ -272,10 +453,34 @@ def getloadavg() -> Tuple[float, float, float]: ... # Unix only
272453
def sysconf(name: Union[str, int]) -> int: ... # Unix only
273454
def urandom(n: int) -> bytes: ...
274455

275-
def tmpfile() -> IO[Any]: ...
276-
def tmpnam() -> str: ...
277-
def tempnam(dir: str = ..., prefix: str = ...) -> str: ...
456+
if sys.version_info >= (3, 0):
457+
def sched_getaffinity(id: int) -> Set[int]: ...
458+
if sys.version_info >= (3, 3):
459+
class waitresult:
460+
si_pid: int
461+
def waitid(idtype: int, id: int, options: int) -> waitresult: ...
462+
463+
if sys.version_info < (3, 0):
464+
def tmpfile() -> IO[Any]: ...
465+
def tmpnam() -> str: ...
466+
def tempnam(dir: str = ..., prefix: str = ...) -> str: ...
278467

279468
P_ALL: int
280469
WEXITED: int
281470
WNOWAIT: int
471+
472+
if sys.version_info >= (3, 3):
473+
def sync() -> None: ... # Unix only
474+
475+
def truncate(path: Union[_PathType, int], length: int) -> None: ... # Unix only up to version 3.4
476+
477+
def fwalk(top: AnyStr = ..., topdown: bool = ...,
478+
onerror: Callable = ..., *, follow_symlinks: bool = ...,
479+
dir_fd: int = ...) -> Iterator[Tuple[AnyStr, List[AnyStr],
480+
List[AnyStr], int]]: ... # Unix only
481+
482+
terminal_size = NamedTuple('terminal_size', [('columns', int), ('lines', int)])
483+
def get_terminal_size(fd: int = ...) -> terminal_size: ...
484+
485+
if sys.version_info >= (3, 4):
486+
def cpu_count() -> Optional[int]: ...

0 commit comments

Comments
 (0)