Skip to content

Commit

Permalink
Add accepted_field_type for Unions with Missing
Browse files Browse the repository at this point in the history
PR #89 fixed compatibility with Arrow v2.6 except when the schema
field's declared type is e.g. `Union{Vector{T},Missing}` and what's
passed for validation is some `AbstractVector`. This adds a method to
`accepted_field_type` that recurses on the non-`Missing` type in a
`Union` with `Missing`. Note that this also necessitated adding an
explicit `accepted_field_type` method for `Any` to avoid infinite
recursion with the fallback definition, since `(Union{T,Missing} where
{T}) == Any`.
  • Loading branch information
ararslan committed Jun 13, 2023
1 parent 3e4db06 commit 72ecc55
Show file tree
Hide file tree
Showing 3 changed files with 19 additions and 1 deletion.
2 changes: 1 addition & 1 deletion Project.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
name = "Legolas"
uuid = "741b9549-f6ed-4911-9fbf-4a1c0c97f0cd"
authors = ["Beacon Biosignals, Inc."]
version = "0.5.11"
version = "0.5.12"

[deps]
Arrow = "69666777-d1a9-59fb-9406-91d4454c9d45"
Expand Down
4 changes: 4 additions & 0 deletions src/schemas.jl
Original file line number Diff line number Diff line change
Expand Up @@ -240,22 +240,26 @@ record type.
Legolas itself defines the following default overloads:
accepted_field_type(::SchemaVersion, T::Type) = T
accepted_field_type(::SchemaVersion, ::Type{Any}) = Any
accepted_field_type(::SchemaVersion, ::Type{UUID}) = Union{UUID,UInt128}
accepted_field_type(::SchemaVersion, ::Type{Symbol}) = Union{Symbol,AbstractString}
accepted_field_type(::SchemaVersion, ::Type{String}) = AbstractString
accepted_field_type(sv::SchemaVersion, ::Type{<:Vector{T}}) where T = AbstractVector{<:(accepted_field_type(sv, T))}
accepted_field_type(::SchemaVersion, ::Type{Vector}) = AbstractVector
accepted_field_type(sv::SchemaVersion, ::Type{Union{T,Missing}}) where {T} = Union{accepted_field_type(sv, T),Missing}
Outside of these default overloads, this function should only be overloaded against specific
`SchemaVersion`s that are authored within the same module as the overload definition; to do
otherwise constitutes type piracy and should be avoided.
"""
@inline accepted_field_type(::SchemaVersion, T::Type) = T
accepted_field_type(::SchemaVersion, ::Type{Any}) = Any
accepted_field_type(::SchemaVersion, ::Type{UUID}) = Union{UUID,UInt128}
accepted_field_type(::SchemaVersion, ::Type{Symbol}) = Union{Symbol,AbstractString}
accepted_field_type(::SchemaVersion, ::Type{String}) = AbstractString
accepted_field_type(sv::SchemaVersion, ::Type{<:Vector{T}}) where T = AbstractVector{<:(accepted_field_type(sv, T))}
accepted_field_type(::SchemaVersion, ::Type{Vector}) = AbstractVector
accepted_field_type(sv::SchemaVersion, ::Type{Union{T,Missing}}) where {T} = Union{accepted_field_type(sv, T),Missing}

"""
Legolas.find_violation(ts::Tables.Schema, sv::Legolas.SchemaVersion)
Expand Down
14 changes: 14 additions & 0 deletions test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -276,6 +276,12 @@ end
i::(<:Integer)
end

@schema "test.union-with-param" UnionWithParam

@version UnionWithParamV1 begin
xs::Union{Vector{String},Missing}
end

@testset "`Legolas.@version` and associated utilities for declared `Legolas.SchemaVersion`s" begin
@testset "Legolas.SchemaVersionDeclarationError" begin
@test_throws SchemaVersionDeclarationError("malformed or missing declaration of required fields") eval(:(@version(NewV1, $(Expr(:block, LineNumberNode(1, :test))))))
Expand Down Expand Up @@ -401,6 +407,14 @@ end
for T in (UUID, UInt128), S in (Symbol, String)
@test Legolas.complies_with(Tables.Schema((:id, :sym), (T, S)), AcceptedV1SchemaVersion())
end

t = Tables.Schema((:xs,), (SubArray{String,1,Arrow.List{String,Int32,Vector{UInt8}},
Tuple{UnitRange{Int64}},true},))
s = UnionWithParamV1SchemaVersion()
@test isnothing(Legolas.validate(t, s))
@test Legolas.complies_with(t, s)
@test isnothing(Legolas.find_violation(t, s))
@test isempty(Legolas.find_violations(t, s))
end

@testset "Legolas.declaration" begin
Expand Down

0 comments on commit 72ecc55

Please sign in to comment.