Skip to content

Commit

Permalink
Loosen type restriction on Ryu.writeshortest (#57172)
Browse files Browse the repository at this point in the history
`Ryu.writeshortest` is documented to have a method that "allows passing
in a byte buffer", just like `Ryu.writefixed` and `Ryu.writeexp`, but
unlike those functions `writeshortest` is type constrained to
`::Vector{UInt8}`. This PR loosens that to `::AbstractVector{UInt8}`, to
allow the "byte buffer" to e.g. be a `Memory` rather than a `Vector`.

I've added tests and updated the docstrings for all three functions to
ensure that they're not just restricted to `Vector{UInt8}`.

This change was prompted by our private codebase hitting `MethodError:
no method matching writeshortest(::Memory{UInt8}, ::Int64, ::Float64,
...)` when trying it out with Julia v1.12.0-DEV.
 
(cc @quinnj -- i think you added this method originally, but i couldn't
see any reason why e.g. Memory shouldn't be allowed now we have it)
  • Loading branch information
nickrobinson251 authored Jan 28, 2025
1 parent eff8ba4 commit 8560318
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 4 deletions.
6 changes: 3 additions & 3 deletions base/ryu/Ryu.jl
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ neededdigits(::Type{Float16}) = 9 + 5 + 9

"""
Ryu.writeshortest(x, plus=false, space=false, hash=true, precision=-1, expchar=UInt8('e'), padexp=false, decchar=UInt8('.'), typed=false, compact=false)
Ryu.writeshortest(buf::Vector{UInt8}, pos::Int, x, args...)
Ryu.writeshortest(buf::AbstractVector{UInt8}, pos::Int, x, args...)
Convert a float value `x` into its "shortest" decimal string, which can be parsed back to the same value.
This function allows achieving the `%g` printf format.
Expand Down Expand Up @@ -53,7 +53,7 @@ end

"""
Ryu.writefixed(x, precision, plus=false, space=false, hash=false, decchar=UInt8('.'), trimtrailingzeros=false)
Ryu.writefixed(buf::Vector{UInt8}, pos::Int, x, args...)
Ryu.writefixed(buf::AbstractVector{UInt8}, pos::Int, x, args...)
Convert a float value `x` into a "fixed" size decimal string of the provided precision.
This function allows achieving the `%f` printf format.
Expand Down Expand Up @@ -81,7 +81,7 @@ end

"""
Ryu.writeexp(x, precision, plus=false, space=false, hash=false, expchar=UInt8('e'), decchar=UInt8('.'), trimtrailingzeros=false)
Ryu.writeexp(buf::Vector{UInt8}, pos::Int, x, args...)
Ryu.writeexp(buf::AbstractVector{UInt8}, pos::Int, x, args...)
Convert a float value `x` into a scientific notation decimal string.
This function allows achieving the `%e` printf format.
Expand Down
2 changes: 1 addition & 1 deletion base/ryu/shortest.jl
Original file line number Diff line number Diff line change
Expand Up @@ -224,7 +224,7 @@ integer. If a `maxsignif` argument is provided, then `b < maxsignif`.
return b, e10
end

function writeshortest(buf::Vector{UInt8}, pos, x::T,
function writeshortest(buf::AbstractVector{UInt8}, pos, x::T,
plus=false, space=false, hash=true,
precision=-1, expchar=UInt8('e'), padexp=false, decchar=UInt8('.'),
typed=false, compact=false) where {T}
Expand Down
51 changes: 51 additions & 0 deletions test/ryu.jl
Original file line number Diff line number Diff line change
Expand Up @@ -370,6 +370,23 @@ end

end # Float16

@testset "writeshortest(::AbstractVector, pos, ...)" begin
@testset for Vec in (Vector{UInt8}, Memory{UInt8})
buf = Vec(undef, 4)
@test Ryu.writeshortest(buf, 1, -0.0) == 5
@test String(buf) == "-0.0"

buf = Vec(undef, 100)
xx = 4.7223665f21
expected = "4.7223665e21"
start_pos = 42
nwritten = length(expected)
end_pos = start_pos + nwritten
@test Ryu.writeshortest(buf, start_pos, xx) == end_pos
@test String(buf[start_pos:end_pos-1]) == expected
end
end

@testset "Ryu.writefixed" begin
@testset "Basic" begin
@test Ryu.writefixed(todouble(false, 1234, 99999), 0) ==
Expand Down Expand Up @@ -563,6 +580,23 @@ end # Float16
@test Ryu.writefixed(-100.0+eps(-100.0), 0, false, false, true, UInt8('.'), false) == "-100."
@test Ryu.writefixed(100.0-eps(100.0), 1, false, false, true, UInt8('.'), false) == "100.0"
@test Ryu.writefixed(-100.0+eps(-100.0), 1, false, false, true, UInt8('.'), false) == "-100.0"

@testset "writefixed(::AbstractVector, pos, ...)" begin
@testset for Vec in (Vector{UInt8}, Memory{UInt8})
buf = Vec(undef, 6)
@test Ryu.writefixed(buf, 1, 0.0, 4) == 7
@test String(buf) == "0.0000"

buf = Vec(undef, 100)
xx = 1729.142857142857
prec = 8
start_pos = 42
nwritten = 4 + 1 + prec
end_pos = start_pos + nwritten
@test Ryu.writefixed(buf, start_pos, xx, prec) == end_pos
@test String(buf[start_pos:end_pos-1]) == "1729.14285714"
end
end
end # fixed

@testset "Ryu.writeexp" begin
Expand Down Expand Up @@ -761,6 +795,23 @@ end
@test Ryu.writeexp(2.0, 1, false, false, false, UInt8('e'), UInt8('.'), true) == "2e+00"
end

@testset "writeexp(::AbstractVector, pos, ...)" begin
@testset for Vec in (Vector{UInt8}, Memory{UInt8})
buf = Vec(undef, 10)
@test Ryu.writeexp(buf, 1, 0.0, 4) == 11
@test String(buf) == "0.0000e+00"

buf = Vec(undef, 100)
xx = 1729.142857142857
prec = 8
start_pos = 42
nwritten = 1 + 1 + prec + 4
end_pos = start_pos + nwritten
@test Ryu.writeexp(buf, start_pos, xx, prec) == end_pos
@test String(buf[start_pos:end_pos-1]) == "1.72914286e+03"
end
end

end # exp

@testset "compact" begin
Expand Down

0 comments on commit 8560318

Please sign in to comment.