Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit ae882f7

Browse files
author
Johannes Gijsbers
committed
Patch #941486: add os.path.lexists(). Also fix bug #940578 by using lexists in glob.glob.
1 parent d3f61a2 commit ae882f7

11 files changed

Lines changed: 57 additions & 4 deletions

File tree

Doc/lib/libglob.tex

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ \section{\module{glob} ---
2121
\var{pathname} can be either absolute (like
2222
\file{/usr/src/Python-1.5/Makefile}) or relative (like
2323
\file{../../Tools/*/*.gif}), and can contain shell-style wildcards.
24+
Broken symlinks are included in the results (as in the shell).
2425
\end{funcdesc}
2526

2627
For example, consider a directory containing only the following files:

Doc/lib/libposixpath.tex

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,15 @@ \section{\module{os.path} ---
4343

4444
\begin{funcdesc}{exists}{path}
4545
Return \code{True} if \var{path} refers to an existing path.
46+
Returns \code{False} for broken symbolic links.
47+
\end{funcdesc}
48+
49+
\begin{funcdesc}{lexists}{path}
50+
Return \code{True} if \var{path} refers to an existing path.
51+
Returns \code{True} for broken symbolic links.
52+
Equivalent to \function{exists()} on platforms lacking
53+
\function{os.lstat()}.
54+
\versionadded{2.4}
4655
\end{funcdesc}
4756

4857
\begin{funcdesc}{expanduser}{path}

Lib/glob.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ def glob(pathname):
1313
1414
"""
1515
if not has_magic(pathname):
16-
if os.path.exists(pathname):
16+
if os.path.lexists(pathname):
1717
return [pathname]
1818
else:
1919
return []
@@ -29,7 +29,7 @@ def glob(pathname):
2929
for dirname in list:
3030
if basename or os.path.isdir(dirname):
3131
name = os.path.join(dirname, basename)
32-
if os.path.exists(name):
32+
if os.path.lexists(name):
3333
result.append(name)
3434
else:
3535
result = []

Lib/macpath.py

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -150,14 +150,26 @@ def getctime(filename):
150150
return os.stat(filename).st_ctime
151151

152152
def exists(s):
153-
"""Return True if the pathname refers to an existing file or directory."""
153+
"""Test whether a path exists. Returns False for broken symbolic links"""
154154

155155
try:
156156
st = os.stat(s)
157157
except os.error:
158158
return False
159159
return True
160160

161+
# Is `stat`/`lstat` a meaningful difference on the Mac? This is safe in any
162+
# case.
163+
164+
def lexists(path):
165+
"""Test whether a path exists. Returns True for broken symbolic links"""
166+
167+
try:
168+
st = os.lstat(path)
169+
except os.error:
170+
return False
171+
return True
172+
161173
# Return the longest prefix of all list elements.
162174

163175
def commonprefix(m):

Lib/ntpath.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -249,7 +249,6 @@ def islink(path):
249249

250250

251251
# Does a path exist?
252-
# This is false for dangling symbolic links.
253252

254253
def exists(path):
255254
"""Test whether a path exists"""
@@ -259,6 +258,8 @@ def exists(path):
259258
return False
260259
return True
261260

261+
lexists = exists
262+
262263

263264
# Is a path a dos directory?
264265
# This follows symbolic links, so both islink() and isdir() can be true

Lib/os2emxpath.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -220,6 +220,8 @@ def exists(path):
220220
return False
221221
return True
222222

223+
lexists = exists
224+
223225

224226
# Is a path a directory?
225227

Lib/plat-riscos/riscospath.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -218,6 +218,8 @@ def exists(p):
218218
except swi.error:
219219
return 0
220220

221+
lexists = exists
222+
221223

222224
def isdir(p):
223225
"""

Lib/posixpath.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,17 @@ def exists(path):
174174
return True
175175

176176

177+
# Being true for dangling symbolic links is also useful.
178+
179+
def lexists(path):
180+
"""Test whether a path exists. Returns True for broken symbolic links"""
181+
try:
182+
st = os.lstat(path)
183+
except os.error:
184+
return False
185+
return True
186+
187+
177188
# Is a path a directory?
178189
# This follows symbolic links, so both islink() and isdir() can be true
179190
# for the same path.

Lib/test/test_glob.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,9 @@ def setUp(self):
4848
self.mktemp('ZZZ')
4949
self.mktemp('a', 'bcd', 'EF')
5050
self.mktemp('a', 'bcd', 'efg', 'ha')
51+
if hasattr(os, 'symlink'):
52+
os.symlink(self.norm('broken'), self.norm('sym1'))
53+
os.symlink(self.norm('broken'), self.norm('sym2'))
5154

5255
def tearDown(self):
5356
deltree(self.tempdir)
@@ -98,6 +101,13 @@ def test_glob_directory_names(self):
98101
eq(self.glob('?a?', '*F'), map(self.norm, [os.path.join('aaa', 'zzzF'),
99102
os.path.join('aab', 'F')]))
100103

104+
def test_glob_broken_symlinks(self):
105+
if hasattr(os, 'symlink'):
106+
eq = self.assertSequencesEqual_noorder
107+
eq(self.glob('sym*'), [self.norm('sym1'), self.norm('sym2')])
108+
eq(self.glob('sym1'), [self.norm('sym1')])
109+
eq(self.glob('sym2'), [self.norm('sym2')])
110+
101111

102112
def test_main():
103113
run_unittest(GlobTests)

Lib/test/test_posixpath.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,7 @@ def test_islink(self):
150150
os.remove(test_support.TESTFN + "1")
151151
self.assertIs(posixpath.islink(test_support.TESTFN + "2"), True)
152152
self.assertIs(posixpath.exists(test_support.TESTFN + "2"), False)
153+
self.assertIs(posixpath.lexists(test_support.TESTFN + "2"), True)
153154
finally:
154155
if not f.close():
155156
f.close()
@@ -171,6 +172,7 @@ def test_exists(self):
171172
f.write("foo")
172173
f.close()
173174
self.assertIs(posixpath.exists(test_support.TESTFN), True)
175+
self.assertIs(posixpath.lexists(test_support.TESTFN), True)
174176
finally:
175177
if not f.close():
176178
f.close()

0 commit comments

Comments
 (0)