Skip to content

Commit b9280de

Browse files
authored
fix(parser): warn on short final rows (#1193)
Only suppress the short-row warning at EOF when the parser consumed an explicit trailing delimiter. Preserve the valid empty-field behavior from #948 and add regression coverage with and without a final newline. Fixes #1190
1 parent 3d11b23 commit b9280de

2 files changed

Lines changed: 13 additions & 8 deletions

File tree

src/file.jl

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -678,13 +678,12 @@ Base.@propagate_inbounds function parserow(startpos, row, numwarnings, ctx::Cont
678678
else
679679
if i < ncols
680680
if Parsers.newline(code) || pos > len
681-
# in https://github.com/JuliaData/CSV.jl/issues/948,
682-
# it was noticed that if we reached the EOF right before parsing
683-
# the last expected column, then the warning is a bit spurious.
684-
# The final value is `missing` and the csv writer chose to just
685-
# "close" the file w/o including a final newline
686-
# we can treat this special-case as "valid" and not emit a warning
687-
if !(pos > len && i == (ncols - 1))
681+
# In https://github.com/JuliaData/CSV.jl/issues/948,
682+
# the delimiter for an empty final field was the final byte of
683+
# the input. Treat that explicit empty field as valid even
684+
# without a trailing newline, but still warn if the row ended
685+
# before the final field's delimiter was present.
686+
if !(pos > len && i == (ncols - 1) && Parsers.delimited(code))
688687
ctx.silencewarnings || numwarnings[] > ctx.maxwarnings || notenoughcolumns(i, ncols, rowoffset + row)
689688
!ctx.silencewarnings && numwarnings[] == ctx.maxwarnings && toomanywwarnings()
690689
numwarnings[] += 1

test/basics.jl

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -804,10 +804,16 @@ f = CSV.File(IOBuffer(data); header=false, types=Dict(1 => String), typemap=Dict
804804
@test f.types == [i == 1 ? String : Int8 for i = 1:60_000]
805805

806806
# 948
807-
f = CSV.File(IOBuffer("a,b\n1,2\n3,"))
807+
f = @test_logs CSV.File(IOBuffer("a,b\n1,2\n3,"))
808808
@test f.a == [1, 3]
809809
@test isequal(f.b, [2, missing])
810810

811+
# 1190
812+
for source in ("a,b,c\n1,2,3\n4,5", "a,b,c\n1,2,3\n4,5\n")
813+
f = @test_logs (:warn, r"only found 2 / 3 columns around data row: 2") CSV.File(IOBuffer(source))
814+
@test isequal(f.c, [3, missing])
815+
end
816+
811817
# duplicate column names
812818
f = CSV.File(IOBuffer("a,a,a\n"))
813819
@test f.names == [:a, :a_1, :a_2]

0 commit comments

Comments
 (0)