Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support to multiple property pairs in sprint #39381

Merged
merged 6 commits into from
Feb 22, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ New library functions
New library features
--------------------

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

Standard library changes
------------------------
Expand Down
23 changes: 15 additions & 8 deletions base/strings/io.jl
Original file line number Diff line number Diff line change
Expand Up @@ -79,14 +79,19 @@ println(io::IO, xs...) = print(io, xs..., "\n")

Call the given function with an I/O stream and the supplied extra arguments.
Everything written to this I/O stream is returned as a string.
`context` can be either an [`IOContext`](@ref) whose properties will be used,
or a `Pair` specifying a property and its value. `sizehint` suggests the capacity
of the buffer (in bytes).
`context` can be an [`IOContext`](@ref) whose properties will be used, a `Pair`
specifying a property and its value, or a tuple of `Pair` specifying multiple
properties and their values. `sizehint` suggests the capacity of the buffer (in
bytes).

The optional keyword argument `context` can be set to `:key=>value` pair
or an `IO` or [`IOContext`](@ref) object whose attributes are used for the I/O
stream passed to `f`. The optional `sizehint` is a suggested size (in bytes)
to allocate for the buffer used to write the string.
The optional keyword argument `context` can be set to a `:key=>value` pair, a
tuple of `:key=>value` pairs, or an `IO` or [`IOContext`](@ref) object whose
attributes are used for the I/O stream passed to `f`. The optional `sizehint`
is a suggested size (in bytes) to allocate for the buffer used to write the
string.

!!! compat "Julia 1.7"
Passing a tuple to keyword `context` requires Julia 1.7 or later.

# Examples
```jldoctest
Expand All @@ -99,7 +104,9 @@ julia> sprint(showerror, BoundsError([1], 100))
"""
function sprint(f::Function, args...; context=nothing, sizehint::Integer=0)
s = IOBuffer(sizehint=sizehint)
if context !== nothing
if context isa Tuple
f(IOContext(s, context...), args...)
elseif context !== nothing
f(IOContext(s, context), args...)
else
f(s, args...)
Expand Down
32 changes: 32 additions & 0 deletions test/strings/io.jl
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,38 @@ join(myio, "", "", 1)
@test_throws ArgumentError unescape_string(IOBuffer(), string('\\',"N"))
@test_throws ArgumentError unescape_string(IOBuffer(), string('\\',"m"))
end

@testset "sprint with context" begin
function f(io::IO)
println(io, "compact => ", get(io, :compact, false))
println(io, "limit => ", get(io, :limit, false))
end

str = sprint(f)
@test str == """
compact => false
limit => false
"""

str = sprint(f, context = :compact => true)
@test str == """
compact => true
limit => false
"""

str = sprint(f, context = (:compact => true, :limit => true))
@test str == """
compact => true
limit => true
"""

str = sprint(f, context = IOContext(stdout, :compact => true, :limit => true))
@test str == """
compact => true
limit => true
"""
end

@testset "#11659" begin
# The indentation code was not correctly counting tab stops
@test Base.indentation(" \t") == (8, true)
Expand Down