From 7e9c6c0f29d6145a305d909a7d947c3a4a71dfc9 Mon Sep 17 00:00:00 2001 From: Ben Arthur Date: Tue, 6 Oct 2026 20:37:46 +0000 Subject: [PATCH] getattributes(::DimArray): always a Dict with String keys The axis interface promises getattributes returns a Dict keyed by Strings. For a DimArray it returned DimensionalData's metadata as is: NoMetadata() for an array built without metadata, or a Metadata wrapper, or a Dict keyed by Symbols. Downstream, YAXArrays stored that as the YAXArray's properties and savedataset failed on copy(::NoMetadata); users worked around it with `metadata = Dict{String,Any}()` (JuliaDataCubes/YAXArrays.jl#362). Normalise all three to Dict{String,Any}; anything else is passed through unchanged. Co-Authored-By: Claude Fable 5.1 --- ext/DimensionalDataExt.jl | 10 ++++++++-- test/arrays.jl | 8 ++++++++ 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/ext/DimensionalDataExt.jl b/ext/DimensionalDataExt.jl index 8472175..c29c095 100644 --- a/ext/DimensionalDataExt.jl +++ b/ext/DimensionalDataExt.jl @@ -1,5 +1,5 @@ module DimensionalDataExt -using DimensionalData: DimArray, DimensionalData, data, Dim, metadata +using DimensionalData: DimArray, DimensionalData, data, Dim, metadata, NoMetadata, Metadata, val import YAXArrayBase: dimname, dimnames, dimvals, iscontdim, getattributes, getdata, yaxcreate _dname(::DimensionalData.Dim{N}) where N = N _dname(d::DimensionalData.Dimension) = DimensionalData.name(d) @@ -10,7 +10,13 @@ dimvals(x::DimArray,i) = DimensionalData.dims(x)[i].val getdata(x::DimArray) = data(x) -getattributes(x::DimArray) = metadata(x) +# the interface promises a Dict with String keys; DimensionalData's default metadata is +# `NoMetadata()` and its `Metadata` wraps a Dict whose keys may be Symbols +getattributes(x::DimArray) = _attributes(metadata(x)) +_attributes(::NoMetadata) = Dict{String,Any}() +_attributes(m::Metadata) = _attributes(val(m)) +_attributes(d::AbstractDict) = Dict{String,Any}(string(k) => v for (k, v) in d) +_attributes(m) = m function yaxcreate(::Type{<:DimArray},data,dnames,dvals,atts) d = ntuple(ndims(data)) do i diff --git a/test/arrays.jl b/test/arrays.jl index 0cd12d5..51dd40f 100644 --- a/test/arrays.jl +++ b/test/arrays.jl @@ -53,6 +53,14 @@ end @test dimvals(d,1) == 0.5:1.0:2.5 @test dimvals(d,2) == 1.5:0.5:3.0 @test getattributes(d) == Dict{String,Any}("a1"=>5, "a2"=>"att") + # metadata is normalised to a Dict with String keys, whatever DimensionalData holds + dd = DimArray(rand(2, 3), (X(1:2), Y(1:3))) + @test getattributes(dd) == Dict{String,Any}() && getattributes(dd) isa Dict{String,Any} + dd = DimArray(rand(2, 3), (X(1:2), Y(1:3)); metadata=Dict(:units => "K")) + @test getattributes(dd) == Dict{String,Any}("units" => "K") && getattributes(dd) isa Dict{String,Any} + dd = DimArray(rand(2, 3), (X(1:2), Y(1:3)); metadata=DimensionalData.Metadata(Dict("a" => 1))) + @test getattributes(dd) == Dict{String,Any}("a" => 1) + @test yaxconvert(DimArray, M()) isa DimArray end @testitem "ArchGDAL" begin