Skip to content

Commit

Permalink
better error message for rpad/lpad with zero-width padding (#56488)
Browse files Browse the repository at this point in the history
Closes #45339 — throw a more informative `ArgumentError` message from
`rpad` and `lpad` if a zero-`textwidth` padding is passed (not a
`DivideError`).

If the padding character has `ncodeunits == 1`, suggests that maybe they
want `str * pad^max(0, npad - ncodeunits(str))` instead.
  • Loading branch information
stevengj authored Nov 9, 2024
1 parent 024d42a commit ecfd1a0
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 2 deletions.
14 changes: 12 additions & 2 deletions base/strings/util.jl
Original file line number Diff line number Diff line change
Expand Up @@ -476,7 +476,12 @@ function lpad(
n = Int(n)::Int
m = signed(n) - Int(textwidth(s))::Int
m 0 && return stringfn(s)
l = textwidth(p)
l = Int(textwidth(p))::Int
if l == 0
throw(ArgumentError("$(repr(p)) has zero textwidth" * (ncodeunits(p) != 1 ? "" :
"; maybe you want pad^max(0, npad - ncodeunits(str)) * str to pad by codeunits" *
(s isa AbstractString && codeunit(s) != UInt8 ? "?" : " (bytes)?"))))
end
q, r = divrem(m, l)
r == 0 ? stringfn(p^q, s) : stringfn(p^q, first(p, r), s)
end
Expand Down Expand Up @@ -508,7 +513,12 @@ function rpad(
n = Int(n)::Int
m = signed(n) - Int(textwidth(s))::Int
m 0 && return stringfn(s)
l = textwidth(p)
l = Int(textwidth(p))::Int
if l == 0
throw(ArgumentError("$(repr(p)) has zero textwidth" * (ncodeunits(p) != 1 ? "" :
"; maybe you want str * pad^max(0, npad - ncodeunits(str)) to pad by codeunits" *
(s isa AbstractString && codeunit(s) != UInt8 ? "?" : " (bytes)?"))))
end
q, r = divrem(m, l)
r == 0 ? stringfn(s, p^q) : stringfn(s, p^q, first(p, r))
end
Expand Down
7 changes: 7 additions & 0 deletions test/strings/util.jl
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,13 @@ end
@test rpad("⟨k|H₁|k̃⟩", 12) |> textwidth == 12
@test lpad("⟨k|H₁|k⟩", 12) |> textwidth == 12
@test rpad("⟨k|H₁|k⟩", 12) |> textwidth == 12
for pad in (rpad, lpad), p in ('\0', "\0", "\0\0", "\u302")
if ncodeunits(p) == 1
@test_throws r".*has zero textwidth.*maybe you want.*bytes.*" pad("foo", 10, p)
else
@test_throws r".*has zero textwidth$" pad("foo", 10, p)
end
end
end

@testset "string truncation (ltruncate, rtruncate, ctruncate)" begin
Expand Down

0 comments on commit ecfd1a0

Please sign in to comment.