Skip to content

Commit ef6458c

Browse files
splitpath: accept generic strings; more generic path tests (#33012)
fixes #32995
1 parent 050160c commit ef6458c

File tree

3 files changed

+132
-127
lines changed

3 files changed

+132
-127
lines changed

NEWS.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ Build system changes
2020
New library functions
2121
---------------------
2222

23+
* The `splitpath` function now accepts any `AbstractString` whereas previously it only accepted paths of type `String` ([#33012]).
24+
2325

2426
Standard library changes
2527
------------------------

base/path.jl

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -226,6 +226,8 @@ julia> splitpath("/home/myuser/example.jl")
226226
"example.jl"
227227
```
228228
"""
229+
splitpath(p::AbstractString) = splitpath(String(p))
230+
229231
function splitpath(p::String)
230232
drive, p = splitdrive(p)
231233
out = String[]
@@ -244,8 +246,6 @@ function splitpath(p::String)
244246
return out
245247
end
246248

247-
joinpath(a::AbstractString) = a
248-
249249
"""
250250
joinpath(parts...) -> AbstractString
251251
@@ -260,6 +260,7 @@ julia> joinpath("/home/myuser", "example.jl")
260260
```
261261
"""
262262
joinpath(a::AbstractString, b::AbstractString, c::AbstractString...) = joinpath(joinpath(a,b), c...)
263+
joinpath(a::AbstractString) = a
263264

264265
function joinpath(a::String, b::String)
265266
isabspath(b) && return b

test/path.jl

Lines changed: 127 additions & 125 deletions
Original file line numberDiff line numberDiff line change
@@ -86,42 +86,42 @@
8686
@test relpath(S(joinpath("foo","bar")), S("foo")) == "bar"
8787

8888
@testset "splitpath" begin
89-
@test splitpath(joinpath("a","b","c")) == ["a", "b", "c"]
89+
@test splitpath(S(joinpath("a","b","c"))) == ["a", "b", "c"]
9090
@test splitpath("") == [""]
9191

92-
@test splitpath(joinpath("cats are", "gr8t")) == ["cats are", "gr8t"]
93-
@test splitpath(joinpath(" ", " ")) == [" ", " "]
92+
@test splitpath(S(joinpath("cats are", "gr8t"))) == ["cats are", "gr8t"]
93+
@test splitpath(S(joinpath(" ", " "))) == [" ", " "]
9494

9595
# Unix-style paths are understood by all systems.
96-
@test splitpath("/a/b") == ["/", "a", "b"]
97-
@test splitpath("/") == ["/"]
98-
@test splitpath("a/") == ["a"]
99-
@test splitpath("a/b/") == ["a", "b"]
100-
@test splitpath("a.dir/b.txt") == ["a.dir", "b.txt"]
101-
@test splitpath("///") == ["/"]
102-
@test splitpath("///a///b///") == ["/", "a", "b"]
96+
@test splitpath(S("/a/b")) == ["/", "a", "b"]
97+
@test splitpath(S("/")) == ["/"]
98+
@test splitpath(S("a/")) == ["a"]
99+
@test splitpath(S("a/b/")) == ["a", "b"]
100+
@test splitpath(S("a.dir/b.txt")) == ["a.dir", "b.txt"]
101+
@test splitpath(S("///")) == ["/"]
102+
@test splitpath(S("///a///b///")) == ["/", "a", "b"]
103103

104104
if Sys.iswindows()
105-
@test splitpath("C:\\\\a\\b\\c") == ["C:\\", "a", "b", "c"]
106-
@test splitpath("C:\\\\") == ["C:\\"]
107-
@test splitpath("J:\\") == ["J:\\"]
108-
@test splitpath("C:") == ["C:"]
109-
@test splitpath("C:a") == ["C:a"]
110-
@test splitpath("C:a\\b") == ["C:a", "b"]
105+
@test splitpath(S("C:\\\\a\\b\\c")) == ["C:\\", "a", "b", "c"]
106+
@test splitpath(S("C:\\\\")) == ["C:\\"]
107+
@test splitpath(S("J:\\")) == ["J:\\"]
108+
@test splitpath(S("C:")) == ["C:"]
109+
@test splitpath(S("C:a")) == ["C:a"]
110+
@test splitpath(S("C:a\\b")) == ["C:a", "b"]
111111

112-
@test splitpath("a\\") == ["a"]
113-
@test splitpath("a\\\\b\\\\") == ["a","b"]
114-
@test splitpath("a.dir\\b.txt") == ["a.dir", "b.txt"]
115-
@test splitpath("\\a\\b\\") == ["\\", "a","b"]
116-
@test splitpath("\\\\a\\b") == ["\\\\a\\b"] # This is actually a valid drive name in windows.
112+
@test splitpath(S("a\\")) == ["a"]
113+
@test splitpath(S("a\\\\b\\\\")) == ["a","b"]
114+
@test splitpath(S("a.dir\\b.txt")) == ["a.dir", "b.txt"]
115+
@test splitpath(S("\\a\\b\\")) == ["\\", "a","b"]
116+
@test splitpath(S("\\\\a\\b")) == ["\\\\a\\b"] # This is actually a valid drive name in windows.
117117

118-
@test splitpath("/a/b\\c/d\\\\e") == ["/", "a", "b", "c", "d", "e"]
119-
@test splitpath("/\\/\\") == ["/"]
120-
@test splitpath("\\/\\a/\\//b") == ["\\","a","b"]
118+
@test splitpath(S("/a/b\\c/d\\\\e")) == ["/", "a", "b", "c", "d", "e"]
119+
@test splitpath(S("/\\/\\")) == ["/"]
120+
@test splitpath(S("\\/\\a/\\//b")) == ["\\","a","b"]
121121
end
122122
end
123123

124-
@testset "splitting" begin
124+
@testset "splitdir, splitdrive" begin
125125
@test joinpath(splitdir(S(homedir()))...) == homedir()
126126
@test string(splitdrive(S(homedir()))...) == homedir()
127127
@test splitdrive("a\nb") == ("", "a\nb")
@@ -150,113 +150,115 @@
150150
@test_broken splitext(S(".foo...")) == (".foo", "...")
151151
@test splitext(S(".foo.bar")) == (".foo", ".bar")
152152
end
153-
end
154153

155-
@testset "isabspath" begin
156-
@test isabspath("~") == false
157-
@test isabspath("/") == true # on windows, this is relatively absolute
158-
@test isabspath("A:/") == Sys.iswindows()
159-
@test isabspath("B:\\") == Sys.iswindows()
160-
@test isabspath("./") == false
161-
@test isabspath("C:") == false
162-
@test isabspath("C:.") == false
163-
@test isabspath("α:/") == false
164-
@test isabspath(".:/") == false
165-
#@test isabspath("_:/") == false # FIXME?
166-
#@test isabspath("AB:/") == false # FIXME?
167-
@test isabspath("\\\\") == Sys.iswindows()
168-
if Sys.isunix()
169-
@test isabspath(expanduser("~")) == true
170-
@test startswith(expanduser("~"), homedir())
171-
else
172-
@test expanduser("~") == "~"
154+
@testset "isabspath" begin
155+
@test isabspath(S("~")) == false
156+
@test isabspath(S("/")) == true # on windows, this is relatively absolute
157+
@test isabspath(S("A:/")) == Sys.iswindows()
158+
@test isabspath(S("B:\\")) == Sys.iswindows()
159+
@test isabspath(S("./")) == false
160+
@test isabspath(S("C:")) == false
161+
@test isabspath(S("C:.")) == false
162+
@test isabspath(S("α:/")) == false
163+
@test isabspath(S(".:/")) == false
164+
#@test isabspath(S("_:/")) == false # FIXME?
165+
#@test isabspath(S("AB:/")) == false # FIXME?
166+
@test isabspath(S("\\\\")) == Sys.iswindows()
167+
if Sys.isunix()
168+
@test isabspath(S(expanduser("~"))) == true
169+
@test startswith(expanduser(S("~")), homedir())
170+
else
171+
@test expanduser(S("~")) == "~"
172+
end
173173
end
174-
end
175174

176-
@testset "relpath" begin
177-
function test_relpath()
178-
sep = Base.Filesystem.path_separator
179-
filepaths = [
180-
"$(sep)home$(sep)user$(sep).julia$(sep)Test1$(sep)docs$(sep)api$(sep)Test1.md",
181-
"$(sep)home$(sep)user$(sep).julia$(sep)Test1$(sep)docs$(sep)api$(sep)lib$(sep)file1.md",
182-
"$(sep)home$(sep)user$(sep).julia$(sep)测试2$(sep)docs$(sep)api$(sep)测试2.md",
183-
"$(sep)home$(sep)user$(sep)dir_withendsep$(sep)",
184-
"$(sep)home$(sep)dir2_withendsep$(sep)",
185-
"$(sep)home$(sep)test.md",
186-
"$(sep)home",
187-
# Special cases
188-
"$(sep)",
189-
"$(sep)home$(sep)$(sep)$(sep)"
190-
]
191-
startpaths = [
192-
"$(sep)home$(sep)user$(sep).julia$(sep)Test1$(sep)docs$(sep)api$(sep)genindex.md",
193-
"$(sep)multi_docs$(sep)genindex.md",
194-
"$(sep)home$(sep)user$(sep)dir_withendsep$(sep)",
195-
"$(sep)home$(sep)dir2_withendsep$(sep)",
196-
"$(sep)home$(sep)test.md",
197-
"$(sep)home",
198-
# Special cases
199-
"$(sep)",
200-
"$(sep)home$(sep)$(sep)$(sep)"
201-
]
202-
relpath_expected_results = [
203-
"..$(sep)Test1.md",
204-
"..$(sep)..$(sep)home$(sep)user$(sep).julia$(sep)Test1$(sep)docs$(sep)api$(sep)Test1.md",
205-
"..$(sep).julia$(sep)Test1$(sep)docs$(sep)api$(sep)Test1.md",
206-
"..$(sep)user$(sep).julia$(sep)Test1$(sep)docs$(sep)api$(sep)Test1.md",
207-
"..$(sep)user$(sep).julia$(sep)Test1$(sep)docs$(sep)api$(sep)Test1.md",
208-
"user$(sep).julia$(sep)Test1$(sep)docs$(sep)api$(sep)Test1.md",
209-
"home$(sep)user$(sep).julia$(sep)Test1$(sep)docs$(sep)api$(sep)Test1.md",
210-
"user$(sep).julia$(sep)Test1$(sep)docs$(sep)api$(sep)Test1.md",
211-
"..$(sep)lib$(sep)file1.md",
212-
"..$(sep)..$(sep)home$(sep)user$(sep).julia$(sep)Test1$(sep)docs$(sep)api$(sep)lib$(sep)file1.md",
213-
"..$(sep).julia$(sep)Test1$(sep)docs$(sep)api$(sep)lib$(sep)file1.md",
214-
"..$(sep)user$(sep).julia$(sep)Test1$(sep)docs$(sep)api$(sep)lib$(sep)file1.md",
215-
"..$(sep)user$(sep).julia$(sep)Test1$(sep)docs$(sep)api$(sep)lib$(sep)file1.md",
216-
"user$(sep).julia$(sep)Test1$(sep)docs$(sep)api$(sep)lib$(sep)file1.md",
217-
"home$(sep)user$(sep).julia$(sep)Test1$(sep)docs$(sep)api$(sep)lib$(sep)file1.md",
218-
"user$(sep).julia$(sep)Test1$(sep)docs$(sep)api$(sep)lib$(sep)file1.md",
219-
"..$(sep)..$(sep)..$(sep)..$(sep)测试2$(sep)docs$(sep)api$(sep)测试2.md",
220-
"..$(sep)..$(sep)home$(sep)user$(sep).julia$(sep)测试2$(sep)docs$(sep)api$(sep)测试2.md",
221-
"..$(sep).julia$(sep)测试2$(sep)docs$(sep)api$(sep)测试2.md",
222-
"..$(sep)user$(sep).julia$(sep)测试2$(sep)docs$(sep)api$(sep)测试2.md",
223-
"..$(sep)user$(sep).julia$(sep)测试2$(sep)docs$(sep)api$(sep)测试2.md",
224-
"user$(sep).julia$(sep)测试2$(sep)docs$(sep)api$(sep)测试2.md",
225-
"home$(sep)user$(sep).julia$(sep)测试2$(sep)docs$(sep)api$(sep)测试2.md",
226-
"user$(sep).julia$(sep)测试2$(sep)docs$(sep)api$(sep)测试2.md",
227-
"..$(sep)..$(sep)..$(sep)..$(sep)..$(sep)dir_withendsep",
228-
"..$(sep)..$(sep)home$(sep)user$(sep)dir_withendsep",".","..$(sep)user$(sep)dir_withendsep",
229-
"..$(sep)user$(sep)dir_withendsep","user$(sep)dir_withendsep",
230-
"home$(sep)user$(sep)dir_withendsep","user$(sep)dir_withendsep",
231-
"..$(sep)..$(sep)..$(sep)..$(sep)..$(sep)..$(sep)dir2_withendsep",
232-
"..$(sep)..$(sep)home$(sep)dir2_withendsep","..$(sep)..$(sep)dir2_withendsep",".",
233-
"..$(sep)dir2_withendsep","dir2_withendsep","home$(sep)dir2_withendsep","dir2_withendsep",
234-
"..$(sep)..$(sep)..$(sep)..$(sep)..$(sep)..$(sep)test.md","..$(sep)..$(sep)home$(sep)test.md",
235-
"..$(sep)..$(sep)test.md","..$(sep)test.md",".","test.md","home$(sep)test.md","test.md",
236-
"..$(sep)..$(sep)..$(sep)..$(sep)..$(sep)..","..$(sep)..$(sep)home","..$(sep)..",
237-
"..","..",".","home",".","..$(sep)..$(sep)..$(sep)..$(sep)..$(sep)..$(sep)..","..$(sep)..",
238-
"..$(sep)..$(sep)..","..$(sep)..","..$(sep)..","..",".","..",
239-
"..$(sep)..$(sep)..$(sep)..$(sep)..$(sep)..","..$(sep)..$(sep)home","..$(sep)..",
240-
"..","..",".","home","."
241-
]
242-
idx = 0
243-
for filep in filepaths
244-
for startp in startpaths
245-
res = relpath(filep, startp)
246-
idx += 1
247-
@test res == relpath_expected_results[idx]
175+
@testset "relpath" begin
176+
function test_relpath()
177+
sep = Base.Filesystem.path_separator
178+
filepaths = [
179+
"$(sep)home$(sep)user$(sep).julia$(sep)Test1$(sep)docs$(sep)api$(sep)Test1.md",
180+
"$(sep)home$(sep)user$(sep).julia$(sep)Test1$(sep)docs$(sep)api$(sep)lib$(sep)file1.md",
181+
"$(sep)home$(sep)user$(sep).julia$(sep)测试2$(sep)docs$(sep)api$(sep)测试2.md",
182+
"$(sep)home$(sep)user$(sep)dir_withendsep$(sep)",
183+
"$(sep)home$(sep)dir2_withendsep$(sep)",
184+
"$(sep)home$(sep)test.md",
185+
"$(sep)home",
186+
# Special cases
187+
"$(sep)",
188+
"$(sep)home$(sep)$(sep)$(sep)"
189+
]
190+
startpaths = [
191+
"$(sep)home$(sep)user$(sep).julia$(sep)Test1$(sep)docs$(sep)api$(sep)genindex.md",
192+
"$(sep)multi_docs$(sep)genindex.md",
193+
"$(sep)home$(sep)user$(sep)dir_withendsep$(sep)",
194+
"$(sep)home$(sep)dir2_withendsep$(sep)",
195+
"$(sep)home$(sep)test.md",
196+
"$(sep)home",
197+
# Special cases
198+
"$(sep)",
199+
"$(sep)home$(sep)$(sep)$(sep)"
200+
]
201+
relpath_expected_results = [
202+
"..$(sep)Test1.md",
203+
"..$(sep)..$(sep)home$(sep)user$(sep).julia$(sep)Test1$(sep)docs$(sep)api$(sep)Test1.md",
204+
"..$(sep).julia$(sep)Test1$(sep)docs$(sep)api$(sep)Test1.md",
205+
"..$(sep)user$(sep).julia$(sep)Test1$(sep)docs$(sep)api$(sep)Test1.md",
206+
"..$(sep)user$(sep).julia$(sep)Test1$(sep)docs$(sep)api$(sep)Test1.md",
207+
"user$(sep).julia$(sep)Test1$(sep)docs$(sep)api$(sep)Test1.md",
208+
"home$(sep)user$(sep).julia$(sep)Test1$(sep)docs$(sep)api$(sep)Test1.md",
209+
"user$(sep).julia$(sep)Test1$(sep)docs$(sep)api$(sep)Test1.md",
210+
"..$(sep)lib$(sep)file1.md",
211+
"..$(sep)..$(sep)home$(sep)user$(sep).julia$(sep)Test1$(sep)docs$(sep)api$(sep)lib$(sep)file1.md",
212+
"..$(sep).julia$(sep)Test1$(sep)docs$(sep)api$(sep)lib$(sep)file1.md",
213+
"..$(sep)user$(sep).julia$(sep)Test1$(sep)docs$(sep)api$(sep)lib$(sep)file1.md",
214+
"..$(sep)user$(sep).julia$(sep)Test1$(sep)docs$(sep)api$(sep)lib$(sep)file1.md",
215+
"user$(sep).julia$(sep)Test1$(sep)docs$(sep)api$(sep)lib$(sep)file1.md",
216+
"home$(sep)user$(sep).julia$(sep)Test1$(sep)docs$(sep)api$(sep)lib$(sep)file1.md",
217+
"user$(sep).julia$(sep)Test1$(sep)docs$(sep)api$(sep)lib$(sep)file1.md",
218+
"..$(sep)..$(sep)..$(sep)..$(sep)测试2$(sep)docs$(sep)api$(sep)测试2.md",
219+
"..$(sep)..$(sep)home$(sep)user$(sep).julia$(sep)测试2$(sep)docs$(sep)api$(sep)测试2.md",
220+
"..$(sep).julia$(sep)测试2$(sep)docs$(sep)api$(sep)测试2.md",
221+
"..$(sep)user$(sep).julia$(sep)测试2$(sep)docs$(sep)api$(sep)测试2.md",
222+
"..$(sep)user$(sep).julia$(sep)测试2$(sep)docs$(sep)api$(sep)测试2.md",
223+
"user$(sep).julia$(sep)测试2$(sep)docs$(sep)api$(sep)测试2.md",
224+
"home$(sep)user$(sep).julia$(sep)测试2$(sep)docs$(sep)api$(sep)测试2.md",
225+
"user$(sep).julia$(sep)测试2$(sep)docs$(sep)api$(sep)测试2.md",
226+
"..$(sep)..$(sep)..$(sep)..$(sep)..$(sep)dir_withendsep",
227+
"..$(sep)..$(sep)home$(sep)user$(sep)dir_withendsep",".","..$(sep)user$(sep)dir_withendsep",
228+
"..$(sep)user$(sep)dir_withendsep","user$(sep)dir_withendsep",
229+
"home$(sep)user$(sep)dir_withendsep","user$(sep)dir_withendsep",
230+
"..$(sep)..$(sep)..$(sep)..$(sep)..$(sep)..$(sep)dir2_withendsep",
231+
"..$(sep)..$(sep)home$(sep)dir2_withendsep","..$(sep)..$(sep)dir2_withendsep",".",
232+
"..$(sep)dir2_withendsep","dir2_withendsep","home$(sep)dir2_withendsep","dir2_withendsep",
233+
"..$(sep)..$(sep)..$(sep)..$(sep)..$(sep)..$(sep)test.md","..$(sep)..$(sep)home$(sep)test.md",
234+
"..$(sep)..$(sep)test.md","..$(sep)test.md",".","test.md","home$(sep)test.md","test.md",
235+
"..$(sep)..$(sep)..$(sep)..$(sep)..$(sep)..","..$(sep)..$(sep)home","..$(sep)..",
236+
"..","..",".","home",".","..$(sep)..$(sep)..$(sep)..$(sep)..$(sep)..$(sep)..","..$(sep)..",
237+
"..$(sep)..$(sep)..","..$(sep)..","..$(sep)..","..",".","..",
238+
"..$(sep)..$(sep)..$(sep)..$(sep)..$(sep)..","..$(sep)..$(sep)home","..$(sep)..",
239+
"..","..",".","home","."
240+
]
241+
idx = 0
242+
for filep in filepaths
243+
for startp in startpaths
244+
res = relpath(filep, startp)
245+
idx += 1
246+
@test res == relpath_expected_results[idx]
247+
end
248248
end
249+
# Additional cases
250+
@test_throws ArgumentError relpath(S("$(sep)home$(sep)user$(sep)dir_withendsep$(sep)"), "")
251+
@test_throws ArgumentError relpath(S(""), S("$(sep)home$(sep)user$(sep)dir_withendsep$(sep)"))
249252
end
250-
# Additional cases
251-
@test_throws ArgumentError relpath("$(sep)home$(sep)user$(sep)dir_withendsep$(sep)", "")
252-
@test_throws ArgumentError relpath("", "$(sep)home$(sep)user$(sep)dir_withendsep$(sep)")
253+
test_relpath()
254+
end
255+
256+
@testset "type stability" begin
257+
@test isa(joinpath(S("a"), S("b")), String)
258+
@test isa(joinpath(S(abspath("a")), S("b")), String)
253259
end
254-
test_relpath()
255-
end
256-
@testset "type stability" begin
257-
@test isa(joinpath("a", "b"), String)
258-
@test isa(joinpath(abspath("a"), "b"), String)
259260
end
261+
260262
@testset "homedir" begin
261263
var = Sys.iswindows() ? "USERPROFILE" : "HOME"
262264
AVG_PATH = Base.Filesystem.AVG_PATH - 1 # null-termination character

0 commit comments

Comments
 (0)