Skip to content

Commit c4a8051

Browse files
authored
Update genericpath.py from 3.13.5 (RustPython#6065)
1 parent 72fc3c0 commit c4a8051

File tree

2 files changed

+69
-18
lines changed

2 files changed

+69
-18
lines changed

Lib/genericpath.py

Lines changed: 35 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@
77
import stat
88

99
__all__ = ['commonprefix', 'exists', 'getatime', 'getctime', 'getmtime',
10-
'getsize', 'isdir', 'isfile', 'islink', 'samefile', 'sameopenfile',
11-
'samestat']
10+
'getsize', 'isdevdrive', 'isdir', 'isfile', 'isjunction', 'islink',
11+
'lexists', 'samefile', 'sameopenfile', 'samestat', 'ALLOW_MISSING']
1212

1313

1414
# Does a path exist?
@@ -22,6 +22,15 @@ def exists(path):
2222
return True
2323

2424

25+
# Being true for dangling symbolic links is also useful.
26+
def lexists(path):
27+
"""Test whether a path exists. Returns True for broken symbolic links"""
28+
try:
29+
os.lstat(path)
30+
except (OSError, ValueError):
31+
return False
32+
return True
33+
2534
# This follows symbolic links, so both islink() and isdir() can be true
2635
# for the same path on systems that support symlinks
2736
def isfile(path):
@@ -57,6 +66,21 @@ def islink(path):
5766
return stat.S_ISLNK(st.st_mode)
5867

5968

69+
# Is a path a junction?
70+
def isjunction(path):
71+
"""Test whether a path is a junction
72+
Junctions are not supported on the current platform"""
73+
os.fspath(path)
74+
return False
75+
76+
77+
def isdevdrive(path):
78+
"""Determines whether the specified path is on a Windows Dev Drive.
79+
Dev Drives are not supported on the current platform"""
80+
os.fspath(path)
81+
return False
82+
83+
6084
def getsize(filename):
6185
"""Return the size of a file, reported by os.stat()."""
6286
return os.stat(filename).st_size
@@ -165,3 +189,12 @@ def _check_arg_types(funcname, *args):
165189
f'os.PathLike object, not {s.__class__.__name__!r}') from None
166190
if hasstr and hasbytes:
167191
raise TypeError("Can't mix strings and bytes in path components") from None
192+
193+
# A singleton with a true boolean value.
194+
@object.__new__
195+
class ALLOW_MISSING:
196+
"""Special value for use in realpath()."""
197+
def __repr__(self):
198+
return 'os.path.ALLOW_MISSING'
199+
def __reduce__(self):
200+
return self.__class__.__name__

Lib/test/test_genericpath.py

Lines changed: 34 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,9 @@
77
import sys
88
import unittest
99
import warnings
10-
from test.support import is_emscripten
11-
from test.support import os_helper
12-
from test.support import warnings_helper
10+
from test.support import (
11+
is_apple, is_emscripten, os_helper, warnings_helper
12+
)
1313
from test.support.script_helper import assert_python_ok
1414
from test.support.os_helper import FakePath
1515

@@ -135,6 +135,9 @@ def test_exists(self):
135135
self.assertIs(self.pathmodule.exists(filename), False)
136136
self.assertIs(self.pathmodule.exists(bfilename), False)
137137

138+
self.assertIs(self.pathmodule.lexists(filename), False)
139+
self.assertIs(self.pathmodule.lexists(bfilename), False)
140+
138141
create_file(filename)
139142

140143
self.assertIs(self.pathmodule.exists(filename), True)
@@ -145,14 +148,17 @@ def test_exists(self):
145148
self.assertIs(self.pathmodule.exists(filename + '\x00'), False)
146149
self.assertIs(self.pathmodule.exists(bfilename + b'\x00'), False)
147150

148-
if self.pathmodule is not genericpath:
149-
self.assertIs(self.pathmodule.lexists(filename), True)
150-
self.assertIs(self.pathmodule.lexists(bfilename), True)
151+
self.assertIs(self.pathmodule.lexists(filename), True)
152+
self.assertIs(self.pathmodule.lexists(bfilename), True)
153+
154+
self.assertIs(self.pathmodule.lexists(filename + '\udfff'), False)
155+
self.assertIs(self.pathmodule.lexists(bfilename + b'\xff'), False)
156+
self.assertIs(self.pathmodule.lexists(filename + '\x00'), False)
157+
self.assertIs(self.pathmodule.lexists(bfilename + b'\x00'), False)
151158

152-
self.assertIs(self.pathmodule.lexists(filename + '\udfff'), False)
153-
self.assertIs(self.pathmodule.lexists(bfilename + b'\xff'), False)
154-
self.assertIs(self.pathmodule.lexists(filename + '\x00'), False)
155-
self.assertIs(self.pathmodule.lexists(bfilename + b'\x00'), False)
159+
# Keyword arguments are accepted
160+
self.assertIs(self.pathmodule.exists(path=filename), True)
161+
self.assertIs(self.pathmodule.lexists(path=filename), True)
156162

157163
@unittest.skipUnless(hasattr(os, "pipe"), "requires os.pipe()")
158164
@unittest.skipIf(is_emscripten, "Emscripten pipe fds have no stat")
@@ -165,6 +171,14 @@ def test_exists_fd(self):
165171
os.close(w)
166172
self.assertFalse(self.pathmodule.exists(r))
167173

174+
# TODO: RUSTPYTHON
175+
@unittest.expectedFailure
176+
def test_exists_bool(self):
177+
for fd in False, True:
178+
with self.assertWarnsRegex(RuntimeWarning,
179+
'bool is used as a file descriptor'):
180+
self.pathmodule.exists(fd)
181+
168182
def test_isdir(self):
169183
filename = os_helper.TESTFN
170184
bfilename = os.fsencode(filename)
@@ -483,12 +497,16 @@ def test_abspath_issue3426(self):
483497
self.assertIsInstance(abspath(path), str)
484498

485499
def test_nonascii_abspath(self):
486-
if (os_helper.TESTFN_UNDECODABLE
487-
# macOS and Emscripten deny the creation of a directory with an
488-
# invalid UTF-8 name. Windows allows creating a directory with an
489-
# arbitrary bytes name, but fails to enter this directory
490-
# (when the bytes name is used).
491-
and sys.platform not in ('win32', 'darwin', 'emscripten', 'wasi')):
500+
if (
501+
os_helper.TESTFN_UNDECODABLE
502+
# Apple platforms and Emscripten/WASI deny the creation of a
503+
# directory with an invalid UTF-8 name. Windows allows creating a
504+
# directory with an arbitrary bytes name, but fails to enter this
505+
# directory (when the bytes name is used).
506+
and sys.platform not in {
507+
"win32", "emscripten", "wasi"
508+
} and not is_apple
509+
):
492510
name = os_helper.TESTFN_UNDECODABLE
493511
elif os_helper.TESTFN_NONASCII:
494512
name = os_helper.TESTFN_NONASCII

0 commit comments

Comments
 (0)