Skip to content

Commit cfaac3a

Browse files
committed
make find(first|last|next|prev) return nothing rather than 0:-1
deprecate Base extended methods that did not return nothing, in favor of Compat. versions
1 parent fd3b92a commit cfaac3a

File tree

4 files changed

+140
-43
lines changed

4 files changed

+140
-43
lines changed

README.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -353,7 +353,8 @@ Currently, the `@compat` macro supports the following syntaxes:
353353
sometimes combined with `equalto` or `occursin` ([#24673]).
354354

355355
* `Compat.findfirst`, `Compat.findnext`, `Compat.findlast` and `Compat.findprev`,
356-
return `nothing` when no match is found (rather than `0`) as on Julia 0.7 ([#24673]).
356+
return `nothing` when no match is found (rather than `0` or `0:-1`)
357+
as on Julia 0.7 ([#24673], [#26149]).
357358

358359
* `findin(a, b)` is now `findall(occursin(b), a)` ([#24673]).
359360

@@ -586,4 +587,5 @@ includes this fix. Find the minimum version from there.
586587
[#25990]: https://github.com/JuliaLang/julia/issues/25990
587588
[#26069]: https://github.com/JuliaLang/julia/issues/26069
588589
[#26089]: https://github.com/JuliaLang/julia/issues/26089
590+
[#26149]: https://github.com/JuliaLang/julia/issues/26149
589591
[#26156]: https://github.com/JuliaLang/julia/issues/26156

src/Compat.jl

Lines changed: 31 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1498,46 +1498,47 @@ else
14981498
export occursin
14991499

15001500
zero2nothing(x::Integer) = x == 0 ? nothing : x
1501+
zero2nothing(x::AbstractUnitRange{<:Integer}) = isempty(x) ? nothing : x
15011502
zero2nothing(x) = x
15021503

15031504
findnext(xs...) = zero2nothing(Base.findnext(xs...))
15041505
findfirst(xs...) = zero2nothing(Base.findfirst(xs...))
15051506
findprev(xs...) = zero2nothing(Base.findprev(xs...))
15061507
findlast(xs...) = zero2nothing(Base.findlast(xs...))
15071508

1508-
Base.findnext(r::Regex, s::AbstractString, idx::Integer) = search(s, r, idx)
1509-
Base.findfirst(r::Regex, s::AbstractString) = search(s, r)
1510-
Base.findnext(c::EqualTo{Char}, s::AbstractString, i::Integer) = search(s, c.x, i)
1511-
Base.findfirst(c::EqualTo{Char}, s::AbstractString) = search(s, c.x)
1512-
Base.findnext(b::EqualTo{<:Union{Int8,UInt8}}, a::Vector{<:Union{Int8,UInt8}}, i::Integer) =
1513-
search(a, b.x, i)
1514-
Base.findfirst(b::EqualTo{<:Union{Int8,UInt8}}, a::Vector{<:Union{Int8,UInt8}}) =
1515-
search(a, b.x)
1509+
findnext(r::Regex, s::AbstractString, idx::Integer) = zero2nothing(search(s, r, idx))
1510+
findfirst(r::Regex, s::AbstractString) = zero2nothing(search(s, r))
1511+
findnext(c::EqualTo{Char}, s::AbstractString, i::Integer) = zero2nothing(search(s, c.x, i))
1512+
findfirst(c::EqualTo{Char}, s::AbstractString) = zero2nothing(search(s, c.x))
1513+
findnext(b::EqualTo{<:Union{Int8,UInt8}}, a::Vector{<:Union{Int8,UInt8}}, i::Integer) =
1514+
zero2nothing(search(a, b.x, i))
1515+
findfirst(b::EqualTo{<:Union{Int8,UInt8}}, a::Vector{<:Union{Int8,UInt8}}) =
1516+
zero2nothing(search(a, b.x))
15161517

1517-
Base.findnext(c::OccursIn{<:Union{Tuple{Vararg{Char}},AbstractVector{Char},Set{Char}}},
1518+
findnext(c::OccursIn{<:Union{Tuple{Vararg{Char}},AbstractVector{Char},Set{Char}}},
15181519
s::AbstractString, i::Integer) =
1519-
search(s, c.x, i)
1520-
Base.findfirst(c::OccursIn{<:Union{Tuple{Vararg{Char}},AbstractVector{Char},Set{Char}}},
1520+
zero2nothing(search(s, c.x, i))
1521+
findfirst(c::OccursIn{<:Union{Tuple{Vararg{Char}},AbstractVector{Char},Set{Char}}},
15211522
s::AbstractString) =
1522-
search(s, c.x)
1523-
Base.findnext(t::AbstractString, s::AbstractString, i::Integer) = search(s, t, i)
1524-
Base.findfirst(t::AbstractString, s::AbstractString) = search(s, t)
1525-
1526-
Base.findfirst(delim::EqualTo{UInt8}, buf::Base.IOBuffer) = search(buf, delim.x)
1527-
1528-
Base.findprev(c::EqualTo{Char}, s::AbstractString, i::Integer) = rsearch(s, c.x, i)
1529-
Base.findlast(c::EqualTo{Char}, s::AbstractString) = rsearch(s, c.x)
1530-
Base.findprev(b::EqualTo{<:Union{Int8,UInt8}}, a::Vector{<:Union{Int8,UInt8}}, i::Integer) =
1531-
rsearch(a, b.x, i)
1532-
Base.findlast(b::EqualTo{<:Union{Int8,UInt8}}, a::Vector{<:Union{Int8,UInt8}}) =
1533-
rsearch(a, b.x)
1534-
1535-
Base.findprev(c::OccursIn{<:Union{Tuple{Vararg{Char}},AbstractVector{Char},Set{Char}}},
1536-
s::AbstractString, i::Integer) = rsearch(s, c.x, i)
1537-
Base.findlast(c::OccursIn{<:Union{Tuple{Vararg{Char}},AbstractVector{Char},Set{Char}}},
1538-
s::AbstractString) = rsearch(s, c.x)
1539-
Base.findprev(t::AbstractString, s::AbstractString, i::Integer) = rsearch(s, t, i)
1540-
Base.findlast(t::AbstractString, s::AbstractString) = rsearch(s, t)
1523+
zero2nothing(search(s, c.x))
1524+
findnext(t::AbstractString, s::AbstractString, i::Integer) = zero2nothing(search(s, t, i))
1525+
findfirst(t::AbstractString, s::AbstractString) = zero2nothing(search(s, t))
1526+
1527+
findfirst(delim::EqualTo{UInt8}, buf::IOBuffer) = zero2nothing(search(buf, delim.x))
1528+
1529+
findprev(c::EqualTo{Char}, s::AbstractString, i::Integer) = zero2nothing(rsearch(s, c.x, i))
1530+
findlast(c::EqualTo{Char}, s::AbstractString) = zero2nothing(rsearch(s, c.x))
1531+
findprev(b::EqualTo{<:Union{Int8,UInt8}}, a::Vector{<:Union{Int8,UInt8}}, i::Integer) =
1532+
zero2nothing(rsearch(a, b.x, i))
1533+
findlast(b::EqualTo{<:Union{Int8,UInt8}}, a::Vector{<:Union{Int8,UInt8}}) =
1534+
zero2nothing(rsearch(a, b.x))
1535+
1536+
findprev(c::OccursIn{<:Union{Tuple{Vararg{Char}},AbstractVector{Char},Set{Char}}},
1537+
s::AbstractString, i::Integer) = zero2nothing(rsearch(s, c.x, i))
1538+
findlast(c::OccursIn{<:Union{Tuple{Vararg{Char}},AbstractVector{Char},Set{Char}}},
1539+
s::AbstractString) = zero2nothing(rsearch(s, c.x))
1540+
findprev(t::AbstractString, s::AbstractString, i::Integer) = zero2nothing(rsearch(s, t, i))
1541+
findlast(t::AbstractString, s::AbstractString) = zero2nothing(rsearch(s, t))
15411542

15421543
findall(b::OccursIn, a) = findin(a, b.x)
15431544
# To fix ambiguity

src/deprecated.jl

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,3 +56,101 @@ if VERSION < v"0.7.0-DEV.2915"
5656
const textwidth = Compat.Unicode.textwidth
5757
export textwidth
5858
end
59+
60+
@static if VERSION < v"0.7.0-DEV.3272"
61+
function Base.findnext(r::Regex, s::AbstractString, idx::Integer)
62+
Base.depwarn(string("Compat.jl's implementation of Base.findnext(r::Regex, s::AbstractString, idx::Integer) is deprecated, ",
63+
"use Compat.findnext(r, s, idx) instead, which returns `nothing` to indicate no match."), :findnext)
64+
search(s, r, idx)
65+
end
66+
function Base.findfirst(r::Regex, s::AbstractString)
67+
Base.depwarn(string("Compat.jl's implementation of Base.findfirst(r::Regex, s::AbstractString) is deprecated, ",
68+
"use Compat.findfirst(r, s) instead, which returns `nothing` to indicate no match."), :findfirst)
69+
search(s, r)
70+
end
71+
function Base.findnext(c::EqualTo{Char}, s::AbstractString, i::Integer)
72+
Base.depwarn(string("Compat.jl's implementation of Base.findnext(c::EqualTo{Char}, s::AbstractString, i::Integer) is deprecated, ",
73+
"use Compat.findnext(c, s, i) instead, which returns `nothing` to indicate no match."), :findnext)
74+
search(s, c.x, i)
75+
end
76+
function Base.findfirst(c::EqualTo{Char}, s::AbstractString)
77+
Base.depwarn(string("Compat.jl's implementation of Base.findfirst(c::EqualTo{Char}, s::AbstractString) is deprecated, ",
78+
"use Compat.findfirst(c, s) instead, which returns `nothing` to indicate no match."), :findfirst)
79+
search(s, c.x)
80+
end
81+
function Base.findnext(b::EqualTo{<:Union{Int8,UInt8}}, a::Vector{<:Union{Int8,UInt8}}, i::Integer)
82+
Base.depwarn(string("Compat.jl's implementation of Base.findnext(b::EqualTo{<:Union{Int8,UInt8}}, a::Vector{<:Union{Int8,UInt8}}, i::Integer) is deprecated, ",
83+
"use Compat.findnext(b, a, i) instead, which returns `nothing` to indicate no match."), :findnext)
84+
search(a, b.x, i)
85+
end
86+
function Base.findfirst(b::EqualTo{<:Union{Int8,UInt8}}, a::Vector{<:Union{Int8,UInt8}})
87+
Base.depwarn(string("Compat.jl's implementation of Base.findfirst(b::EqualTo{<:Union{Int8,UInt8}}, a::Vector{<:Union{Int8,UInt8}}) is deprecated, ",
88+
"use Compat.findfirst(b, a) instead, which returns `nothing` to indicate no match."), :findfirst)
89+
search(a, b.x)
90+
end
91+
function Base.findnext(c::OccursIn{<:Union{Tuple{Vararg{Char}},AbstractVector{Char},Set{Char}}}, s::AbstractString, i::Integer)
92+
Base.depwarn(string("Compat.jl's implementation of Base.findnext(c::OccursIn{<:Union{Tuple{Vararg{Char}},AbstractVector{Char},Set{Char}}}, s::AbstractString, i::Integer) is deprecated, ",
93+
"use Compat.findnext(c, s, i) instead, which returns `nothing` to indicate no match."), :findnext)
94+
search(s, c.x, i)
95+
end
96+
function Base.findfirst(c::OccursIn{<:Union{Tuple{Vararg{Char}},AbstractVector{Char},Set{Char}}}, s::AbstractString)
97+
Base.depwarn(string("Compat.jl's implementation of Base.findfirst(c::OccursIn{<:Union{Tuple{Vararg{Char}},AbstractVector{Char},Set{Char}}}, s::AbstractString) is deprecated, ",
98+
"use Compat.findfirst(c, s) instead, which returns `nothing` to indicate no match."), :findfirst)
99+
search(s, c.x)
100+
end
101+
function Base.findnext(t::AbstractString, s::AbstractString, i::Integer)
102+
Base.depwarn(string("Compat.jl's implementation of Base.findnext(t::AbstractString, s::AbstractString, i::Integer) is deprecated, ",
103+
"use Compat.findnext(t, s, i) instead, which returns `nothing` to indicate no match."), :findnext)
104+
search(s, t, i)
105+
end
106+
function Base.findfirst(t::AbstractString, s::AbstractString)
107+
Base.depwarn(string("Compat.jl's implementation of Base.findfirst(t::AbstractString, s::AbstractString) is deprecated, ",
108+
"use Compat.findfirst(t, s) instead, which returns `nothing` to indicate no match."), :findfirst)
109+
search(s, t)
110+
end
111+
function Base.findfirst(delim::EqualTo{UInt8}, buf::Base.IOBuffer)
112+
Base.depwarn(string("Compat.jl's implementation of Base.findfirst(delim::EqualTo{UInt8}, buf::Base.IOBuffer) is deprecated, ",
113+
"use Compat.findfirst(delim, buf) instead, which returns `nothing` to indicate no match."), :findfirst)
114+
search(buf, delim.x)
115+
end
116+
function Base.findprev(c::EqualTo{Char}, s::AbstractString, i::Integer)
117+
Base.depwarn(string("Compat.jl's implementation of Base.findprev(c::EqualTo{Char}, s::AbstractString, i::Integer) is deprecated, ",
118+
"use Compat.findprev(c, s, i) instead, which returns `nothing` to indicate no match."), :findprev)
119+
rsearch(s, c.x, i)
120+
end
121+
function Base.findlast(c::EqualTo{Char}, s::AbstractString)
122+
Base.depwarn(string("Compat.jl's implementation of Base.findlast(c::EqualTo{Char}, s::AbstractString) is deprecated, ",
123+
"use Compat.findlast(c, s) instead, which returns `nothing` to indicate no match."), :findlast)
124+
rsearch(s, c.x)
125+
end
126+
function Base.findprev(b::EqualTo{<:Union{Int8,UInt8}}, a::Vector{<:Union{Int8,UInt8}}, i::Integer)
127+
Base.depwarn(string("Compat.jl's implementation of Base.findprev(b::EqualTo{<:Union{Int8,UInt8}}, a::Vector{<:Union{Int8,UInt8}}, i::Integer) is deprecated, ",
128+
"use Compat.findprev(b, a, i) instead, which returns `nothing` to indicate no match."), :findprev)
129+
rsearch(a, b.x, i)
130+
end
131+
function Base.findlast(b::EqualTo{<:Union{Int8,UInt8}}, a::Vector{<:Union{Int8,UInt8}})
132+
Base.depwarn(string("Compat.jl's implementation of Base.findlast(b::EqualTo{<:Union{Int8,UInt8}}, a::Vector{<:Union{Int8,UInt8}}) is deprecated, ",
133+
"use Compat.findlast(b, a) instead, which returns `nothing` to indicate no match."), :findlast)
134+
rsearch(a, b.x)
135+
end
136+
function Base.findprev(c::OccursIn{<:Union{Tuple{Vararg{Char}},AbstractVector{Char},Set{Char}}}, s::AbstractString, i::Integer)
137+
Base.depwarn(string("Compat.jl's implementation of Base.findprev(c::OccursIn{<:Union{Tuple{Vararg{Char}},AbstractVector{Char},Set{Char}}}, s::AbstractString, i::Integer) is deprecated, ",
138+
"use Compat.findprev(c, s, i) instead, which returns `nothing` to indicate no match."), :findprev)
139+
rsearch(s, c.x, i)
140+
end
141+
function Base.findlast(c::OccursIn{<:Union{Tuple{Vararg{Char}},AbstractVector{Char},Set{Char}}}, s::AbstractString)
142+
Base.depwarn(string("Compat.jl's implementation of Base.findlast(c::OccursIn{<:Union{Tuple{Vararg{Char}},AbstractVector{Char},Set{Char}}}, s::AbstractString) is deprecated, ",
143+
"use Compat.findlast(c, s) instead, which returns `nothing` to indicate no match."), :findlast)
144+
rsearch(s, c.x)
145+
end
146+
function Base.findprev(t::AbstractString, s::AbstractString, i::Integer)
147+
Base.depwarn(string("Compat.jl's implementation of Base.findprev(t::AbstractString, s::AbstractString, i::Integer) is deprecated, ",
148+
"use Compat.findprev(t, s, i) instead, which returns `nothing` to indicate no match."), :findprev)
149+
rsearch(s, t, i)
150+
end
151+
function Base.findlast(t::AbstractString, s::AbstractString)
152+
Base.depwarn(string("Compat.jl's implementation of Base.findlast(t::AbstractString, s::AbstractString) is deprecated, ",
153+
"use Compat.findlast(t, s) instead, which returns `nothing` to indicate no match."), :findlast)
154+
rsearch(s, t)
155+
end
156+
end

test/runtests.jl

Lines changed: 8 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1378,18 +1378,14 @@ for (f1, f2, i) in ((Compat.findfirst, Compat.findnext, 1),
13781378
@test f2(occursin(chars), "bx", i) == f1(occursin(chars), "bx") == nothing
13791379
end
13801380
end
1381-
for (f1, f2, i) in ((findfirst, findnext, 1),
1382-
(findlast, findprev, 2),
1383-
(Compat.findfirst, Compat.findnext, 1),
1384-
(Compat.findlast, Compat.findprev, 2))
1385-
@test f2("a", "ba", i) == f1("a", "ba") == 2:2
1386-
@test f2("z", "ba", i) == f1("z", "ba") == 0:-1
1387-
end
1388-
for (f1, f2, i) in ((findfirst, findnext, 1),
1389-
(Compat.findfirst, Compat.findnext, 1))
1390-
@test f2(r"a", "ba", 1) == f1(r"a", "ba") == 2:2
1391-
@test f2(r"z", "ba", 1) == f1(r"z", "ba") == 0:-1
1392-
end
1381+
1382+
@test Compat.findnext("a", "ba", 1) == Compat.findfirst("a", "ba") == 2:2
1383+
@test Compat.findnext("z", "ba", 1) == Compat.findfirst("z", "ba") == nothing
1384+
@test Compat.findprev("a", "ba", 2) == Compat.findlast("a", "ba") == 2:2
1385+
@test Compat.findprev("z", "ba", 2) == Compat.findlast("z", "ba") == nothing
1386+
1387+
@test Compat.findnext(r"a", "ba", 1) == Compat.findfirst(r"a", "ba") == 2:2
1388+
@test Compat.findnext(r"z", "ba", 1) == Compat.findfirst(r"z", "ba") == nothing
13931389

13941390
@test Compat.findfirst(equalto(UInt8(0)), IOBuffer(UInt8[1, 0])) == 2
13951391
@test Compat.findfirst(equalto(UInt8(9)), IOBuffer(UInt8[1, 0])) == nothing

0 commit comments

Comments
 (0)