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

Skip to content

Commit b186f34

Browse files
committed
Issue3187 for Macintosh platform:
macpath.py now accepts both unicode string and bytes as file names. Also add more tests for these functions. Reviewed by Benjamin.
1 parent f60fe81 commit b186f34

2 files changed

Lines changed: 123 additions & 23 deletions

File tree

Lib/macpath.py

Lines changed: 39 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
"devnull","realpath","supports_unicode_filenames"]
1414

1515
# strings representing various path-related bits and pieces
16+
# These are primarily for export; internally, they are hardcoded.
1617
curdir = ':'
1718
pardir = '::'
1819
extsep = '.'
@@ -22,6 +23,12 @@
2223
altsep = None
2324
devnull = 'Dev:Null'
2425

26+
def _get_colon(path):
27+
if isinstance(path, bytes):
28+
return b':'
29+
else:
30+
return ':'
31+
2532
# Normalize the case of a pathname. Dummy in Posix, but <s>.lower() here.
2633

2734
def normcase(path):
@@ -35,21 +42,23 @@ def isabs(s):
3542
Anything else is absolute (the string up to the first colon is the
3643
volume name)."""
3744

38-
return ':' in s and s[0] != ':'
45+
colon = _get_colon(s)
46+
return colon in s and s[:1] != colon
3947

4048

4149
def join(s, *p):
50+
colon = _get_colon(s)
4251
path = s
4352
for t in p:
4453
if (not s) or isabs(t):
4554
path = t
4655
continue
47-
if t[:1] == ':':
56+
if t[:1] == colon:
4857
t = t[1:]
49-
if ':' not in path:
50-
path = ':' + path
51-
if path[-1:] != ':':
52-
path = path + ':'
58+
if colon not in path:
59+
path = colon + path
60+
if path[-1:] != colon:
61+
path = path + colon
5362
path = path + t
5463
return path
5564

@@ -59,18 +68,22 @@ def split(s):
5968
bit, and the basename (the filename, without colons, in that directory).
6069
The result (s, t) is such that join(s, t) yields the original argument."""
6170

62-
if ':' not in s: return '', s
63-
colon = 0
71+
colon = _get_colon(s)
72+
if colon not in s: return s[:0], s
73+
col = 0
6474
for i in range(len(s)):
65-
if s[i] == ':': colon = i + 1
66-
path, file = s[:colon-1], s[colon:]
67-
if path and not ':' in path:
68-
path = path + ':'
75+
if s[i:i+1] == colon: col = i + 1
76+
path, file = s[:col-1], s[col:]
77+
if path and not colon in path:
78+
path = path + colon
6979
return path, file
7080

7181

7282
def splitext(p):
73-
return genericpath._splitext(p, sep, altsep, extsep)
83+
if isinstance(p, bytes):
84+
return genericpath._splitext(p, b':', altsep, b'.')
85+
else:
86+
return genericpath._splitext(p, sep, altsep, extsep)
7487
splitext.__doc__ = genericpath._splitext.__doc__
7588

