Skip to content

Commit 01b4035

Browse files
ronisbrrfourquet
authored andcommitted
Add support to multiple property pairs in sprint (JuliaLang#39381)
* Add support to multiple property pairs in sprint Sometimes it is required to pass multiple properties to `IOContext` in `sprint`. For example, if we want to print with `:compact` and `:limit` set to true. Currently, the only possible way to do this is creating an `IOContext` using a dummy `IOBuffer` with those parameters. Hence, this commit allows to pass a vector of pairs `:key=>value` to `context` keyword of `sprint` so that we can easily set multiple properties. This is not a breaking change, and no performance regression was identified when using the previous function signatures. * Add compat annotation to sprint * Update base/strings/io.jl Co-authored-by: Rafael Fourquet <[email protected]> * Update sprint docstring * Update NEWS.md * Move NEWS.md entry to the correct place Co-authored-by: Rafael Fourquet <[email protected]>
1 parent a25040d commit 01b4035

File tree

3 files changed

+48
-8
lines changed

3 files changed

+48
-8
lines changed

NEWS.md

+1
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ New library functions
3838
New library features
3939
--------------------
4040

41+
* The optional keyword argument `context` of `sprint` can now be set to a tuple of `:key => value` pairs to specify multiple attributes. ([#39381])
4142

4243
Standard library changes
4344
------------------------

base/strings/io.jl

+15-8
Original file line numberDiff line numberDiff line change
@@ -79,14 +79,19 @@ println(io::IO, xs...) = print(io, xs..., "\n")
7979
8080
Call the given function with an I/O stream and the supplied extra arguments.
8181
Everything written to this I/O stream is returned as a string.
82-
`context` can be either an [`IOContext`](@ref) whose properties will be used,
83-
or a `Pair` specifying a property and its value. `sizehint` suggests the capacity
84-
of the buffer (in bytes).
82+
`context` can be an [`IOContext`](@ref) whose properties will be used, a `Pair`
83+
specifying a property and its value, or a tuple of `Pair` specifying multiple
84+
properties and their values. `sizehint` suggests the capacity of the buffer (in
85+
bytes).
8586
86-
The optional keyword argument `context` can be set to `:key=>value` pair
87-
or an `IO` or [`IOContext`](@ref) object whose attributes are used for the I/O
88-
stream passed to `f`. The optional `sizehint` is a suggested size (in bytes)
89-
to allocate for the buffer used to write the string.
87+
The optional keyword argument `context` can be set to a `:key=>value` pair, a
88+
tuple of `:key=>value` pairs, or an `IO` or [`IOContext`](@ref) object whose
89+
attributes are used for the I/O stream passed to `f`. The optional `sizehint`
90+
is a suggested size (in bytes) to allocate for the buffer used to write the
91+
string.
92+
93+
!!! compat "Julia 1.7"
94+
Passing a tuple to keyword `context` requires Julia 1.7 or later.
9095
9196
# Examples
9297
```jldoctest
@@ -99,7 +104,9 @@ julia> sprint(showerror, BoundsError([1], 100))
99104
"""
100105
function sprint(f::Function, args...; context=nothing, sizehint::Integer=0)
101106
s = IOBuffer(sizehint=sizehint)
102-
if context !== nothing
107+
if context isa Tuple
108+
f(IOContext(s, context...), args...)
109+
elseif context !== nothing
103110
f(IOContext(s, context), args...)
104111
else
105112
f(s, args...)

test/strings/io.jl

+32
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,38 @@ join(myio, "", "", 1)
187187
@test_throws ArgumentError unescape_string(IOBuffer(), string('\\',"N"))
188188
@test_throws ArgumentError unescape_string(IOBuffer(), string('\\',"m"))
189189
end
190+
191+
@testset "sprint with context" begin
192+
function f(io::IO)
193+
println(io, "compact => ", get(io, :compact, false))
194+
println(io, "limit => ", get(io, :limit, false))
195+
end
196+
197+
str = sprint(f)
198+
@test str == """
199+
compact => false
200+
limit => false
201+
"""
202+
203+
str = sprint(f, context = :compact => true)
204+
@test str == """
205+
compact => true
206+
limit => false
207+
"""
208+
209+
str = sprint(f, context = (:compact => true, :limit => true))
210+
@test str == """
211+
compact => true
212+
limit => true
213+
"""
214+
215+
str = sprint(f, context = IOContext(stdout, :compact => true, :limit => true))
216+
@test str == """
217+
compact => true
218+
limit => true
219+
"""
220+
end
221+
190222
@testset "#11659" begin
191223
# The indentation code was not correctly counting tab stops
192224
@test Base.indentation(" \t") == (8, true)

0 commit comments

Comments
 (0)