diff --git a/src/other/index.jl b/src/other/index.jl index 61341b0c2..e3a491868 100644 --- a/src/other/index.jl +++ b/src/other/index.jl @@ -45,7 +45,7 @@ function rename!(x::Index, nms::AbstractVector{Symbol}; makeunique::Bool=false) if !makeunique if length(unique(nms)) != length(nms) dup = unique(nms[nonunique(DataFrame(nms=nms))]) - dupstr = join(string.(':', dup), ", ", " and ") + dupstr = join(repr.(dup), ", ", " and ") msg = "Duplicate variable names: $dupstr. Pass makeunique=true " * "to make them unique using a suffix automatically." throw(ArgumentError(msg)) @@ -463,7 +463,7 @@ function add_names(ind::Index, add_ind::AbstractIndex; makeunique::Bool=false) end if length(dups) > 0 if !makeunique - dupstr = join(string.(':', unique(u[dups])), ", ", " and ") + dupstr = join(repr.(unique(u[dups])), ", ", " and ") msg = "Duplicate variable names: $dupstr. Pass makeunique=true " * "to make them unique using a suffix automatically." throw(ArgumentError(msg)) diff --git a/src/other/utils.jl b/src/other/utils.jl index 3839e93da..89b04a150 100644 --- a/src/other/utils.jl +++ b/src/other/utils.jl @@ -93,7 +93,7 @@ function make_unique!(names::Vector{Symbol}, src::AbstractVector{Symbol}; if length(dups) > 0 if !makeunique - dupstr = join(string.(':', unique(src[dups])), ", ", " and ") + dupstr = join(repr.(unique(src[dups])), ", ", " and ") msg = "Duplicate variable names: $dupstr. Pass makeunique=true " * "to make them unique using a suffix automatically." throw(ArgumentError(msg)) diff --git a/test/utils.jl b/test/utils.jl index a6e4030d4..d2936814f 100644 --- a/test/utils.jl +++ b/test/utils.jl @@ -8,6 +8,30 @@ using Test, Random, DataFrames @test DataFrames.make_unique([:x, :x_1, :x2], makeunique=false) == [:x, :x_1, :x2] end +@testset "duplicate-name error message uses repr for Symbols" begin + # this testset was AI generated + # Identifier-like Symbols still render as `:name`. + err = try DataFrames.make_unique([:a, :a]) catch e; e end + @test err isa ArgumentError + @test occursin(":a", err.msg) + + # Symbols containing characters that aren't valid in an identifier + # must use the explicit `Symbol("...")` form so the message is + # unambiguous (previously rendered as `:column name`, which + # reads like a parse error rather than naming a single Symbol). + s = Symbol("column name") + for thunk in ( + () -> DataFrames.make_unique([s, s]), # src/other/utils.jl + () -> rename!(DataFrames.Index([:a, :b]), [s, s]), # src/other/index.jl rename! + () -> hcat(DataFrame(s => 1), DataFrame(s => 2)), # src/other/index.jl add_names + ) + err = try thunk() catch e; e end + @test err isa ArgumentError + @test occursin("Symbol(\"column name\")", err.msg) + @test !occursin(":column name", err.msg) + end +end + @testset "repeat count" begin df = DataFrame(a=1:2, b=3:4) ref = DataFrame(a=repeat(1:2, 2),