7689
def splitdrive(p):
@@ -80,7 +93,7 @@ def splitdrive(p):
8093
syntactic and semantic oddities as DOS drive letters, such as there
8194
being a separate current directory per drive)."""
8295

83-
return '', p
96+
return p[:0], p
8497

8598

8699
# Short interfaces to split()
@@ -92,7 +105,7 @@ def ismount(s):
92105
if not isabs(s):
93106
return False
94107
components = split(s)
95-
return len(components) == 2 and components[1] == ''
108+
return len(components) == 2 and not components[1]
96109

97110
def islink(s):
98111
"""Return true if the pathname refers to a symbolic link."""
@@ -131,13 +144,15 @@ def normpath(s):
131144
"""Normalize a pathname. Will return the same result for
132145
equivalent paths."""
133146

134-
if ":" not in s:
135-
return ":"+s
147+
colon = _get_colon(s)
148+
149+
if colon not in s:
150+
return colon + s
136151

137-
comps = s.split(":")
152+
comps = s.split(colon)
138153
i = 1
139154
while i < len(comps)-1:
140-
if comps[i] == "" and comps[i-1] != "":
155+
if not comps[i] and comps[i-1]:
141156
if i > 1:
142157
del comps[i-1:i+1]
143158
i = i - 1
@@ -147,10 +162,10 @@ def normpath(s):
147162
else:
148163
i = i + 1
149164

150-
s = ":".join(comps)
165+
s = colon.join(comps)
151166

152167
# remove trailing ":" except for ":" and "Volume:"
153-
if s[-1] == ":" and len(comps) > 2 and s != ":"*len(s):
168+
if s[-1:] == colon and len(comps) > 2 and s != colon*len(s):
154169
s = s[:-1]
155170
return s
156171

@@ -169,8 +184,9 @@ def realpath(path):
169184
return path
170185
if not path:
171186
return path
172-
components = path.split(':')
173-
path = components[0] + ':'
187+
colon = _get_colon(path)
188+
components = path.split(colon)
189+
path = components[0] + colon
174190
for c in components[1:]:
175191
path = join(path, c)
176192
path = Carbon.File.FSResolveAliasFile(path, 1)[0].as_pathname()

Lib/test/test_macpath.py

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,14 @@ def test_isabs(self):
1818
self.failIf(isabs(":foo:bar"))
1919
self.failIf(isabs(":foo:bar:"))
2020

21+
self.assert_(isabs(b"xx:yy"))
22+
self.assert_(isabs(b"xx:yy:"))
23+
self.assert_(isabs(b"xx:"))
24+
self.failIf(isabs(b"foo"))
25+
self.failIf(isabs(b":foo"))
26+
self.failIf(isabs(b":foo:bar"))
27+
self.failIf(isabs(b":foo:bar:"))
28+
2129

2230
def test_commonprefix(self):
2331
commonprefix = macpath.commonprefix
@@ -28,6 +36,13 @@ def test_commonprefix(self):
2836
self.assert_(commonprefix([":home:swen:spam", ":home:swen:spam"])
2937
== ":home:swen:spam")
3038

39+
self.assert_(commonprefix([b"home:swenson:spam", b"home:swen:spam"])
40+
== b"home:swen")
41+
self.assert_(commonprefix([b":home:swen:spam", b":home:swen:eggs"])
42+
== b":home:swen:")
43+
self.assert_(commonprefix([b":home:swen:spam", b":home:swen:spam"])
44+
== b":home:swen:spam")
45+
3146
def test_split(self):
3247
split = macpath.split
3348
self.assertEquals(split("foo:bar"),
@@ -39,11 +54,37 @@ def test_split(self):
3954
self.assertEquals(split(":conky:mountpoint:"),
4055
(':conky:mountpoint', ''))
4156

57+
self.assertEquals(split(b"foo:bar"),
58+
(b'foo:', b'bar'))
59+
self.assertEquals(split(b"conky:mountpoint:foo:bar"),
60+
(b'conky:mountpoint:foo', b'bar'))
61+
62+
self.assertEquals(split(b":"), (b'', b''))
63+
self.assertEquals(split(b":conky:mountpoint:"),
64+
(b':conky:mountpoint', b''))
65+
66+
def test_join(self):
67+
join = macpath.join
68+
self.assertEquals(join('a', 'b'), ':a:b')
69+
self.assertEquals(join('', 'a:b'), 'a:b')
70+
self.assertEquals(join('a:b', 'c'), 'a:b:c')
71+
self.assertEquals(join('a:b', ':c'), 'a:b:c')
72+
self.assertEquals(join('a', ':b', ':c'), ':a:b:c')
73+
74+
self.assertEquals(join(b'a', b'b'), b':a:b')
75+
self.assertEquals(join(b'', b'a:b'), b'a:b')
76+
self.assertEquals(join(b'a:b', b'c'), b'a:b:c')
77+
self.assertEquals(join(b'a:b', b':c'), b'a:b:c')
78+
self.assertEquals(join(b'a', b':b', b':c'), b':a:b:c')
79+
4280
def test_splitdrive(self):
4381
splitdrive = macpath.splitdrive
4482
self.assertEquals(splitdrive("foo:bar"), ('', 'foo:bar'))
4583
self.assertEquals(splitdrive(":foo:bar"), ('', ':foo:bar'))
4684

85+
self.assertEquals(splitdrive(b"foo:bar"), (b'', b'foo:bar'))
86+
self.assertEquals(splitdrive(b":foo:bar"), (b'', b':foo:bar'))
87+
4788
def test_splitext(self):
4889
splitext = macpath.splitext
4990
self.assertEquals(splitext(":foo.ext"), (':foo', '.ext'))
@@ -54,6 +95,49 @@ def test_splitext(self):
5495
self.assertEquals(splitext(""), ('', ''))
5596
self.assertEquals(splitext("foo.bar.ext"), ('foo.bar', '.ext'))
5697

98+
self.assertEquals(splitext(b":foo.ext"), (b':foo', b'.ext'))
99+
self.assertEquals(splitext(b"foo:foo.ext"), (b'foo:foo', b'.ext'))
100+
self.assertEquals(splitext(b".ext"), (b'.ext', b''))
101+
self.assertEquals(splitext(b"foo.ext:foo"), (b'foo.ext:foo', b''))
102+
self.assertEquals(splitext(b":foo.ext:"), (b':foo.ext:', b''))
103+
self.assertEquals(splitext(b""), (b'', b''))
104+
self.assertEquals(splitext(b"foo.bar.ext"), (b'foo.bar', b'.ext'))
105+
106+
def test_ismount(self):
107+
ismount = macpath.ismount
108+
self.assertEquals(ismount("a:"), True)
109+
self.assertEquals(ismount("a:b"), False)
110+
self.assertEquals(ismount("a:b:"), True)
111+
self.assertEquals(ismount(""), False)
112+
self.assertEquals(ismount(":"), False)
113+
114+
self.assertEquals(ismount(b"a:"), True)
115+
self.assertEquals(ismount(b"a:b"), False)
116+
self.assertEquals(ismount(b"a:b:"), True)
117+
self.assertEquals(ismount(b""), False)
118+
self.assertEquals(ismount(b":"), False)
119+
120+
def test_normpath(self):
121+
normpath = macpath.normpath
122+
self.assertEqual(normpath("a:b"), "a:b")
123+
self.assertEqual(normpath("a"), ":a")
124+
self.assertEqual(normpath("a:b::c"), "a:c")
125+
self.assertEqual(normpath("a:b:c:::d"), "a:d")
126+
self.assertRaises(macpath.norm_error, normpath, "a::b")
127+
self.assertRaises(macpath.norm_error, normpath, "a:b:::c")
128+
self.assertEqual(normpath(":"), ":")
129+
self.assertEqual(normpath("a:"), "a:")
130+
self.assertEqual(normpath("a:b:"), "a:b")
131+
132+
self.assertEqual(normpath(b"a:b"), b"a:b")
133+
self.assertEqual(normpath(b"a"), b":a")
134+
self.assertEqual(normpath(b"a:b::c"), b"a:c")
135+
self.assertEqual(normpath(b"a:b:c:::d"), b"a:d")
136+
self.assertRaises(macpath.norm_error, normpath, b"a::b")
137+
self.assertRaises(macpath.norm_error, normpath, b"a:b:::c")
138+
self.assertEqual(normpath(b":"), b":")
139+
self.assertEqual(normpath(b"a:"), b"a:")
140+
self.assertEqual(normpath(b"a:b:"), b"a:b")
57141

58142
def test_main():
59143
support.run_unittest(MacPathTestCase)

0 commit comments

Comments
 (0)