Skip to content

Commit

Permalink
Deprecate tryparse(T, s) in favor of tryparse(Union{T, Void}, s)
Browse files Browse the repository at this point in the history
  • Loading branch information
nalimilan committed Dec 16, 2017
1 parent 4570ca7 commit 487603a
Show file tree
Hide file tree
Showing 16 changed files with 70 additions and 43 deletions.
4 changes: 4 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -804,6 +804,9 @@ Deprecated or removed

* `sub2ind` and `ind2sub` are deprecated in favor of using `CartesianIndices` and `LinearIndices` ([#24715]).

* `tryparse(T, s[, base])` has been deprecated in favor of `parse(Union{T, Void}, s[, base])`
([#25130]).

Command-line option changes
---------------------------

Expand Down Expand Up @@ -1784,3 +1787,4 @@ Command-line option changes
[#24869]: https://github.com/JuliaLang/julia/issues/24869
[#25021]: https://github.com/JuliaLang/julia/issues/25021
[#25088]: https://github.com/JuliaLang/julia/issues/25088
[#25130]: https://github.com/JuliaLang/julia/issues/25130
2 changes: 1 addition & 1 deletion base/client.jl
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ color_normal = text_colors[:normal]

function repl_color(key, default)
env_str = get(ENV, key, "")
c = tryparse(Int, env_str)
c = parse(Union{Int, Void}, env_str)
c_conv = coalesce(c, Symbol(env_str))
haskey(text_colors, c_conv) ? c_conv : default
end
Expand Down
3 changes: 3 additions & 0 deletions base/deprecated.jl
Original file line number Diff line number Diff line change
Expand Up @@ -3411,6 +3411,9 @@ end
# PR #25113
@deprecate_binding CartesianRange CartesianIndices

@deprecate tryparse(T::Type, str::AbstractString) parse(Union{T, Void}, str)
@deprecate tryparse(T::Type, str::AbstractString, base::Integer) parse(Union{T, Void}, str, base)

# END 0.7 deprecations

# BEGIN 1.0 deprecations
Expand Down
1 change: 0 additions & 1 deletion base/exports.jl
Original file line number Diff line number Diff line change
Expand Up @@ -316,7 +316,6 @@ export
fldmod1,
flipsign,
float,
tryparse,
floor,
fma,
frexp,
Expand Down
6 changes: 3 additions & 3 deletions base/int.jl
Original file line number Diff line number Diff line change
Expand Up @@ -602,12 +602,12 @@ macro big_str(s)
end
print(bf, s[end])
seekstart(bf)
n = tryparse(BigInt, String(take!(bf)))
n = parse(Union{BigInt, Void}, String(take!(bf)))
n === nothing || return n
else
n = tryparse(BigInt, s)
n = parse(Union{BigInt, Void}, s)
n === nothing || return n
n = tryparse(BigFloat, s)
n = parse(Union{BigFloat, Void}, s)
n === nothing || return n
end
message = "invalid number format $s for BigInt or BigFloat"
Expand Down
6 changes: 3 additions & 3 deletions base/mpfr.jl
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import
eps, signbit, sin, cos, sincos, tan, sec, csc, cot, acos, asin, atan,
cosh, sinh, tanh, sech, csch, coth, acosh, asinh, atanh, atan2,
cbrt, typemax, typemin, unsafe_trunc, realmin, realmax, rounding,
setrounding, maxintfloat, widen, significand, frexp, tryparse, iszero,
setrounding, maxintfloat, widen, significand, frexp, parse, iszero,
isone, big

import Base.Rounding: rounding_raw, setrounding_raw
Expand Down Expand Up @@ -121,8 +121,8 @@ convert(::Type{BigFloat}, x::Union{UInt8,UInt16,UInt32}) = BigFloat(convert(Culo
convert(::Type{BigFloat}, x::Union{Float16,Float32}) = BigFloat(Float64(x))
convert(::Type{BigFloat}, x::Rational) = BigFloat(numerator(x)) / BigFloat(denominator(x))

function tryparse(::Type{BigFloat}, s::AbstractString, base::Int=0)
!isempty(s) && Base.Unicode.isspace(s[end]) && return tryparse(BigFloat, rstrip(s), base)
function parse(::Type{Union{BigFloat, Void}}, s::AbstractString, base::Int=0)
!isempty(s) && Base.Unicode.isspace(s[end]) && return parse(Union{BigFloat, Void}, rstrip(s), base)
z = BigFloat()
err = ccall((:mpfr_set_str, :libmpfr), Int32, (Ref{BigFloat}, Cstring, Int32, Int32), z, s, base, ROUNDING_MODE[])
err == 0 ? z : nothing
Expand Down
36 changes: 24 additions & 12 deletions base/parse.jl
Original file line number Diff line number Diff line change
Expand Up @@ -202,14 +202,23 @@ end
end

"""
tryparse(type, str, [base])
parse(::Type{Union{T, Void}}, str, [base])
Like [`parse`](@ref), but returns either a value of the requested type,
Like [`parse`](@ref), but returns either a value of the requested type `T`,
or [`nothing`](@ref) if the string does not contain a valid number.
# Examples
```jldoctest
julia> parse(Union{Int, Void}, "1")
1
julia> parse(Union{Int, Void}, "a") === nothing
true
```
"""
tryparse(::Type{T}, s::AbstractString, base::Integer) where {T<:Integer} =
parse(::Type{Union{T, Void}}, s::AbstractString, base::Integer) where {T<:Integer} =
tryparse_internal(T, s, start(s), endof(s), check_valid_base(base), false)
tryparse(::Type{T}, s::AbstractString) where {T<:Integer} =
parse(::Type{Union{T, Void}}, s::AbstractString) where {T<:Integer} =
tryparse_internal(T, s, start(s), endof(s), 0, false)

function parse(::Type{T}, s::AbstractString, base::Integer) where T<:Integer
Expand All @@ -222,12 +231,12 @@ end

## string to float functions ##

function tryparse(::Type{Float64}, s::String)
function parse(::Type{Union{Float64, Void}}, s::String)
hasvalue, val = ccall(:jl_try_substrtod, Tuple{Bool, Float64},
(Ptr{UInt8},Csize_t,Csize_t), s, 0, sizeof(s))
hasvalue ? val : nothing
end
function tryparse(::Type{Float64}, s::SubString{String})
function parse(::Type{Union{Float64, Void}}, s::SubString{String})
hasvalue, val = ccall(:jl_try_substrtod, Tuple{Bool, Float64},
(Ptr{UInt8},Csize_t,Csize_t), s.string, s.offset, s.ncodeunits)
hasvalue ? val : nothing
Expand All @@ -242,12 +251,12 @@ function tryparse_internal(::Type{Float64}, s::SubString{String}, startpos::Int,
(Ptr{UInt8},Csize_t,Csize_t), s.string, s.offset+startpos-1, endpos-startpos+1)
hasvalue ? val : nothing
end
function tryparse(::Type{Float32}, s::String)
function parse(::Type{Union{Float32, Void}}, s::String)
hasvalue, val = ccall(:jl_try_substrtof, Tuple{Bool, Float32},
(Ptr{UInt8},Csize_t,Csize_t), s, 0, sizeof(s))
hasvalue ? val : nothing
end
function tryparse(::Type{Float32}, s::SubString{String})
function parse(::Type{Union{Float32, Void}}, s::SubString{String})
hasvalue, val = ccall(:jl_try_substrtof, Tuple{Bool, Float32},
(Ptr{UInt8},Csize_t,Csize_t), s.string, s.offset, s.ncodeunits)
hasvalue ? val : nothing
Expand All @@ -262,9 +271,10 @@ function tryparse_internal(::Type{Float32}, s::SubString{String}, startpos::Int,
(Ptr{UInt8},Csize_t,Csize_t), s.string, s.offset+startpos-1, endpos-startpos+1)
hasvalue ? val : nothing
end
tryparse(::Type{T}, s::AbstractString) where {T<:Union{Float32,Float64}} = tryparse(T, String(s))
tryparse(::Type{Float16}, s::AbstractString) =
convert(Union{Float16, Void}, tryparse(Float32, s))
parse(::Type{Union{T, Void}}, s::AbstractString) where {T<:Union{Float32,Float64}} =
parse(Union{T, Void}, String(s))
parse(::Type{Union{Float16, Void}}, s::AbstractString) =
convert(Union{Float16, Void}, parse(Union{Float32, Void}, s))
tryparse_internal(::Type{Float16}, s::AbstractString, startpos::Int, endpos::Int) =
convert(Union{Float16, Void}, tryparse_internal(Float32, s, startpos, endpos))

Expand Down Expand Up @@ -331,7 +341,9 @@ tryparse_internal(T::Type{<:Complex}, s::AbstractString, i::Int, e::Int, raise::

# fallback methods for tryparse_internal
tryparse_internal(::Type{T}, s::AbstractString, startpos::Int, endpos::Int) where T<:Real =
startpos == start(s) && endpos == endof(s) ? tryparse(T, s) : tryparse(T, SubString(s, startpos, endpos))
startpos == start(s) && endpos == endof(s) ?
parse(Union{T, Void}, s) :
parse(Union{T, Void}, SubString(s, startpos, endpos))
function tryparse_internal(::Type{T}, s::AbstractString, startpos::Int, endpos::Int, raise::Bool) where T<:Real
result = tryparse_internal(T, s, startpos, endpos)
if raise && result === nothing
Expand Down
2 changes: 1 addition & 1 deletion base/repl/REPL.jl
Original file line number Diff line number Diff line change
Expand Up @@ -979,7 +979,7 @@ function setup_interface(
"^Q" => (s, o...) -> begin
linfos = Base.LAST_SHOWN_LINE_INFOS
str = String(take!(LineEdit.buffer(s)))
n = tryparse(Int, str)
n = parse(Union{Int, Void}, str)
n === nothing && @goto writeback
if n <= 0 || n > length(linfos) || startswith(linfos[n][1], "./REPL")
@goto writeback
Expand Down
2 changes: 1 addition & 1 deletion doc/src/stdlib/numbers.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ Base.digits
Base.digits!
Base.bitstring
Base.parse(::Type, ::Any, ::Any)
Base.tryparse
Base.parse(::Type{Union{T, Void}}, ::AbstractString, ::Integer) where {T<:Integer}
Base.big
Base.signed
Base.unsigned
Expand Down
4 changes: 3 additions & 1 deletion stdlib/Dates/src/parse.jl
Original file line number Diff line number Diff line change
Expand Up @@ -270,7 +270,9 @@ function Base.parse(::Type{T}, str::AbstractString, df::DateFormat=default_forma
T(values...)
end

function Base.tryparse(::Type{T}, str::AbstractString, df::DateFormat=default_format(T)) where T<:TimeType
function Base.parse(::Type{Union{T, Void}},
str::AbstractString,
df::DateFormat=default_format(T)) where T<:TimeType
pos, len = start(str), endof(str)
values, pos = tryparsenext_internal(T, str, pos, len, df, false)
if values === nothing
Expand Down
5 changes: 3 additions & 2 deletions stdlib/Dates/src/types.jl
Original file line number Diff line number Diff line change
Expand Up @@ -147,9 +147,10 @@ daysinmonth(y,m) = DAYSINMONTH[m] + (m == 2 && isleapyear(y))
### UTILITIES ###

# These are necessary because the type constructors for TimeType subtypes can
# throw, and we want to be able to use tryparse without requiring a try/catch.
# throw, and we want to be able to use parse(Union{T, Void}, ...) without
# requiring a try/catch.
# This is made easier by providing a helper function that checks arguments, so
# we can validate arguments in tryparse.
# we can validate arguments in parse(Union{T, Void}, ...).

"""
validargs(::Type{<:TimeType}, args...) -> Union{ArgumentError, Void}
Expand Down
2 changes: 1 addition & 1 deletion stdlib/Dates/test/io.jl
Original file line number Diff line number Diff line change
Expand Up @@ -439,7 +439,7 @@ end
end
end
# Issue #21504
@test tryparse(Dates.Date, "0-1000") === nothing
@test parse(Union{Dates.Date, Void}, "0-1000") === nothing

@testset "parse milliseconds, Issue #22100" begin
@test Dates.DateTime("2017-Mar-17 00:00:00.0000", "y-u-d H:M:S.s") == Dates.DateTime(2017, 3, 17)
Expand Down
6 changes: 6 additions & 0 deletions test/ambiguous.jl
Original file line number Diff line number Diff line change
Expand Up @@ -290,6 +290,12 @@ end
pop!(need_to_handle_undef_sparam, which(Base.nonmissingtype, Tuple{Type{Union{Missing, T}} where T}))
pop!(need_to_handle_undef_sparam, which(Base.convert, (Type{Union{Some{T}, Void}} where T, Some)))
pop!(need_to_handle_undef_sparam, which(Base.convert, (Type{Union{T, Void}} where T, Some)))
using Dates
pop!(need_to_handle_undef_sparam, which(Base.parse, (Type{Union{Void, T}} where T<:Union{Float32, Float64}, AbstractString)))
pop!(need_to_handle_undef_sparam, which(Base.parse, (Type{Union{Void, T}} where T<:Dates.TimeType, AbstractString)))
pop!(need_to_handle_undef_sparam, which(Base.parse, (Type{Union{Void, T}} where T<:Integer, AbstractString, Integer)))
pop!(need_to_handle_undef_sparam, which(Base.parse, (Type{Union{Void, T}} where T<:Dates.TimeType, AbstractString, Dates.DateFormat)))
pop!(need_to_handle_undef_sparam, which(Base.parse, (Type{Union{Void, T}} where T<:Integer, AbstractString)))
@test need_to_handle_undef_sparam == Set()
end
end
Expand Down
14 changes: 7 additions & 7 deletions test/parse.jl
Original file line number Diff line number Diff line change
Expand Up @@ -212,22 +212,22 @@ end
@test parse(Int, "2") === 2
@test parse(Bool, "true") === true
@test parse(Bool, "false") === false
@test tryparse(Bool, "true") === true
@test tryparse(Bool, "false") === false
@test parse(Union{Bool, Void}, "true") === true
@test parse(Union{Bool, Void}, "false") === false
@test_throws ArgumentError parse(Int, "2", 1)
@test_throws ArgumentError parse(Int, "2", 63)

# issue #17333: tryparse should still throw on invalid base
# issue #17333: parse(Union{T, Void}, ...) should still throw on invalid base
for T in (Int32, BigInt), base in (0,1,100)
@test_throws ArgumentError tryparse(T, "0", base)
@test_throws ArgumentError parse(Union{T, Void}, "0", base)
end

# error throwing branch from #10560
@test_throws ArgumentError Base.tryparse_internal(Bool, "foo", 1, 2, 10, true)

@test tryparse(Float64, "1.23") === 1.23
@test tryparse(Float32, "1.23") === 1.23f0
@test tryparse(Float16, "1.23") === Float16(1.23)
@test parse(Union{Float64, Void}, "1.23") === 1.23
@test parse(Union{Float32, Void}, "1.23") === 1.23f0
@test parse(Union{Float16, Void}, "1.23") === Float16(1.23)

# parsing complex numbers (#22250)
@testset "complex parsing" begin
Expand Down
2 changes: 1 addition & 1 deletion test/spawn.jl
Original file line number Diff line number Diff line change
Expand Up @@ -451,7 +451,7 @@ end
# test for proper handling of FD exhaustion
if Sys.isunix()
let ps = Pipe[]
ulimit_n = tryparse(Int, readchomp(`sh -c 'ulimit -n'`))
ulimit_n = parse(Union{Int, Void}, readchomp(`sh -c 'ulimit -n'`))
try
for i = 1 : 100 * coalesce(ulimit_n, 1000)
p = Pipe()
Expand Down
18 changes: 9 additions & 9 deletions test/strings/basic.jl
Original file line number Diff line number Diff line change
Expand Up @@ -260,14 +260,14 @@ end
for T in [Int8, UInt8, Int16, UInt16, Int32, UInt32, Int64, UInt64, Int128, UInt128]
for i in [typemax(T), typemin(T)]
s = "$i"
@test tryparse(T, s) == i
@test parse(Union{T, Void}, s) == i
end
end

for T in [Int8, Int16, Int32, Int64, Int128]
for i in [typemax(T), typemin(T)]
f = "$(i)0"
@test tryparse(T, f) === nothing
@test parse(Union{T, Void}, f) === nothing
end
end
end
Expand All @@ -284,21 +284,21 @@ end
@test unsafe_string(sp,5) == "abcde"
@test typeof(unsafe_string(sp)) == String

@test tryparse(BigInt, "1234567890") == BigInt(1234567890)
@test tryparse(BigInt, "1234567890-") === nothing
@test parse(Union{BigInt, Void}, "1234567890") == BigInt(1234567890)
@test parse(Union{BigInt, Void}, "1234567890-") === nothing

@test tryparse(Float64, "64") == 64.0
@test tryparse(Float64, "64o") === nothing
@test tryparse(Float32, "32") == 32.0f0
@test tryparse(Float32, "32o") === nothing
@test parse(Union{Float64, Void}, "64") == 64.0
@test parse(Union{Float64, Void}, "64o") === nothing
@test parse(Union{Float32, Void}, "32") == 32.0f0
@test parse(Union{Float32, Void}, "32o") === nothing
end

@testset "issue #10994: handle embedded NUL chars for string parsing" begin
for T in [BigInt, Int8, UInt8, Int16, UInt16, Int32, UInt32, Int64, UInt64, Int128, UInt128]
@test_throws ArgumentError parse(T, "1\0")
end
for T in [BigInt, Int8, UInt8, Int16, UInt16, Int32, UInt32, Int64, UInt64, Int128, UInt128, Float64, Float32]
@test tryparse(T, "1\0") === nothing
@test parse(Union{T, Void}, "1\0") === nothing
end
let s = Base.Unicode.normalize("tést",:NFKC)
@test unsafe_string(Base.unsafe_convert(Cstring, Base.cconvert(Cstring, s))) == s
Expand Down

0 comments on commit 487603a

Please sign in to comment.