From b56063e2ac1a79dfcaf62eefa9668175aeaa2094 Mon Sep 17 00:00:00 2001 From: Jacob Quinn Date: Mon, 12 Jun 2023 20:42:16 -0600 Subject: [PATCH] Ensure that ArrowTypes.default is defined for Vararg tuples Fixes #461. This is the other proposal from what I originally suggested. Though `Tuple{Varag}` is never the concrete type of a value in Julia, it comes up when dealing with structs with fields that have Vararg types; not common at all, but it's allowed and happens. The reflection code here is a little gross, but it seems to be what Base Julia uses in similar queries to see if a tuple has a vararg element. I've commented out the Arrow/runtests test for now until we bump another version and can then uncomment. Unit tests are added for ArrowTypes in the meantime. --- src/ArrowTypes/src/ArrowTypes.jl | 8 +++++++- src/ArrowTypes/test/tests.jl | 4 ++++ test/runtests.jl | 9 +++++++++ 3 files changed, 20 insertions(+), 1 deletion(-) diff --git a/src/ArrowTypes/src/ArrowTypes.jl b/src/ArrowTypes/src/ArrowTypes.jl index 2245842d..60663bd3 100644 --- a/src/ArrowTypes/src/ArrowTypes.jl +++ b/src/ArrowTypes/src/ArrowTypes.jl @@ -351,7 +351,13 @@ end default(::Type{SubArray{T,N,P,I,L}}) where {T,N,P,I,L} = view(default(P), 0:-1) default(::Type{NTuple{N, T}}) where {N, T} = ntuple(i -> default(T), N) -default(::Type{T}) where {T <: Tuple} = Tuple(default(fieldtype(T, i)) for i = 1:fieldcount(T)) +default(::Type{Tuple{}}) = () +function default(::Type{T}) where {T <: Tuple} + T === Tuple{} && return () + N = Base.isvarargtype(T.parameters[end]) ? length(T.parameters) - 1 : fieldcount(T) + return Tuple(default(fieldtype(T, i)) for i = 1:N) +end + default(::Type{T}) where {T <: AbstractDict} = T() default(::Type{NamedTuple{names, types}}) where {names, types} = NamedTuple{names}(Tuple(default(fieldtype(types, i)) for i = 1:length(names))) diff --git a/src/ArrowTypes/test/tests.jl b/src/ArrowTypes/test/tests.jl index 0c257dc8..143041df 100644 --- a/src/ArrowTypes/test/tests.jl +++ b/src/ArrowTypes/test/tests.jl @@ -137,6 +137,10 @@ nt = (id=1, name="bob") @test ArrowTypes.JuliaType(Val(ArrowTypes.TUPLE), NamedTuple{(Symbol("1"), Symbol("2")), Tuple{Int, String}}) == Tuple{Int, String} @test ArrowTypes.fromarrow(Tuple{Int, String}, nt) == (1, "bob") @test ArrowTypes.fromarrow(Union{Missing, typeof(nt)}, nt) == nt +# #461 +@test ArrowTypes.default(Tuple{}) == () +@test ArrowTypes.default(Tuple{Vararg{Int}}) == () +@test ArrowTypes.default(Tuple{String, Vararg{Int}}) == ("",) v = v"1" v_nt = (major=1, minor=0, patch=0, prerelease=(), build=()) diff --git a/test/runtests.jl b/test/runtests.jl index edeb4d19..9169b81e 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -713,6 +713,15 @@ t = [(a=1,b=view(data,1:2)), (a=2,b=view(data,3:4)), missing] end +# @testset "# 461" begin + +# table = (; v=[v"1", v"2", missing]) +# buf = Arrow.tobuffer(table) +# table2 = Arrow.Table(buf) +# @test isequal(table.v, table2.v) + +# end + end # @testset "misc" end