Skip to content

Commit

Permalink
Allow nothing to be printed (#32148)
Browse files Browse the repository at this point in the history
  • Loading branch information
oxinabox authored and StefanKarpinski committed Aug 5, 2019
1 parent 53beb34 commit a288779
Show file tree
Hide file tree
Showing 4 changed files with 21 additions and 13 deletions.
1 change: 1 addition & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ Standard library changes
* `empty` now accepts a `NamedTuple` ([#32534]).
* `mod` now accepts a unit range as the second argument to easily perform offset modular arithmetic to ensure the result is inside the range ([#32628]).
* `Sockets.recvfrom` now returns both host and port as an InetAddr ([#32729]).
* `nothing` can now be `print`ed, and interplated into strings etc. as the string `"nothing"`. It is still not permitted to be interplated into Cmds (i.e. ``echo `$(nothing)` `` will still error without running anything.) ([#32148])

#### Libdl

Expand Down
10 changes: 7 additions & 3 deletions base/cmd.jl
Original file line number Diff line number Diff line change
Expand Up @@ -314,6 +314,10 @@ pipeline(a, b, c, d...) = pipeline(pipeline(a, b), c, d...)

## implementation of `cmd` syntax ##

cmd_interpolate(xs...) = cstr(string(map(cmd_interpolate1, xs)...))
cmd_interpolate1(x) = x
cmd_interpolate1(::Nothing) = throw(ArgumentError("`nothing` can not be interpolated into commands (`Cmd`)"))

arg_gen() = String[]
arg_gen(x::AbstractString) = String[cstr(x)]
function arg_gen(cmd::Cmd)
Expand All @@ -327,11 +331,11 @@ function arg_gen(head)
if isiterable(typeof(head))
vals = String[]
for x in head
push!(vals, cstr(string(x)))
push!(vals, cmd_interpolate(x))
end
return vals
else
return String[cstr(string(head))]
return String[cmd_interpolate(head)]
end
end

Expand All @@ -340,7 +344,7 @@ function arg_gen(head, tail...)
tail = arg_gen(tail...)
vals = String[]
for h = head, t = tail
push!(vals, cstr(string(h,t)))
push!(vals, cmd_interpolate(h,t))
end
return vals
end
Expand Down
1 change: 0 additions & 1 deletion base/show.jl
Original file line number Diff line number Diff line change
Expand Up @@ -590,7 +590,6 @@ function show(io::IO, tn::Core.TypeName)
end

show(io::IO, ::Nothing) = print(io, "nothing")
print(io::IO, ::Nothing) = throw(ArgumentError("`nothing` should not be printed; use `show`, `repr`, or custom output instead."))
show(io::IO, b::Bool) = print(io, get(io, :typeinfo, Any) === Bool ? (b ? "1" : "0") : (b ? "true" : "false"))
show(io::IO, n::Signed) = (write(io, string(n)); nothing)
show(io::IO, n::Unsigned) = print(io, "0x", string(n, pad = sizeof(n)<<1, base = 16))
Expand Down
22 changes: 13 additions & 9 deletions test/show.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1467,15 +1467,19 @@ let src = code_typed(gcd, (Int, Int), debuginfo=:source)[1][1]
@test pop!(lines) == " ! ── unreachable::#UNDEF"
end

# issue #27352
@test_throws ArgumentError print(nothing)
@test_throws ArgumentError print(stdout, nothing)
@test_throws ArgumentError string(nothing)
@test_throws ArgumentError string(1, "", nothing)
@test_throws ArgumentError let x = nothing; "x = $x" end
@test let x = nothing; "x = $(repr(x))" end == "x = nothing"
@test_throws ArgumentError `/bin/foo $nothing`
@test_throws ArgumentError `$nothing`
@testset "printing and interpolating nothing" begin
@test sprint(print, nothing) == "nothing"
@test string(nothing) == "nothing"
@test repr(nothing) == "nothing"
@test string(1, "", nothing) == "1nothing"
@test let x = nothing; "x = $x" end == "x = nothing"
@test let x = nothing; "x = $(repr(x))" end == "x = nothing"

# issue #27352 : No interpolating nothing into commands
@test_throws ArgumentError `/bin/foo $nothing`
@test_throws ArgumentError `$nothing`
@test_throws ArgumentError let x = nothing; `/bin/foo $x` end
end

struct X28004
value::Any
Expand Down

0 comments on commit a288779

Please sign in to comment.