Skip to content

Commit 3b4a2ce

Browse files
Merge pull request #103 from mauro3/m3/fix17
Fix all but one 1.7 issues
2 parents ecae116 + 4fd3ae9 commit 3b4a2ce

File tree

4 files changed

+53
-20
lines changed

4 files changed

+53
-20
lines changed

src/anonymous.jl

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ structdata(meth::Method) =
1919
_uncompress(meth, meth.source)]
2020
else
2121
structdata(meth::Method) =
22-
[meth.module, meth.name, meth.file, meth.line, meth.sig, getfield(meth, syms_fieldname),
22+
[meth.module, meth.name, meth.file, meth.line, meth.sig, getfield(meth, syms_fieldname),
2323
meth.nargs, meth.isva, meth.nospecialize, _uncompress(meth, meth.source)]
2424
end
2525

@@ -66,8 +66,8 @@ function structdata(t::TypeName)
6666
[t.mt.name, collect(Base.MethodList(t.mt)), t.mt.max_args,
6767
isdefined(t.mt, :kwsorter) ? t.mt.kwsorter : nothing]
6868
[Base.string(VERSION), t.name, t.names, primary.super, primary.parameters,
69-
primary.types, isdefined(primary, :instance), primary.abstract,
70-
primary.mutable, primary.ninitialized, mt]
69+
primary.types, isdefined(primary, :instance), isabstracttype(primary),
70+
ismutabletype(primary), primary.ninitialized, mt]
7171
end
7272

7373
# Type Names

src/extensions.jl

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,16 @@ lower(m::Module) = ref(modpath(m)...)
3232

3333
# Types
3434

35+
@static if VERSION < v"1.7.0-DEV"
36+
# Borrowed from julia base
37+
function ismutabletype(@nospecialize(t::Type))
38+
t = Base.unwrap_unionall(t)
39+
# TODO: what to do for `Union`?
40+
return isa(t, DataType) && t.mutable
41+
end
42+
end
43+
44+
3545
ismutable(::Type{<:Type}) = false
3646

3747
typepath(x::DataType) = [modpath(x.name.module)..., x.name.name]
@@ -83,10 +93,8 @@ tags[:array] = d ->
8393

8494
# Structs
8595

86-
isprimitive(T) = fieldcount(T) == 0 && T.size > 0
87-
88-
structdata(x) = isprimitive(typeof(x)) ? reinterpret_(UInt8, [x]) :
89-
Any[getfield(x, f) for f in fieldnames(typeof(x))]
96+
structdata(x) = isprimitivetype(typeof(x)) ? reinterpret_(UInt8, [x]) :
97+
Any[getfield(x,f) for f in fieldnames(typeof(x)) if isdefined(x, f)]
9098

9199
function lower(x)
92100
BSONDict(:tag => "struct", :type => typeof(x), :data => structdata(x))
@@ -103,7 +111,7 @@ function newstruct!(x, fs...)
103111
end
104112

105113
function newstruct(T, xs...)
106-
if !T.mutable
114+
if !ismutabletype(T)
107115
flds = Any[convert(fieldtype(T, i), x) for (i,x) in enumerate(xs)]
108116
return ccall(:jl_new_structv, Any, (Any,Ptr{Cvoid},UInt32), T, flds, length(flds))
109117
else
@@ -129,7 +137,7 @@ end
129137
newprimitive(T, data) = reinterpret_(T, data)[1]
130138

131139
tags[:struct] = d ->
132-
isprimitive(d[:type]) ?
140+
isprimitivetype(d[:type]) ?
133141
newprimitive(d[:type], d[:data]) :
134142
newstruct(d[:type], d[:data]...)
135143

src/write.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ lower(x::Primitive) = x
4343

4444
import Base: RefValue
4545

46-
ismutable(T) = !isa(T, DataType) || T.mutable
46+
ismutable(T) = !isa(T, DataType) || ismutabletype(T)
4747
ismutable(::Type{String}) = false
4848

4949
typeof_(x) = typeof(x)

test/runtests.jl

Lines changed: 35 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ end
88

99
# avoid hitting bug where
1010
# Dict{Symbol,T} -> Dict{Symbol,Any}
11-
function roundtrip_equal(x::Dict{Symbol})
11+
function roundtrip_equal(x::Dict{Symbol})
1212
y = BSON.roundtrip(x)
1313
y isa Dict{Symbol} && y == x
1414
end
@@ -23,6 +23,11 @@ end
2323

2424
struct S end
2525

26+
struct Bar
27+
a
28+
Bar() = new()
29+
end
30+
2631
module A
2732
using DataFrames, BSON
2833
d = DataFrame(a = 1:10, b = rand(10))
@@ -39,6 +44,22 @@ end
3944
@test roundtrip_equal("b")
4045
@test roundtrip_equal([1,"b"])
4146
@test roundtrip_equal(Tuple)
47+
@test roundtrip_equal(Tuple{Int, Float64})
48+
@test roundtrip_equal(Vararg{Any})
49+
end
50+
51+
@testset "Undefined References" begin
52+
# from Issue #3
53+
d = Dict(:a => 1, :b => Dict(:c => 3, :d => Dict("e" => 5)))
54+
@test roundtrip_equal(d)
55+
56+
# from Issue #43
57+
x = Array{String, 1}(undef, 5)
58+
x[1] = "a"
59+
x[4] = "d"
60+
@test_broken roundtrip_equal(Dict(:x => x))
61+
62+
@test roundtrip_equal(Bar())
4263
end
4364

4465
@testset "Complex Types" begin
@@ -82,15 +103,19 @@ end
82103

83104
@testset "Anonymous Functions" begin
84105
f = x -> x+1
85-
f2 = BSON.roundtrip(f)
86-
@test f2(5) == f(5)
87-
@test typeof(f2) !== typeof(f)
88-
89-
chicken_tikka_masala(y) = x -> x+y
90-
f = chicken_tikka_masala(5)
91-
f2 = BSON.roundtrip(f)
92-
@test f2(6) == f(6)
93-
@test typeof(f2) !== typeof(f)
106+
if VERSION < v"1.7-"
107+
f2 = BSON.roundtrip(f)
108+
@test f2(5) == f(5)
109+
@test typeof(f2) !== typeof(f)
110+
111+
chicken_tikka_masala(y) = x -> x+y
112+
f = chicken_tikka_masala(5)
113+
f2 = BSON.roundtrip(f)
114+
@test f2(6) == f(6)
115+
@test typeof(f2) !== typeof(f)
116+
else
117+
@test_throws ErrorException f2 = BSON.roundtrip(f)
118+
end
94119
end
95120

96121
@testset "Int Literals in Type Params #41" begin

0 commit comments

Comments
 (0)