From 23c65b3208d32f29c780ac0efd61137f8fb73569 Mon Sep 17 00:00:00 2001 From: daviehh <25255906+daviehh@users.noreply.github.com> Date: Tue, 1 Jun 2021 17:40:27 -0400 Subject: [PATCH 1/3] julia 1.7: mutable field fix --- src/anonymous.jl | 2 +- src/extensions.jl | 12 +++++++++++- src/write.jl | 2 +- 3 files changed, 13 insertions(+), 3 deletions(-) diff --git a/src/anonymous.jl b/src/anonymous.jl index 2c20d63..cfecf98 100644 --- a/src/anonymous.jl +++ b/src/anonymous.jl @@ -67,7 +67,7 @@ function structdata(t::TypeName) isdefined(t.mt, :kwsorter) ? t.mt.kwsorter : nothing] [Base.string(VERSION), t.name, t.names, primary.super, primary.parameters, primary.types, isdefined(primary, :instance), primary.abstract, - primary.mutable, primary.ninitialized, mt] + ismutabletype(primary), primary.ninitialized, mt] end # Type Names diff --git a/src/extensions.jl b/src/extensions.jl index fa7cd20..ab91b58 100644 --- a/src/extensions.jl +++ b/src/extensions.jl @@ -32,6 +32,16 @@ lower(m::Module) = ref(modpath(m)...) # Types +@static if VERSION < v"1.7.0-DEV" + # Borrowed from julia base + function ismutabletype(@nospecialize(t::Type)) + t = Base.unwrap_unionall(t) + # TODO: what to do for `Union`? + return isa(t, DataType) && t.mutable + end +end + + ismutable(::Type{<:Type}) = false typepath(x::DataType) = [modpath(x.name.module)..., x.name.name] @@ -103,7 +113,7 @@ function newstruct!(x, fs...) end function newstruct(T, xs...) - if !T.mutable + if !ismutabletype(T) flds = Any[convert(fieldtype(T, i), x) for (i,x) in enumerate(xs)] return ccall(:jl_new_structv, Any, (Any,Ptr{Cvoid},UInt32), T, flds, length(flds)) else diff --git a/src/write.jl b/src/write.jl index 0f7e086..d05c4f0 100644 --- a/src/write.jl +++ b/src/write.jl @@ -43,7 +43,7 @@ lower(x::Primitive) = x import Base: RefValue -ismutable(T) = !isa(T, DataType) || T.mutable +ismutable(T) = !isa(T, DataType) || ismutabletype(T) ismutable(::Type{String}) = false typeof_(x) = typeof(x) From 445548abd78864754bab2d65a3ca10315a73dc80 Mon Sep 17 00:00:00 2001 From: Mauro Werder Date: Thu, 30 Sep 2021 09:33:47 +0200 Subject: [PATCH 2/3] Mostly fixed the 1.7 issues except for annonymous function test --- src/anonymous.jl | 4 ++-- src/extensions.jl | 8 +++----- test/runtests.jl | 24 ++++++++++++++---------- 3 files changed, 19 insertions(+), 17 deletions(-) diff --git a/src/anonymous.jl b/src/anonymous.jl index cfecf98..2929fd7 100644 --- a/src/anonymous.jl +++ b/src/anonymous.jl @@ -19,7 +19,7 @@ structdata(meth::Method) = _uncompress(meth, meth.source)] else structdata(meth::Method) = - [meth.module, meth.name, meth.file, meth.line, meth.sig, getfield(meth, syms_fieldname), + [meth.module, meth.name, meth.file, meth.line, meth.sig, getfield(meth, syms_fieldname), meth.nargs, meth.isva, meth.nospecialize, _uncompress(meth, meth.source)] end @@ -66,7 +66,7 @@ function structdata(t::TypeName) [t.mt.name, collect(Base.MethodList(t.mt)), t.mt.max_args, isdefined(t.mt, :kwsorter) ? t.mt.kwsorter : nothing] [Base.string(VERSION), t.name, t.names, primary.super, primary.parameters, - primary.types, isdefined(primary, :instance), primary.abstract, + primary.types, isdefined(primary, :instance), isabstracttype(primary), ismutabletype(primary), primary.ninitialized, mt] end diff --git a/src/extensions.jl b/src/extensions.jl index ab91b58..3c22dcf 100644 --- a/src/extensions.jl +++ b/src/extensions.jl @@ -93,10 +93,8 @@ tags[:array] = d -> # Structs -isprimitive(T) = fieldcount(T) == 0 && T.size > 0 - -structdata(x) = isprimitive(typeof(x)) ? reinterpret_(UInt8, [x]) : - Any[getfield(x, f) for f in fieldnames(typeof(x))] +structdata(x) = isprimitivetype(typeof(x)) ? reinterpret_(UInt8, [x]) : + Any[getfield(x,f) for f in fieldnames(typeof(x)) if isdefined(x, f)] function lower(x) BSONDict(:tag => "struct", :type => typeof(x), :data => structdata(x)) @@ -139,7 +137,7 @@ end newprimitive(T, data) = reinterpret_(T, data)[1] tags[:struct] = d -> - isprimitive(d[:type]) ? + isprimitivetype(d[:type]) ? newprimitive(d[:type], d[:data]) : newstruct(d[:type], d[:data]...) diff --git a/test/runtests.jl b/test/runtests.jl index b34d1c3..8472fcd 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -8,7 +8,7 @@ end # avoid hitting bug where # Dict{Symbol,T} -> Dict{Symbol,Any} -function roundtrip_equal(x::Dict{Symbol}) +function roundtrip_equal(x::Dict{Symbol}) y = BSON.roundtrip(x) y isa Dict{Symbol} && y == x end @@ -82,15 +82,19 @@ end @testset "Anonymous Functions" begin f = x -> x+1 - f2 = BSON.roundtrip(f) - @test f2(5) == f(5) - @test typeof(f2) !== typeof(f) - - chicken_tikka_masala(y) = x -> x+y - f = chicken_tikka_masala(5) - f2 = BSON.roundtrip(f) - @test f2(6) == f(6) - @test typeof(f2) !== typeof(f) + if VERSION < v"1.7-" + f2 = BSON.roundtrip(f) + @test f2(5) == f(5) + @test typeof(f2) !== typeof(f) + + chicken_tikka_masala(y) = x -> x+y + f = chicken_tikka_masala(5) + f2 = BSON.roundtrip(f) + @test f2(6) == f(6) + @test typeof(f2) !== typeof(f) + else + @test_throws ErrorException f2 = BSON.roundtrip(f) + end end @testset "Int Literals in Type Params #41" begin From 4fd3ae9a5c7de696ede37bc47b2c547bbda15ade Mon Sep 17 00:00:00 2001 From: Mauro Werder Date: Thu, 30 Sep 2021 17:36:00 +0200 Subject: [PATCH 3/3] Added tests to reconstruct an undef fields --- test/runtests.jl | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/test/runtests.jl b/test/runtests.jl index 8472fcd..51e2424 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -23,6 +23,11 @@ end struct S end +struct Bar + a + Bar() = new() +end + module A using DataFrames, BSON d = DataFrame(a = 1:10, b = rand(10)) @@ -39,6 +44,22 @@ end @test roundtrip_equal("b") @test roundtrip_equal([1,"b"]) @test roundtrip_equal(Tuple) + @test roundtrip_equal(Tuple{Int, Float64}) + @test roundtrip_equal(Vararg{Any}) +end + +@testset "Undefined References" begin + # from Issue #3 + d = Dict(:a => 1, :b => Dict(:c => 3, :d => Dict("e" => 5))) + @test roundtrip_equal(d) + + # from Issue #43 + x = Array{String, 1}(undef, 5) + x[1] = "a" + x[4] = "d" + @test_broken roundtrip_equal(Dict(:x => x)) + + @test roundtrip_equal(Bar()) end @testset "Complex Types" begin