From 7973e7c603f4afdb52047f2e0f633ffbde0b84bb Mon Sep 17 00:00:00 2001 From: Ian Weaver Date: Sat, 21 Mar 2026 06:26:50 -0700 Subject: [PATCH 01/26] feat: add FileIO.jl load/save --- Project.toml | 1 + src/ASDF.jl | 11 +++++++++++ 2 files changed, 12 insertions(+) diff --git a/Project.toml b/Project.toml index 4c609d5..4c9af60 100644 --- a/Project.toml +++ b/Project.toml @@ -13,6 +13,7 @@ ChunkCodecLibLz4 = "7e9cc85e-5614-42a3-ad86-b78f920b38a5" ChunkCodecLibZlib = "4c0bbee4-addc-4d73-81a0-b6caacae83c8" ChunkCodecLibZstd = "55437552-ac27-4d47-9aa3-63184e8fd398" CodecXz = "ba30903b-d9e8-5048-a5ec-d1f5b0d4b47b" +FileIO = "5789e2e9-d7fb-5bc7-8068-2c6fae9b9549" MD5 = "6ac74813-4b46-53a4-afec-0b5dc9d7885c" PkgVersion = "eebad327-c553-4316-9ea0-9fa01ccd7688" StridedViews = "4db3bf67-4bd7-4b4e-b153-31dc3fb37143" diff --git a/src/ASDF.jl b/src/ASDF.jl index 1fe903e..9f7c1d3 100644 --- a/src/ASDF.jl +++ b/src/ASDF.jl @@ -10,6 +10,9 @@ using MD5: md5 using PkgVersion: PkgVersion using StridedViews: StridedView using YAML: YAML +using FileIO: @format_str, File, load, save + +export load, save ################################################################################ @@ -533,6 +536,10 @@ function load_file(filename::AbstractString) return ASDFFile(filename, metadata, lazy_block_headers) end +function fileio_load(f::File{format"ASDF"}) + return load_file(f.filename) +end + ################################################################################ ################################################################################ ################################################################################ @@ -749,4 +756,8 @@ function write_file(filename::AbstractString, document::Dict{Any,Any}) return nothing end +function fileio_save(f::File{format"ASDF"}, data) + return write_file(f.filename, data) +end + end From b2bca560c00fa0ab6f83104ed5dcdd40c3e388bc Mon Sep 17 00:00:00 2001 From: Ian Weaver Date: Sat, 21 Mar 2026 06:28:10 -0700 Subject: [PATCH 02/26] fix: widen accepted payload types for writing --- src/ASDF.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ASDF.jl b/src/ASDF.jl index 9f7c1d3..455dbb3 100644 --- a/src/ASDF.jl +++ b/src/ASDF.jl @@ -611,7 +611,7 @@ function YAML._print(io::IO, val::NDArrayWrapper, level::Int=0, ignore_level::Bo YAML._print(io, ndarray, level, ignore_level) end -function write_file(filename::AbstractString, document::Dict{Any,Any}) +function write_file(filename::AbstractString, document::Dict) # Set up block descriptors global blocks empty!(blocks) From 5af3ae928f32280f157e39055d546e9d5cd20f30 Mon Sep 17 00:00:00 2001 From: Ian Weaver Date: Sat, 21 Mar 2026 06:30:22 -0700 Subject: [PATCH 03/26] feat: add convenience getter for .metadata fields --- src/ASDF.jl | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/ASDF.jl b/src/ASDF.jl index 455dbb3..47392a5 100644 --- a/src/ASDF.jl +++ b/src/ASDF.jl @@ -512,6 +512,8 @@ function YAML.write(file::ASDFFile) return "[ASDF file \"$(file.filename)\"]\n" * YAML.write(file.metadata) end +Base.getindex(af::ASDFFile, key) = af.metadata[key] + ################################################################################ asdf_constructors = copy(YAML.default_yaml_constructors) From 6182c9228a0cfe15ff94b72b02d6103fe6008591 Mon Sep 17 00:00:00 2001 From: Ian Weaver Date: Sat, 21 Mar 2026 07:56:32 -0700 Subject: [PATCH 04/26] feat: add some simple tree printing for ASDFFile objects --- Project.toml | 2 ++ src/ASDF.jl | 6 ++++++ 2 files changed, 8 insertions(+) diff --git a/Project.toml b/Project.toml index 4c9af60..66b2e5b 100644 --- a/Project.toml +++ b/Project.toml @@ -7,6 +7,7 @@ authors = ["Erik Schnetter "] projects = ["test", "docs"] [deps] +AbstractTrees = "1520ce14-60c1-5f80-bbc7-55ef81b5835c" ChunkCodecLibBlosc = "c6a955be-ab7f-4fbb-b38f-caf93db6b928" ChunkCodecLibBzip2 = "2b723af9-f480-4e8d-a1e4-4a9f5a906122" ChunkCodecLibLz4 = "7e9cc85e-5614-42a3-ad86-b78f920b38a5" @@ -20,6 +21,7 @@ StridedViews = "4db3bf67-4bd7-4b4e-b153-31dc3fb37143" YAML = "ddb6d928-2868-570f-bddf-ab3f9cf99eb6" [compat] +AbstractTrees = "0.4.5" ChunkCodecLibBlosc = "0.2.0, 0.3" ChunkCodecLibBzip2 = "0.2.0, 1.0" ChunkCodecLibLz4 = "0.2.1, 1.0" diff --git a/src/ASDF.jl b/src/ASDF.jl index 47392a5..2a8e7a7 100644 --- a/src/ASDF.jl +++ b/src/ASDF.jl @@ -11,6 +11,7 @@ using PkgVersion: PkgVersion using StridedViews: StridedView using YAML: YAML using FileIO: @format_str, File, load, save +using AbstractTrees: AbstractTrees export load, save @@ -514,6 +515,11 @@ end Base.getindex(af::ASDFFile, key) = af.metadata[key] +cs = AbstractTrees.TreeCharSet("├", "└", "│", "─", "", ": ") +function Base.show(io::IO, ::MIME"text/plain", af::ASDFFile) + AbstractTrees.print_tree((io, x) -> print(io, typeof(x)), io, af.metadata; charset = cs) +end + ################################################################################ asdf_constructors = copy(YAML.default_yaml_constructors) From f82a65bcbad0f86494876479b488912aa9554db0 Mon Sep 17 00:00:00 2001 From: Ian Weaver Date: Mon, 23 Mar 2026 03:21:27 -0700 Subject: [PATCH 05/26] build: use asdf patch of FILEIO.jl until merged --- Project.toml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Project.toml b/Project.toml index 66b2e5b..3b81e60 100644 --- a/Project.toml +++ b/Project.toml @@ -20,6 +20,10 @@ PkgVersion = "eebad327-c553-4316-9ea0-9fa01ccd7688" StridedViews = "4db3bf67-4bd7-4b4e-b153-31dc3fb37143" YAML = "ddb6d928-2868-570f-bddf-ab3f9cf99eb6" +# TODO: Remove after https://github.com/JuliaIO/FileIO.jl/pull/427 +[sources] +FileIO = {url = "https://github.com/icweaver/FileIO.jl", rev = "asdf"} + [compat] AbstractTrees = "0.4.5" ChunkCodecLibBlosc = "0.2.0, 0.3" @@ -28,6 +32,7 @@ ChunkCodecLibLz4 = "0.2.1, 1.0" ChunkCodecLibZlib = "0.2.0, 1.0" ChunkCodecLibZstd = "0.2.0, 1.0" CodecXz = "0.7.4" +FileIO = "1" MD5 = "0.2.1" PkgVersion = "0.3.3" StridedViews = "0.2.1, 0.3, 0.4" From 8ac86adef3049e559229fc698338fd423f3c298d Mon Sep 17 00:00:00 2001 From: Ian Weaver Date: Mon, 23 Mar 2026 06:06:09 -0700 Subject: [PATCH 06/26] feat: cleanup tree display --- src/ASDF.jl | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/src/ASDF.jl b/src/ASDF.jl index 2a8e7a7..18e6c71 100644 --- a/src/ASDF.jl +++ b/src/ASDF.jl @@ -515,9 +515,23 @@ end Base.getindex(af::ASDFFile, key) = af.metadata[key] -cs = AbstractTrees.TreeCharSet("├", "└", "│", "─", "", ": ") +struct ASDFTreeNode + key::Union{String, Nothing} + value::Any +end + +AbstractTrees.children(n::ASDFTreeNode) = + n.value isa ASDFFile ? [ASDFTreeNode(k, v) for (k, v) in n.value.metadata] : + n.value isa Dict ? [ASDFTreeNode(k, v) for (k, v) in n.value] : () + +AbstractTrees.printnode(io::IO, n::ASDFTreeNode) = + n.key === nothing ? print(io, n.value.filename) : + n.value isa Dict ? print(io, n.key, "::Dict") : + n.value isa NDArray ? print(io, "$(n.key): NDArray{$(n.value.datatype), shape=$(n.value.shape)}") : + print(io, n.key, ": ", repr(n.value)) + function Base.show(io::IO, ::MIME"text/plain", af::ASDFFile) - AbstractTrees.print_tree((io, x) -> print(io, typeof(x)), io, af.metadata; charset = cs) + AbstractTrees.print_tree(io, ASDFTreeNode(nothing, af)) end ################################################################################ From 0f3a4ced4c0ee883412c66c60fc4ea007d058c17 Mon Sep 17 00:00:00 2001 From: Ian Weaver Date: Mon, 23 Mar 2026 07:18:03 -0700 Subject: [PATCH 07/26] feat: more tree printing --- src/ASDF.jl | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/ASDF.jl b/src/ASDF.jl index 18e6c71..df40c58 100644 --- a/src/ASDF.jl +++ b/src/ASDF.jl @@ -516,19 +516,20 @@ end Base.getindex(af::ASDFFile, key) = af.metadata[key] struct ASDFTreeNode - key::Union{String, Nothing} + key::Union{Any, Nothing} value::Any end AbstractTrees.children(n::ASDFTreeNode) = n.value isa ASDFFile ? [ASDFTreeNode(k, v) for (k, v) in n.value.metadata] : - n.value isa Dict ? [ASDFTreeNode(k, v) for (k, v) in n.value] : () + n.value isa Dict ? [ASDFTreeNode(k, v) for (k, v) in sort(n.value)] : () AbstractTrees.printnode(io::IO, n::ASDFTreeNode) = - n.key === nothing ? print(io, n.value.filename) : - n.value isa Dict ? print(io, n.key, "::Dict") : - n.value isa NDArray ? print(io, "$(n.key): NDArray{$(n.value.datatype), shape=$(n.value.shape)}") : - print(io, n.key, ": ", repr(n.value)) + n.key === nothing ? print(io, n.value.filename) : + n.value isa Dict ? print(io, n.key, "::", typeof(n.key)) : + n.value isa NDArray ? print(io, n.key, "::", typeof(n.value), " | shape = ", n.value.shape) : + n.value isa AbstractVector ? print(io, n.key, "::" , typeof(n.value), " | shape = ", size(n.value)) : + print(io, n.key, "::", typeof(n.value), " | ", n.value) function Base.show(io::IO, ::MIME"text/plain", af::ASDFFile) AbstractTrees.print_tree(io, ASDFTreeNode(nothing, af)) From b365e6d344c0968da6eac91c645e250678440fc6 Mon Sep 17 00:00:00 2001 From: Ian Weaver Date: Mon, 23 Mar 2026 13:28:43 -0700 Subject: [PATCH 08/26] don't fall for type piracy See: https://github.com/timholy/Revise.jl/issues/605 --- src/ASDF.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ASDF.jl b/src/ASDF.jl index df40c58..de07a9c 100644 --- a/src/ASDF.jl +++ b/src/ASDF.jl @@ -522,7 +522,7 @@ end AbstractTrees.children(n::ASDFTreeNode) = n.value isa ASDFFile ? [ASDFTreeNode(k, v) for (k, v) in n.value.metadata] : - n.value isa Dict ? [ASDFTreeNode(k, v) for (k, v) in sort(n.value)] : () + n.value isa Dict ? [ASDFTreeNode(k, v) for (k, v) in sort(collect(n.value); by = first)] : () AbstractTrees.printnode(io::IO, n::ASDFTreeNode) = n.key === nothing ? print(io, n.value.filename) : From ab4de87d551b5d50a9ca8b62b3e2101ff07f2ea7 Mon Sep 17 00:00:00 2001 From: Ian Weaver Date: Mon, 23 Mar 2026 13:47:52 -0700 Subject: [PATCH 09/26] tests: update with new I/O methods --- test/test-read.jl | 6 +++--- test/test-read_chunked.jl | 4 ++-- test/test-show.jl | 16 ++++++++++++++++ test/test-write.jl | 10 +++++----- 4 files changed, 26 insertions(+), 10 deletions(-) create mode 100644 test/test-show.jl diff --git a/test/test-read.jl b/test/test-read.jl index 94f6bc3..b806d52 100644 --- a/test/test-read.jl +++ b/test/test-read.jl @@ -1,15 +1,15 @@ @testset "Read ASDF file" begin - asdf = ASDF.load_file("blue_upchan_gain.00000000.asdf") + asdf = load("blue_upchan_gain.00000000.asdf") println(YAML.write(asdf.metadata)) map_tree(output, asdf.metadata) - buffer = asdf.metadata[0]["buffer"][] + buffer = asdf[0]["buffer"][] @test eltype(buffer) == Float16 @test size(buffer) == (256,) @test buffer == fill(1, 256) - dish_index = asdf.metadata[0]["dish_index"][] + dish_index = asdf[0]["dish_index"][] @test eltype(dish_index) == Int32 @test size(dish_index) == (3, 2) @test dish_index == [ diff --git a/test/test-read_chunked.jl b/test/test-read_chunked.jl index b7a101c..ca0dbef 100644 --- a/test/test-read_chunked.jl +++ b/test/test-read_chunked.jl @@ -1,10 +1,10 @@ @testset "Read ASDF file with chunked arrays" begin - asdf = ASDF.load_file("chunking.asdf") + asdf = load("chunking.asdf") println(YAML.write(asdf.metadata)) map_tree(output, asdf.metadata) - chunky = asdf.metadata["chunky"][] + chunky = asdf["chunky"][] @test eltype(chunky) == Float16 @test size(chunky) == (4, 4) @test chunky == [ diff --git a/test/test-show.jl b/test/test-show.jl new file mode 100644 index 0000000..8cd2fff --- /dev/null +++ b/test/test-show.jl @@ -0,0 +1,16 @@ +@testset "Show method for `ASDF.ASDFFile`" begin + af = load("blue_upchan_gain.00000000.asdf") + + sprint(show, MIME"text/plain"(), af) == """ + test/blue_upchan_gain.00000000.asdf + ├─ 0::Int64 + │ ├─ buffer::ASDF.NDArray | shape = [256] + │ ├─ dim_names::Vector{String} | shape = (1,) + │ └─ dish_index::ASDF.NDArray | shape = [2, 3] + └─ asdf/library::String + ├─ author::String | Erik Schnetter + ├─ homepage::String | https://github.com/eschnett/asdf-cxx + ├─ name::String | asdf-cxx + └─ version::String | 7.2.0 + """ +end diff --git a/test/test-write.jl b/test/test-write.jl index 86b5b81..67b5f9c 100644 --- a/test/test-write.jl +++ b/test/test-write.jl @@ -16,26 +16,26 @@ "element7" => ASDF.NDArrayWrapper(array; compression=ASDF.C_Zstd), ), ) - ASDF.write_file(filename, doc) + save(filename, doc) - doc′ = ASDF.load_file(filename) + doc′ = load(filename) map_tree(output, doc′.metadata) data1 = doc["data1"][] - data1′ = doc′.metadata["data1"][] + data1′ = doc′["data1"][] @test eltype(data1′) == eltype(data1) @test size(data1′) == size(data1) @test data1′ == data1 data2 = doc["data2"][] - data2′ = doc′.metadata["data2"][] + data2′ = doc′["data2"][] @test eltype(data2′) == eltype(data2) @test size(data2′) == size(data2) @test data2′ == data2 for n in 1:7 element = doc["group"]["element$n"][] - element′ = doc′.metadata["group"]["element$n"][] + element′ = doc′["group"]["element$n"][] @test eltype(element′) == eltype(element) @test size(element′) == size(element) @test element′ == element From d17aef57edcba50c33b867227fe140a784f3e54c Mon Sep 17 00:00:00 2001 From: Ian Weaver Date: Tue, 24 Mar 2026 00:57:08 -0700 Subject: [PATCH 10/26] ci: temp workaround until FileIO.jl PR merge --- .github/workflows/CI.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 16a6700..d26cc2b 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -9,7 +9,8 @@ jobs: strategy: matrix: version: - - "min" + # TODO: Put back after https://github.com/JuliaIO/FileIO.jl/pull/427 + #- "min" - "1" - "pre" os: From 3a55418e9cc6e62dd4787f0dc255d35826c6d413 Mon Sep 17 00:00:00 2001 From: Ian Weaver Date: Wed, 25 Mar 2026 13:33:38 -0700 Subject: [PATCH 11/26] feat: add info function for tree printing --- src/ASDF.jl | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/src/ASDF.jl b/src/ASDF.jl index de07a9c..874d6af 100644 --- a/src/ASDF.jl +++ b/src/ASDF.jl @@ -531,9 +531,30 @@ AbstractTrees.printnode(io::IO, n::ASDFTreeNode) = n.value isa AbstractVector ? print(io, n.key, "::" , typeof(n.value), " | shape = ", size(n.value)) : print(io, n.key, "::", typeof(n.value), " | ", n.value) -function Base.show(io::IO, ::MIME"text/plain", af::ASDFFile) - AbstractTrees.print_tree(io, ASDFTreeNode(nothing, af)) +""" + info(io::IO, af::ASDFFile; max_rows = 20) + +Display up to `max_rows` lines of `af` tree. `Base.show` calls this function internally to display this type. +""" +function info(io::IO, af::ASDFFile; max_rows = 20) + root = ASDFTreeNode(nothing, af) + n_rows = sum(1 for _ in AbstractTrees.PostOrderDFS(root)) + + if n_rows < max_rows + AbstractTrees.print_tree(io, root) + else + # Store entire tree in `buf` + buf = IOBuffer() + AbstractTrees.print_tree(buf, root) + # Only print up to `n_rows` lines from that buffer + lines = split(String(take!(buf)), '\n', keepempty = false) + foreach(l -> println(io, l), Iterators.take(lines, max_rows)) + println(io, " ⋮ (", (n_rows - max_rows), ") more rows") + end end +info(af; kwargs...) = info(stdout, af; kwargs...) + +Base.show(io::IO, ::MIME"text/plain", af::ASDFFile) = info(io, af) # Display up to `max_rows` by default ################################################################################ From 21a5c4f9fd5b06f8d0d34885f47fc1324e4453e7 Mon Sep 17 00:00:00 2001 From: Ian Weaver Date: Wed, 25 Mar 2026 13:36:28 -0700 Subject: [PATCH 12/26] style (tree): internal cleanup --- src/ASDF.jl | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/ASDF.jl b/src/ASDF.jl index 874d6af..5f44c25 100644 --- a/src/ASDF.jl +++ b/src/ASDF.jl @@ -516,7 +516,7 @@ end Base.getindex(af::ASDFFile, key) = af.metadata[key] struct ASDFTreeNode - key::Union{Any, Nothing} + key::Any value::Any end @@ -540,7 +540,7 @@ function info(io::IO, af::ASDFFile; max_rows = 20) root = ASDFTreeNode(nothing, af) n_rows = sum(1 for _ in AbstractTrees.PostOrderDFS(root)) - if n_rows < max_rows + if n_rows ≤ max_rows AbstractTrees.print_tree(io, root) else # Store entire tree in `buf` @@ -549,7 +549,7 @@ function info(io::IO, af::ASDFFile; max_rows = 20) # Only print up to `n_rows` lines from that buffer lines = split(String(take!(buf)), '\n', keepempty = false) foreach(l -> println(io, l), Iterators.take(lines, max_rows)) - println(io, " ⋮ (", (n_rows - max_rows), ") more rows") + println(io, " ⋮ (", n_rows - max_rows, ") more rows") end end info(af; kwargs...) = info(stdout, af; kwargs...) From 189ef833bf6a96ef066d04ce5f668c85dbcd48f0 Mon Sep 17 00:00:00 2001 From: Ian Weaver Date: Wed, 25 Mar 2026 14:02:05 -0700 Subject: [PATCH 13/26] tests(tree printing): fix + add more --- test/test-show.jl | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/test/test-show.jl b/test/test-show.jl index 8cd2fff..9e5d2e7 100644 --- a/test/test-show.jl +++ b/test/test-show.jl @@ -1,7 +1,7 @@ @testset "Show method for `ASDF.ASDFFile`" begin af = load("blue_upchan_gain.00000000.asdf") - sprint(show, MIME"text/plain"(), af) == """ + @test sprint(show, MIME"text/plain"(), af) == """ test/blue_upchan_gain.00000000.asdf ├─ 0::Int64 │ ├─ buffer::ASDF.NDArray | shape = [256] @@ -13,4 +13,13 @@ ├─ name::String | asdf-cxx └─ version::String | 7.2.0 """ + + @test sprint(io -> ASDF.info(io, af; max_rows = 5)) == """ + test/blue_upchan_gain.00000000.asdf + ├─ 0::Int64 + │ ├─ buffer::ASDF.NDArray | shape = [256] + │ ├─ dim_names::Vector{String} | shape = (1,) + │ └─ dish_index::ASDF.NDArray | shape = [2, 3] + ⋮ (5) more rows + """ end From fa86c305ebe4d6f7932a56a218f334fd58b051c9 Mon Sep 17 00:00:00 2001 From: Ian Weaver Date: Wed, 25 Mar 2026 14:03:31 -0700 Subject: [PATCH 14/26] test(tree printing): fr this time --- test/test-show.jl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/test-show.jl b/test/test-show.jl index 9e5d2e7..8ca23c1 100644 --- a/test/test-show.jl +++ b/test/test-show.jl @@ -2,7 +2,7 @@ af = load("blue_upchan_gain.00000000.asdf") @test sprint(show, MIME"text/plain"(), af) == """ - test/blue_upchan_gain.00000000.asdf + blue_upchan_gain.00000000.asdf ├─ 0::Int64 │ ├─ buffer::ASDF.NDArray | shape = [256] │ ├─ dim_names::Vector{String} | shape = (1,) @@ -15,7 +15,7 @@ """ @test sprint(io -> ASDF.info(io, af; max_rows = 5)) == """ - test/blue_upchan_gain.00000000.asdf + blue_upchan_gain.00000000.asdf ├─ 0::Int64 │ ├─ buffer::ASDF.NDArray | shape = [256] │ ├─ dim_names::Vector{String} | shape = (1,) From 595cf2c1e85d7415581832c641cc4b5dbdeeec47 Mon Sep 17 00:00:00 2001 From: Ian Weaver Date: Wed, 25 Mar 2026 14:45:35 -0700 Subject: [PATCH 15/26] tests(tree printing): more --- test/test-show.jl | 3 +++ 1 file changed, 3 insertions(+) diff --git a/test/test-show.jl b/test/test-show.jl index 8ca23c1..124d0ce 100644 --- a/test/test-show.jl +++ b/test/test-show.jl @@ -22,4 +22,7 @@ │ └─ dish_index::ASDF.NDArray | shape = [2, 3] ⋮ (5) more rows """ + + # I'm sure there's a better way to test this code path + @test ASDF.info(af; max_rows = 5) == nothing end From 4f8cd1f87a9c740c9b575228baebd55b0fd98e15 Mon Sep 17 00:00:00 2001 From: Ian Weaver Date: Wed, 25 Mar 2026 15:00:35 -0700 Subject: [PATCH 16/26] tests(tree printing): make less brittle --- test/test-show.jl | 22 ++-------------------- 1 file changed, 2 insertions(+), 20 deletions(-) diff --git a/test/test-show.jl b/test/test-show.jl index 124d0ce..eb965b3 100644 --- a/test/test-show.jl +++ b/test/test-show.jl @@ -1,27 +1,9 @@ @testset "Show method for `ASDF.ASDFFile`" begin af = load("blue_upchan_gain.00000000.asdf") - @test sprint(show, MIME"text/plain"(), af) == """ - blue_upchan_gain.00000000.asdf - ├─ 0::Int64 - │ ├─ buffer::ASDF.NDArray | shape = [256] - │ ├─ dim_names::Vector{String} | shape = (1,) - │ └─ dish_index::ASDF.NDArray | shape = [2, 3] - └─ asdf/library::String - ├─ author::String | Erik Schnetter - ├─ homepage::String | https://github.com/eschnett/asdf-cxx - ├─ name::String | asdf-cxx - └─ version::String | 7.2.0 - """ + @test occursin("blue_upchan_gain.00000000.asdf\n├─", sprint(show, MIME"text/plain"(), af)) - @test sprint(io -> ASDF.info(io, af; max_rows = 5)) == """ - blue_upchan_gain.00000000.asdf - ├─ 0::Int64 - │ ├─ buffer::ASDF.NDArray | shape = [256] - │ ├─ dim_names::Vector{String} | shape = (1,) - │ └─ dish_index::ASDF.NDArray | shape = [2, 3] - ⋮ (5) more rows - """ + @test occursin("(5) more rows", sprint(io -> ASDF.info(io, af; max_rows = 5))) # I'm sure there's a better way to test this code path @test ASDF.info(af; max_rows = 5) == nothing From 8b90094e62482305a921a0912c92e61af2a73e74 Mon Sep 17 00:00:00 2001 From: Ian Weaver Date: Sun, 29 Mar 2026 19:08:40 -0700 Subject: [PATCH 17/26] fix: save dict data without needing to sprinkle {Any, Any} --- src/ASDF.jl | 16 ++++++++-------- test/test-write.jl | 4 ++-- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/ASDF.jl b/src/ASDF.jl index 5f44c25..b1fce14 100644 --- a/src/ASDF.jl +++ b/src/ASDF.jl @@ -662,13 +662,13 @@ function write_file(filename::AbstractString, document::Dict) # Ensure standard tags are present # TODO: - # - provide a function that generates a standard empty document - # - don't modify the input - # - remove the `{Any,Any}` in the test cases - # - maybe make the document not a `Dict` but the stuff with the `metadata` that the writer returns? - get!(document, "asdf/library") do - ASDFLibrary(software_name, software_author, software_homepage, software_version) - end + # - [ ] provide a function that generates a standard empty document + # - [x] don't modify the input + # - [x] remove the `{Any,Any}` in the test cases + # - [ ] maybe make the document not a `Dict` but the stuff with the `metadata` that the writer returns? + # - [ ] preserve insertion order? https://github.com/JuliaAstro/ASDF.jl/tree/ordered + library = ASDFLibrary(software_name, software_author, software_homepage, software_version) + full_document = merge(Dict{Any, Any}(document), Dict{Any, Any}("asdf/library" => library)) # Write YAML part of file io = open(filename, "w") @@ -682,7 +682,7 @@ function write_file(filename::AbstractString, document::Dict) --- !core/asdf-1.1.0""", ) - YAML.write(io, document) + YAML.write(io, full_document) println(io, "...") # Write blocks diff --git a/test/test-write.jl b/test/test-write.jl index 67b5f9c..d175a04 100644 --- a/test/test-write.jl +++ b/test/test-write.jl @@ -3,10 +3,10 @@ filename = joinpath(dirname, "output.asdf") array = Float64[1/(i+j+k-2) for i in 1:50, j in 1:51, k in 1:52] - doc = Dict{Any,Any}( + doc = Dict( "data1" => ASDF.NDArrayWrapper([1 2; 3 4]; inline=false), "data2" => ASDF.NDArrayWrapper([1 2; 3 4]; inline=true), - "group" => Dict{Any,Any}( + "group" => Dict( "element1" => ASDF.NDArrayWrapper(array; compression=ASDF.C_None), "element2" => ASDF.NDArrayWrapper(array; compression=ASDF.C_Blosc), "element3" => ASDF.NDArrayWrapper(array; compression=ASDF.C_Bzip2), From efbfb460aabfa5995bf908de888926be583d4255 Mon Sep 17 00:00:00 2001 From: Ian Weaver Date: Sun, 29 Mar 2026 19:20:51 -0700 Subject: [PATCH 18/26] test: add doctest for ASDF.info, move it to testsuite --- docs/make.jl | 1 + src/ASDF.jl | 77 +++++++++++++++++++++++++++++++++++++++++++++-- test/Project.toml | 1 + test/runtests.jl | 5 +++ 4 files changed, 82 insertions(+), 2 deletions(-) diff --git a/docs/make.jl b/docs/make.jl index 80d9484..1f6ae0a 100644 --- a/docs/make.jl +++ b/docs/make.jl @@ -11,6 +11,7 @@ makedocs(; prettyurls = true, canonical = "https://juliaastro.org/ASDF/stable/", ), + doctest = false, ) deploydocs(; diff --git a/src/ASDF.jl b/src/ASDF.jl index b1fce14..97df739 100644 --- a/src/ASDF.jl +++ b/src/ASDF.jl @@ -525,7 +525,7 @@ AbstractTrees.children(n::ASDFTreeNode) = n.value isa Dict ? [ASDFTreeNode(k, v) for (k, v) in sort(collect(n.value); by = first)] : () AbstractTrees.printnode(io::IO, n::ASDFTreeNode) = - n.key === nothing ? print(io, n.value.filename) : + n.key === nothing ? print(io, basename(n.value.filename)) : n.value isa Dict ? print(io, n.key, "::", typeof(n.key)) : n.value isa NDArray ? print(io, n.key, "::", typeof(n.value), " | shape = ", n.value.shape) : n.value isa AbstractVector ? print(io, n.key, "::" , typeof(n.value), " | shape = ", size(n.value)) : @@ -534,7 +534,80 @@ AbstractTrees.printnode(io::IO, n::ASDFTreeNode) = """ info(io::IO, af::ASDFFile; max_rows = 20) -Display up to `max_rows` lines of `af` tree. `Base.show` calls this function internally to display this type. +Display up to `max_rows` lines of `af` tree. `Base.show` calls this function internally to display this type. Set `max_rows = Inf` to display all rows. + +## Examples + +```jldoctest +julia> doc = Dict("field_\$(i)" => rand(10) for i in 1:25); + +julia> save("long.asdf", doc) + +julia> af = load("long.asdf") +long.asdf +├─ field_22::Vector{Float64} | shape = (10,) +├─ field_24::Vector{Float64} | shape = (10,) +├─ field_11::Vector{Float64} | shape = (10,) +├─ field_2::Vector{Float64} | shape = (10,) +├─ field_4::Vector{Float64} | shape = (10,) +├─ field_20::Vector{Float64} | shape = (10,) +├─ asdf/library::String +│ ├─ author::String | Erik Schnetter +│ ├─ homepage::String | https://github.com/JuliaAstro/ASDF.jl +│ ├─ name::String | ASDF.jl +│ └─ version::String | 2.0.0 +├─ field_15::Vector{Float64} | shape = (10,) +├─ field_18::Vector{Float64} | shape = (10,) +├─ field_25::Vector{Float64} | shape = (10,) +├─ field_12::Vector{Float64} | shape = (10,) +├─ field_5::Vector{Float64} | shape = (10,) +├─ field_3::Vector{Float64} | shape = (10,) +├─ field_7::Vector{Float64} | shape = (10,) +├─ field_9::Vector{Float64} | shape = (10,) + ⋮ (11) more rows + + +julia> ASDF.info(af; max_rows = 5) +long.asdf +├─ field_22::Vector{Float64} | shape = (10,) +├─ field_24::Vector{Float64} | shape = (10,) +├─ field_11::Vector{Float64} | shape = (10,) +├─ field_2::Vector{Float64} | shape = (10,) + ⋮ (26) more rows + +julia> ASDF.info(af; max_rows = Inf) +long.asdf +├─ field_22::Vector{Float64} | shape = (10,) +├─ field_24::Vector{Float64} | shape = (10,) +├─ field_11::Vector{Float64} | shape = (10,) +├─ field_2::Vector{Float64} | shape = (10,) +├─ field_4::Vector{Float64} | shape = (10,) +├─ field_20::Vector{Float64} | shape = (10,) +├─ asdf/library::String +│ ├─ author::String | Erik Schnetter +│ ├─ homepage::String | https://github.com/JuliaAstro/ASDF.jl +│ ├─ name::String | ASDF.jl +│ └─ version::String | 2.0.0 +├─ field_15::Vector{Float64} | shape = (10,) +├─ field_18::Vector{Float64} | shape = (10,) +├─ field_25::Vector{Float64} | shape = (10,) +├─ field_12::Vector{Float64} | shape = (10,) +├─ field_5::Vector{Float64} | shape = (10,) +├─ field_3::Vector{Float64} | shape = (10,) +├─ field_7::Vector{Float64} | shape = (10,) +├─ field_9::Vector{Float64} | shape = (10,) +├─ field_16::Vector{Float64} | shape = (10,) +├─ field_19::Vector{Float64} | shape = (10,) +├─ field_1::Vector{Float64} | shape = (10,) +├─ field_14::Vector{Float64} | shape = (10,) +├─ field_6::Vector{Float64} | shape = (10,) +├─ field_21::Vector{Float64} | shape = (10,) +├─ field_10::Vector{Float64} | shape = (10,) +├─ field_13::Vector{Float64} | shape = (10,) +├─ field_17::Vector{Float64} | shape = (10,) +├─ field_8::Vector{Float64} | shape = (10,) +└─ field_23::Vector{Float64} | shape = (10,) +``` """ function info(io::IO, af::ASDFFile; max_rows = 20) root = ASDFTreeNode(nothing, af) diff --git a/test/Project.toml b/test/Project.toml index c7f25f6..3cd4bef 100644 --- a/test/Project.toml +++ b/test/Project.toml @@ -1,6 +1,7 @@ [deps] ASDF = "686f71d1-807d-59a4-a860-28280ea06d7b" Aqua = "4c88cf16-eb10-579e-8560-4a9242c79595" +Documenter = "e30172f5-a6a5-5a46-863b-614d45cd2de4" ParallelTestRunner = "d3525ed8-44d0-4b2c-a655-542cee43accc" Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" YAML = "ddb6d928-2868-570f-bddf-ab3f9cf99eb6" diff --git a/test/runtests.jl b/test/runtests.jl index 760c4b2..a00e111 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -1,6 +1,11 @@ using ParallelTestRunner: runtests, find_tests, parse_args using ASDF +# Doctest +using Documenter +DocMeta.setdocmeta!(ASDF, :DocTestSetup, :(using ASDF); recursive = true) +doctest(ASDF) + const init_code = quote using ASDF using Test From 477877ee02420f52a50e7b830a83faa74ca8a47d Mon Sep 17 00:00:00 2001 From: Ian Weaver Date: Sun, 29 Mar 2026 19:42:53 -0700 Subject: [PATCH 19/26] docs: add docstrings for save/load --- src/ASDF.jl | 43 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/src/ASDF.jl b/src/ASDF.jl index 97df739..c101d00 100644 --- a/src/ASDF.jl +++ b/src/ASDF.jl @@ -653,10 +653,38 @@ function load_file(filename::AbstractString) return ASDFFile(filename, metadata, lazy_block_headers) end +""" + load(f::AbstractString) + +Load an asdf file at filepath `f`. + +## Examples + +```jldoctest +julia> doc = Dict("field_\$(i)" => rand(10) for i in 1:5); # Create some sample data + +julia> save("myfile.asdf", doc) + +julia> load("myfile.asdf") +myfile.asdf +├─ field_5::Vector{Float64} | shape = (10,) +├─ field_3::Vector{Float64} | shape = (10,) +├─ field_1::Vector{Float64} | shape = (10,) +├─ asdf/library::String +│ ├─ author::String | Erik Schnetter +│ ├─ homepage::String | https://github.com/JuliaAstro/ASDF.jl +│ ├─ name::String | ASDF.jl +│ └─ version::String | 2.0.0 +├─ field_2::Vector{Float64} | shape = (10,) +└─ field_4::Vector{Float64} | shape = (10,) +``` +""" function fileio_load(f::File{format"ASDF"}) return load_file(f.filename) end +@doc (@doc fileio_load) load + ################################################################################ ################################################################################ ################################################################################ @@ -873,8 +901,23 @@ function write_file(filename::AbstractString, document::Dict) return nothing end +""" + save(f::String, data) + +Save `data` to an asdf file at filepath `f`. + +## Examples + +```jldoctest +julia> data = Dict("field_\$(i)" => rand(10) for i in 1:5); # Create some sample data + +julia> save("myfile.asdf", doc) +``` +""" function fileio_save(f::File{format"ASDF"}, data) return write_file(f.filename, data) end +@doc (@doc fileio_save) save + end From 42e693c96fe48445a45ea62a3d69e11eced91ea7 Mon Sep 17 00:00:00 2001 From: Ian Weaver Date: Sun, 29 Mar 2026 19:48:17 -0700 Subject: [PATCH 20/26] typo --- src/ASDF.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ASDF.jl b/src/ASDF.jl index c101d00..f8ffeb6 100644 --- a/src/ASDF.jl +++ b/src/ASDF.jl @@ -911,7 +911,7 @@ Save `data` to an asdf file at filepath `f`. ```jldoctest julia> data = Dict("field_\$(i)" => rand(10) for i in 1:5); # Create some sample data -julia> save("myfile.asdf", doc) +julia> save("myfile.asdf", data) ``` """ function fileio_save(f::File{format"ASDF"}, data) From a50157730ea083be27e98b3f93196ed239ea2d05 Mon Sep 17 00:00:00 2001 From: Ian Weaver Date: Sat, 21 Mar 2026 06:26:50 -0700 Subject: [PATCH 21/26] fix: use ordered dict --- Project.toml | 2 ++ src/ASDF.jl | 19 +++++++++++-------- 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/Project.toml b/Project.toml index 4c609d5..19f1a06 100644 --- a/Project.toml +++ b/Project.toml @@ -14,6 +14,7 @@ ChunkCodecLibZlib = "4c0bbee4-addc-4d73-81a0-b6caacae83c8" ChunkCodecLibZstd = "55437552-ac27-4d47-9aa3-63184e8fd398" CodecXz = "ba30903b-d9e8-5048-a5ec-d1f5b0d4b47b" MD5 = "6ac74813-4b46-53a4-afec-0b5dc9d7885c" +OrderedCollections = "bac558e1-5e72-5ebc-8fee-abe8a469f55d" PkgVersion = "eebad327-c553-4316-9ea0-9fa01ccd7688" StridedViews = "4db3bf67-4bd7-4b4e-b153-31dc3fb37143" YAML = "ddb6d928-2868-570f-bddf-ab3f9cf99eb6" @@ -26,6 +27,7 @@ ChunkCodecLibZlib = "0.2.0, 1.0" ChunkCodecLibZstd = "0.2.0, 1.0" CodecXz = "0.7.4" MD5 = "0.2.1" +OrderedCollections = "1.8.1" PkgVersion = "0.3.3" StridedViews = "0.2.1, 0.3, 0.4" YAML = "0.4.9" diff --git a/src/ASDF.jl b/src/ASDF.jl index 1fe903e..ad08fee 100644 --- a/src/ASDF.jl +++ b/src/ASDF.jl @@ -10,6 +10,7 @@ using MD5: md5 using PkgVersion: PkgVersion using StridedViews: StridedView using YAML: YAML +using OrderedCollections: OrderedDict ################################################################################ @@ -501,7 +502,7 @@ end struct ASDFFile filename::AbstractString - metadata::Dict{Any,Any} + metadata::OrderedDict{Any,Any} lazy_block_headers::LazyBlockHeaders end @@ -511,9 +512,11 @@ end ################################################################################ +ordered_map_constructor = (constructor, node) -> YAML.construct_mapping(OrderedDict{Any,Any}, constructor, node) asdf_constructors = copy(YAML.default_yaml_constructors) -asdf_constructors["tag:stsci.edu:asdf/core/asdf-1.1.0"] = asdf_constructors["tag:yaml.org,2002:map"] -asdf_constructors["tag:stsci.edu:asdf/core/software-1.0.0"] = asdf_constructors["tag:yaml.org,2002:map"] +delete!(asdf_constructors, "tag:yaml.org,2002:map") # Let dicttype= handle plain maps +asdf_constructors["tag:stsci.edu:asdf/core/asdf-1.1.0"] = ordered_map_constructor +asdf_constructors["tag:stsci.edu:asdf/core/software-1.0.0"] = ordered_map_constructor function load_file(filename::AbstractString) io = open(filename, "r") @@ -527,7 +530,7 @@ function load_file(filename::AbstractString) asdf_constructors′["tag:stsci.edu:asdf/core/ndarray-chunk-1.0.0"] = construct_yaml_ndarray_chunk asdf_constructors′["tag:stsci.edu:asdf/core/chunked-ndarray-1.0.0"] = construct_yaml_chunked_ndarray - metadata = YAML.load(io, asdf_constructors′) + metadata = YAML.load(io, asdf_constructors′; dicttype = OrderedDict{Any, Any}) # lazy_block_headers.block_headers = find_all_blocks(io, position(io)) lazy_block_headers.block_headers = find_all_blocks(io) return ASDFFile(filename, metadata, lazy_block_headers) @@ -545,7 +548,7 @@ struct ASDFLibrary end function YAML._print(io::IO, val::ASDFLibrary, level::Int=0, ignore_level::Bool=false) println(io, "!core/software-1.0.0") - library = Dict(:name => val.name, :author => val.author, :homepage => val.homepage, :version => val.version) + library = OrderedDict(:name => val.name, :author => val.author, :homepage => val.homepage, :version => val.version) YAML._print(io, library, level, ignore_level) end @@ -579,7 +582,7 @@ function YAML._print(io::IO, val::NDArrayWrapper, level::Int=0, ignore_level::Bo data = val.array # Split multidimensional arrays into array-of-arrays data = eachslice(data; dims=Tuple(2:ndims(data))) - ndarray = Dict( + ndarray = OrderedDict( :data => data, :shape => collect(reverse(size(val.array)))::Vector{<:Integer}, :datatype => string(Datatype(eltype(val.array))), @@ -590,7 +593,7 @@ function YAML._print(io::IO, val::NDArrayWrapper, level::Int=0, ignore_level::Bo global blocks source = length(blocks.arrays) push!(blocks.arrays, val) - ndarray = Dict( + ndarray = OrderedDict( :source => source::Integer, :shape => collect(reverse(size(val.array)))::Vector{<:Integer}, :datatype => string(Datatype(eltype(val.array))), @@ -604,7 +607,7 @@ function YAML._print(io::IO, val::NDArrayWrapper, level::Int=0, ignore_level::Bo YAML._print(io, ndarray, level, ignore_level) end -function write_file(filename::AbstractString, document::Dict{Any,Any}) +function write_file(filename::AbstractString, document::AbstractDict) # Set up block descriptors global blocks empty!(blocks) From 46426a79502fcc4e406a0c8f61f2c05cdd2a2075 Mon Sep 17 00:00:00 2001 From: Ian Weaver Date: Tue, 31 Mar 2026 11:34:48 -0700 Subject: [PATCH 22/26] fix: update file save order --- src/ASDF.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ASDF.jl b/src/ASDF.jl index 344671a..777fc5d 100644 --- a/src/ASDF.jl +++ b/src/ASDF.jl @@ -772,7 +772,7 @@ function write_file(filename::AbstractString, document::AbstractDict) # - [ ] maybe make the document not a `Dict` but the stuff with the `metadata` that the writer returns? # - [ ] preserve insertion order? https://github.com/JuliaAstro/ASDF.jl/tree/ordered library = ASDFLibrary(software_name, software_author, software_homepage, software_version) - full_document = merge(Dict{Any, Any}(document), Dict{Any, Any}("asdf/library" => library)) + full_document = merge(document, OrderedDict{Any, Any}("asdf/library" => library)) # Write YAML part of file io = open(filename, "w") From 3077f0c305e44f743a3b326f2ea370d4c352321c Mon Sep 17 00:00:00 2001 From: Ian Weaver Date: Tue, 31 Mar 2026 11:46:18 -0700 Subject: [PATCH 23/26] update doctests and printing --- src/ASDF.jl | 116 +++++++++++++++++++++++++++------------------------- 1 file changed, 60 insertions(+), 56 deletions(-) diff --git a/src/ASDF.jl b/src/ASDF.jl index 777fc5d..85c03c2 100644 --- a/src/ASDF.jl +++ b/src/ASDF.jl @@ -522,12 +522,12 @@ struct ASDFTreeNode end AbstractTrees.children(n::ASDFTreeNode) = - n.value isa ASDFFile ? [ASDFTreeNode(k, v) for (k, v) in n.value.metadata] : - n.value isa Dict ? [ASDFTreeNode(k, v) for (k, v) in sort(collect(n.value); by = first)] : () + n.value isa ASDFFile ? [ASDFTreeNode(k, v) for (k, v) in n.value.metadata] : + n.value isa AbstractDict ? [ASDFTreeNode(k, v) for (k, v) in sort(collect(n.value); by = first)] : () AbstractTrees.printnode(io::IO, n::ASDFTreeNode) = n.key === nothing ? print(io, basename(n.value.filename)) : - n.value isa Dict ? print(io, n.key, "::", typeof(n.key)) : + n.value isa AbstractDict ? print(io, n.key, "::", typeof(n.key)) : n.value isa NDArray ? print(io, n.key, "::", typeof(n.value), " | shape = ", n.value.shape) : n.value isa AbstractVector ? print(io, n.key, "::" , typeof(n.value), " | shape = ", size(n.value)) : print(io, n.key, "::", typeof(n.value), " | ", n.value) @@ -540,75 +540,75 @@ Display up to `max_rows` lines of `af` tree. `Base.show` calls this function int ## Examples ```jldoctest +julia> using OrderedCollections: OrderedDict + julia> doc = Dict("field_\$(i)" => rand(10) for i in 1:25); julia> save("long.asdf", doc) julia> af = load("long.asdf") long.asdf -├─ field_22::Vector{Float64} | shape = (10,) -├─ field_24::Vector{Float64} | shape = (10,) -├─ field_11::Vector{Float64} | shape = (10,) +├─ field_1::Vector{Float64} | shape = (10,) ├─ field_2::Vector{Float64} | shape = (10,) +├─ field_3::Vector{Float64} | shape = (10,) ├─ field_4::Vector{Float64} | shape = (10,) -├─ field_20::Vector{Float64} | shape = (10,) -├─ asdf/library::String -│ ├─ author::String | Erik Schnetter -│ ├─ homepage::String | https://github.com/JuliaAstro/ASDF.jl -│ ├─ name::String | ASDF.jl -│ └─ version::String | 2.0.0 -├─ field_15::Vector{Float64} | shape = (10,) -├─ field_18::Vector{Float64} | shape = (10,) -├─ field_25::Vector{Float64} | shape = (10,) -├─ field_12::Vector{Float64} | shape = (10,) ├─ field_5::Vector{Float64} | shape = (10,) -├─ field_3::Vector{Float64} | shape = (10,) +├─ field_6::Vector{Float64} | shape = (10,) ├─ field_7::Vector{Float64} | shape = (10,) +├─ field_8::Vector{Float64} | shape = (10,) ├─ field_9::Vector{Float64} | shape = (10,) - ⋮ (11) more rows - +├─ field_10::Vector{Float64} | shape = (10,) +├─ field_11::Vector{Float64} | shape = (10,) +├─ field_12::Vector{Float64} | shape = (10,) +├─ field_13::Vector{Float64} | shape = (10,) +├─ field_14::Vector{Float64} | shape = (10,) +├─ field_15::Vector{Float64} | shape = (10,) +├─ field_16::Vector{Float64} | shape = (10,) +├─ field_17::Vector{Float64} | shape = (10,) +├─ field_18::Vector{Float64} | shape = (10,) +├─ field_19::Vector{Float64} | shape = (10,) + ⋮ (7) more rows julia> ASDF.info(af; max_rows = 5) long.asdf -├─ field_22::Vector{Float64} | shape = (10,) -├─ field_24::Vector{Float64} | shape = (10,) -├─ field_11::Vector{Float64} | shape = (10,) +├─ field_1::Vector{Float64} | shape = (10,) ├─ field_2::Vector{Float64} | shape = (10,) - ⋮ (26) more rows +├─ field_3::Vector{Float64} | shape = (10,) +├─ field_4::Vector{Float64} | shape = (10,) + ⋮ (22) more rows julia> ASDF.info(af; max_rows = Inf) long.asdf -├─ field_22::Vector{Float64} | shape = (10,) -├─ field_24::Vector{Float64} | shape = (10,) -├─ field_11::Vector{Float64} | shape = (10,) +├─ field_1::Vector{Float64} | shape = (10,) ├─ field_2::Vector{Float64} | shape = (10,) +├─ field_3::Vector{Float64} | shape = (10,) ├─ field_4::Vector{Float64} | shape = (10,) -├─ field_20::Vector{Float64} | shape = (10,) -├─ asdf/library::String -│ ├─ author::String | Erik Schnetter -│ ├─ homepage::String | https://github.com/JuliaAstro/ASDF.jl -│ ├─ name::String | ASDF.jl -│ └─ version::String | 2.0.0 -├─ field_15::Vector{Float64} | shape = (10,) -├─ field_18::Vector{Float64} | shape = (10,) -├─ field_25::Vector{Float64} | shape = (10,) -├─ field_12::Vector{Float64} | shape = (10,) ├─ field_5::Vector{Float64} | shape = (10,) -├─ field_3::Vector{Float64} | shape = (10,) +├─ field_6::Vector{Float64} | shape = (10,) ├─ field_7::Vector{Float64} | shape = (10,) +├─ field_8::Vector{Float64} | shape = (10,) ├─ field_9::Vector{Float64} | shape = (10,) -├─ field_16::Vector{Float64} | shape = (10,) -├─ field_19::Vector{Float64} | shape = (10,) -├─ field_1::Vector{Float64} | shape = (10,) -├─ field_14::Vector{Float64} | shape = (10,) -├─ field_6::Vector{Float64} | shape = (10,) -├─ field_21::Vector{Float64} | shape = (10,) ├─ field_10::Vector{Float64} | shape = (10,) +├─ field_11::Vector{Float64} | shape = (10,) +├─ field_12::Vector{Float64} | shape = (10,) ├─ field_13::Vector{Float64} | shape = (10,) +├─ field_14::Vector{Float64} | shape = (10,) +├─ field_15::Vector{Float64} | shape = (10,) +├─ field_16::Vector{Float64} | shape = (10,) ├─ field_17::Vector{Float64} | shape = (10,) -├─ field_8::Vector{Float64} | shape = (10,) -└─ field_23::Vector{Float64} | shape = (10,) -``` +├─ field_18::Vector{Float64} | shape = (10,) +├─ field_19::Vector{Float64} | shape = (10,) +├─ field_20::Vector{Float64} | shape = (10,) +├─ field_21::Vector{Float64} | shape = (10,) +├─ field_22::Vector{Float64} | shape = (10,) +├─ field_23::Vector{Float64} | shape = (10,) +├─ field_24::Vector{Float64} | shape = (10,) +├─ field_25::Vector{Float64} | shape = (10,) +└─ asdf/library::String + ├─ author::String | Erik Schnetter + ├─ homepage::String | https://github.com/JuliaAstro/ASDF.jl + ├─ name::String | ASDF.jl + └─ version::String | 2.0.0 """ function info(io::IO, af::ASDFFile; max_rows = 20) root = ASDFTreeNode(nothing, af) @@ -664,22 +664,24 @@ Load an asdf file at filepath `f`. ## Examples ```jldoctest -julia> doc = Dict("field_\$(i)" => rand(10) for i in 1:5); # Create some sample data +julia> using OrderedCollections: OrderedDict + +julia> doc = OrderedDict("field_\$(i)" => rand(10) for i in 1:5); # Create some sample data julia> save("myfile.asdf", doc) julia> load("myfile.asdf") myfile.asdf -├─ field_5::Vector{Float64} | shape = (10,) -├─ field_3::Vector{Float64} | shape = (10,) ├─ field_1::Vector{Float64} | shape = (10,) -├─ asdf/library::String -│ ├─ author::String | Erik Schnetter -│ ├─ homepage::String | https://github.com/JuliaAstro/ASDF.jl -│ ├─ name::String | ASDF.jl -│ └─ version::String | 2.0.0 ├─ field_2::Vector{Float64} | shape = (10,) -└─ field_4::Vector{Float64} | shape = (10,) +├─ field_3::Vector{Float64} | shape = (10,) +├─ field_4::Vector{Float64} | shape = (10,) +├─ field_5::Vector{Float64} | shape = (10,) +└─ asdf/library::String + ├─ author::String | Erik Schnetter + ├─ homepage::String | https://github.com/JuliaAstro/ASDF.jl + ├─ name::String | ASDF.jl + └─ version::String | 2.0.0 ``` """ function fileio_load(f::File{format"ASDF"}) @@ -912,7 +914,9 @@ Save `data` to an asdf file at filepath `f`. ## Examples ```jldoctest -julia> data = Dict("field_\$(i)" => rand(10) for i in 1:5); # Create some sample data +julia> using OrderedCollections: OrderedDict + +julia> data = OrderedDict("field_\$(i)" => rand(10) for i in 1:5); # Create some sample data julia> save("myfile.asdf", data) ``` From 1b970e12da5b80f7010b2b4c1f6b367eb37dbf6f Mon Sep 17 00:00:00 2001 From: Ian Weaver Date: Tue, 31 Mar 2026 12:29:15 -0700 Subject: [PATCH 24/26] docs: add OrderedCollections.jl to deps --- docs/Project.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/Project.toml b/docs/Project.toml index 2df60e2..50585c9 100644 --- a/docs/Project.toml +++ b/docs/Project.toml @@ -1,6 +1,7 @@ [deps] ASDF = "686f71d1-807d-59a4-a860-28280ea06d7b" Documenter = "e30172f5-a6a5-5a46-863b-614d45cd2de4" +OrderedCollections = "bac558e1-5e72-5ebc-8fee-abe8a469f55d" [compat] Documenter = "1" From bcd35d18cad228015c78fffa31222bfacfd05585 Mon Sep 17 00:00:00 2001 From: Ian Weaver Date: Tue, 31 Mar 2026 12:33:47 -0700 Subject: [PATCH 25/26] oops, wrong env --- docs/Project.toml | 1 - test/Project.toml | 1 + 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/Project.toml b/docs/Project.toml index 50585c9..2df60e2 100644 --- a/docs/Project.toml +++ b/docs/Project.toml @@ -1,7 +1,6 @@ [deps] ASDF = "686f71d1-807d-59a4-a860-28280ea06d7b" Documenter = "e30172f5-a6a5-5a46-863b-614d45cd2de4" -OrderedCollections = "bac558e1-5e72-5ebc-8fee-abe8a469f55d" [compat] Documenter = "1" diff --git a/test/Project.toml b/test/Project.toml index 3cd4bef..be3639a 100644 --- a/test/Project.toml +++ b/test/Project.toml @@ -2,6 +2,7 @@ ASDF = "686f71d1-807d-59a4-a860-28280ea06d7b" Aqua = "4c88cf16-eb10-579e-8560-4a9242c79595" Documenter = "e30172f5-a6a5-5a46-863b-614d45cd2de4" +OrderedCollections = "bac558e1-5e72-5ebc-8fee-abe8a469f55d" ParallelTestRunner = "d3525ed8-44d0-4b2c-a655-542cee43accc" Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" YAML = "ddb6d928-2868-570f-bddf-ab3f9cf99eb6" From e1559eb3a54dd00f5669e948797a750c502588ed Mon Sep 17 00:00:00 2001 From: Ian Weaver Date: Tue, 31 Mar 2026 12:44:34 -0700 Subject: [PATCH 26/26] typo --- src/ASDF.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ASDF.jl b/src/ASDF.jl index 85c03c2..a6eff0b 100644 --- a/src/ASDF.jl +++ b/src/ASDF.jl @@ -542,7 +542,7 @@ Display up to `max_rows` lines of `af` tree. `Base.show` calls this function int ```jldoctest julia> using OrderedCollections: OrderedDict -julia> doc = Dict("field_\$(i)" => rand(10) for i in 1:25); +julia> doc = OrderedDict("field_\$(i)" => rand(10) for i in 1:25); julia> save("long.asdf", doc)