JuliaIO / JLD2.jl

HDF5-compatible file format in pure Julia
Other
547 stars 85 forks source link

circular references with Ref are not correctly restored using custom serialization #433

Closed dpinol closed 1 year ago

dpinol commented 1 year ago

The problem occurs when:

When loading the data, the restored reference (Ref or Vector item) contains the data actually persisted by the custom serialization (in this case a Dict{Symbol, Any}), not the original object (T1 in this case). This can be reproduced both in master and identitypreserv_cs branches.

using JLD2

abstract type AT end

const DSA=Dict{Symbol, Any}

(JLD2.writeas(::Type{T})) where {T <: AT} = DSA

function Base.convert(::Type{DSA}, t::AT)
    @info "saving $(typeof(t))"
    return DSA(f => getproperty(t, f) for f in fieldnames(typeof(t)))
end
function Base.convert(::Type{T}, dsa::DSA) where {T <: AT}
    t= T(; dsa...)
    @info "loading $T from $(pointer_from_objref(dsa)) to $(pointer_from_objref(t))"
    return t
end

Base.@kwdef mutable struct T1 <: AT
    t1::Base.RefValue{Any}
end

function save()
    t1 = T1(Ref{Any}(nothing))
    t1.t1[] = t1
    @info "t1" t1
    return save_object("kk.jld2", t1)
end
save()

t1 = load_object("kk.jld2")
@info "t1" t1
┌ Info: t1
└   t1 = T1(Base.RefValue{Any}(Dict{Symbol, Any}(:t1 => Base.RefValue{Any}(#= circular reference @-2 =#))))
JonasIsensee commented 1 year ago

Ideally this should be fixed with the latest commit to #432 (provided that tests pass)