From 0a8b4855dfad6408a8f1a6e3e95ac987f5f59a79 Mon Sep 17 00:00:00 2001 From: Lyndon White Date: Mon, 18 Nov 2019 18:35:42 +0000 Subject: [PATCH 1/3] Revert "Merge pull request #35 from invenia/ox/undobreaking" This reverts commit b8c8803c0a0a000f86df898b13c2e63211b9b520. --- Project.toml | 9 +- src/JLSO.jl | 14 +- src/JLSOFile.jl | 63 +++++++-- src/deprecated.jl | 123 ++++++++++++++++++ src/file_io.jl | 81 +++++++----- src/metadata.jl | 34 +++++ src/serialization.jl | 5 +- test/JLSOFile.jl | 23 +++- test/backwards_compat.jl | 54 ++++++-- test/file_io.jl | 50 ++++++- test/runtests.jl | 4 +- test/specimens/v3_bson_gzip.jlso | Bin 0 -> 15366 bytes test/specimens/v3_bson_gzip_fastest.jlso | Bin 0 -> 17213 bytes test/specimens/v3_bson_gzip_smallest.jlso | Bin 0 -> 14616 bytes test/specimens/v3_bson_none.jlso | Bin 0 -> 282063 bytes test/specimens/v3_julia_serialize_gzip.jlso | Bin 0 -> 9771 bytes .../v3_julia_serialize_gzip_fastest.jlso | Bin 0 -> 10370 bytes .../v3_julia_serialize_gzip_smallest.jlso | Bin 0 -> 9771 bytes test/specimens/v3_julia_serialize_none.jlso | Bin 0 -> 26777 bytes test/test_data_setup.jl | 15 ++- 20 files changed, 390 insertions(+), 85 deletions(-) create mode 100644 src/deprecated.jl create mode 100644 test/specimens/v3_bson_gzip.jlso create mode 100644 test/specimens/v3_bson_gzip_fastest.jlso create mode 100644 test/specimens/v3_bson_gzip_smallest.jlso create mode 100644 test/specimens/v3_bson_none.jlso create mode 100644 test/specimens/v3_julia_serialize_gzip.jlso create mode 100644 test/specimens/v3_julia_serialize_gzip_fastest.jlso create mode 100644 test/specimens/v3_julia_serialize_gzip_smallest.jlso create mode 100644 test/specimens/v3_julia_serialize_none.jlso diff --git a/Project.toml b/Project.toml index ce1aaf5..6c37e90 100644 --- a/Project.toml +++ b/Project.toml @@ -2,7 +2,7 @@ name = "JLSO" uuid = "9da8a3cd-07a3-59c0-a743-3fdc52c30d11" license = "MIT" authors = ["Invenia Technical Computing Corperation"] -version = "1.2.1" +version = "1.2.0" [deps] BSON = "fbb218c0-5317-5bc6-957e-2ee96dd4b1f0" @@ -21,9 +21,14 @@ julia = "0.7, 1.0" [extras] AxisArrays = "39de3d68-74b9-583c-8d2d-e117c070f3a9" DataFrames = "a93c6f00-e57d-5684-b7b6-d8193f3e46c0" +Dates = "ade2ca70-3891-5945-98fb-dc099432e06a" +Distributed = "8ba89e20-285c-5b6f-9357-94700520ee1b" Distributions = "31c24e10-a181-5473-b8eb-7969acd0382f" +InteractiveUtils = "b77e0a4c-d291-57a0-90e8-8db25a27a240" +Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" +Suppressor = "fd094767-a336-5f1f-9728-57cf17d0bbfb" Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" TimeZones = "f269a46b-ccf7-5d73-abea-4c690281aa53" [targets] -test = ["AxisArrays", "DataFrames", "Distributions", "Test", "TimeZones"] +test = ["AxisArrays", "DataFrames", "Dates", "Distributed", "Distributions", "InteractiveUtils", "Random", "Suppressor", "Test", "TimeZones"] diff --git a/src/JLSO.jl b/src/JLSO.jl index ea25c76..c7aa533 100644 --- a/src/JLSO.jl +++ b/src/JLSO.jl @@ -16,10 +16,8 @@ Dict( "format" => :bson, # Could also be :julia_serialize "compression" => :gzip_fastest, # could also be: :none, :gzip_smallest, or :gzip "image" => "xxxxxxxxxxxx.dkr.ecr.us-east-1.amazonaws.com/myrepository:latest" - "pkgs" => Dict( - "AxisArrays" => v"0.2.1", - ... - ) + "project" => Dict{String, Any}(...), + "manifest" => Dict{String, Any}(...), ), "objects" => Dict( "var1" => [0x35, 0x10, 0x01, 0x04, 0x44], @@ -44,15 +42,19 @@ using Memento using Pkg: Pkg using Pkg.Types: semver_spec +# We need to import these cause of a deprecation on object index via strings. +import Base: getindex, setindex! + export JLSOFile -const READABLE_VERSIONS = semver_spec("1, 2") -const WRITEABLE_VERSIONS = semver_spec("2") +const READABLE_VERSIONS = semver_spec("1, 2, 3") +const WRITEABLE_VERSIONS = semver_spec("3") const LOGGER = getlogger(@__MODULE__) __init__() = Memento.register(LOGGER) include("JLSOFile.jl") +include("deprecated.jl") include("file_io.jl") include("metadata.jl") include("serialization.jl") diff --git a/src/JLSOFile.jl b/src/JLSOFile.jl index 30be065..dae98a5 100644 --- a/src/JLSOFile.jl +++ b/src/JLSOFile.jl @@ -4,8 +4,9 @@ struct JLSOFile format::Symbol compression::Symbol image::String - pkgs::Dict{String, VersionNumber} - objects::Dict{String, Vector{UInt8}} + project::Dict{String, Any} + manifest::Dict{String, Any} + objects::Dict{Symbol, Vector{UInt8}} end """ @@ -31,8 +32,8 @@ Stores the information needed to write a .jlso file. Due to the time taken for disk IO, :none is not normally as fast as using some compression. """ function JLSOFile( - data::Dict{String, <:Any}; - version=v"2.0.0", + data::Dict{Symbol, <:Any}; + version=v"3", julia=VERSION, format=:julia_serialize, compression=:gzip, @@ -45,8 +46,17 @@ function JLSOFile( end _versioncheck(version, WRITEABLE_VERSIONS) - objects = Dict{String, Vector{UInt8}}() - jlso = JLSOFile(version, julia, format, compression, image, _pkgs(), objects) + project_toml, manifest_toml = _env() + jlso = JLSOFile( + version, + julia, + format, + compression, + image, + Pkg.TOML.parse(project_toml), + Pkg.TOML.parse(manifest_toml), + Dict{Symbol, Vector{UInt8}}(), + ) for (key, val) in data jlso[key] = val @@ -55,15 +65,33 @@ function JLSOFile( return jlso end -JLSOFile(data; kwargs...) = JLSOFile(Dict("data" => data); kwargs...) -JLSOFile(data::Pair...; kwargs...) = JLSOFile(Dict(data...); kwargs...) +function JLSOFile(; + version=v"3", + julia=VERSION, + format=:julia_serialize, + compression=:gzip, + image=_image(), + kwargs... +) + return JLSOFile( + Dict(kwargs); + version=version, + julia=julia, + format=format, + compression=compression, + image=image, + ) +end + + +JLSOFile(data::Pair...; kwargs...) = JLSOFile(Dict(data); kwargs...) function Base.show(io::IO, jlso::JLSOFile) variables = join(names(jlso), ", ") kwargs = join( [ - "version=v\"$(jlso.version)\"", - "julia=v\"$(jlso.julia)\"", + "version=\"$(jlso.version)\"", + "julia=\"$(jlso.julia)\"", "format=:$(jlso.format)", "compression=:$(jlso.compression)", "image=\"$(jlso.image)\"", @@ -79,7 +107,7 @@ function Base.:(==)(a::JLSOFile, b::JLSOFile) a.version == b.version && a.julia == b.julia && a.image == b.image && - a.pkgs == b.pkgs && + a.manifest == b.manifest && a.format == b.format && a.compression == b.compression && a.objects == b.objects @@ -87,5 +115,14 @@ function Base.:(==)(a::JLSOFile, b::JLSOFile) end Base.names(jlso::JLSOFile) = collect(keys(jlso.objects)) - -# TODO: Include a more detail summary method for displaying version information. +function Base.getproperty(jlso::JLSOFile, attr::Symbol) + if attr === :pkgs + @warn "pkgs property is deprecated, use .manifest instead" + return Dict( + name => VersionNumber(get(first(spec), "version", "0.0.0")) + for (name, spec) in jlso.manifest + ) + else + return getfield(jlso, attr) + end +end diff --git a/src/deprecated.jl b/src/deprecated.jl new file mode 100644 index 0000000..af22cc0 --- /dev/null +++ b/src/deprecated.jl @@ -0,0 +1,123 @@ +@deprecate( + JLSOFile( + version::VersionNumber, + julia::VersionNumber, + format::Symbol, + compression::Symbol, + image::String, + pkgs::Dict{String, VersionNumber}, + objects::Dict{String, Vector{UInt8}}, + ), + JLSOFile( + version, + julia, + format, + compression, + image, + Pkg.TOML.parse.(_upgrade_env(pkgs))..., + Dict{Symbol, Vector{UInt8}}(Symbol(k) => v for (k, v) in objects), + ) +) + +@deprecate JLSOFile(data; kwargs...) JLSOFile(:data => data; kwargs...) +@deprecate( + JLSOFile(data::Dict{String, <:Any}; kwargs...), + JLSOFile(Dict(Symbol(k) => v for (k, v) in data); kwargs...) +) + +function upgrade_jlso(raw_dict::AbstractDict) + result = copy(raw_dict) + version = version_number(result["metadata"]["version"]) + + while version < v"3" + result = upgrade_jlso(result, Val(Int(version.major))) + version = version_number(result["metadata"]["version"]) + end + + return result +end + +@deprecate getindex(jlso::JLSOFile, name::String) getindex(jlso, Symbol(name)) +@deprecate setindex!(jlso::JLSOFile, value, name::String) setindex!(jlso, value, Symbol(name)) + +# v1 and v2 stored version numbers but v3 stores strings to be bson parser agnostic +version_number(x::VersionNumber) = x +version_number(x::String) = VersionNumber(x) + +# Metadata changes to upgrade file from v1 to v2 +function upgrade_jlso(raw_dict::AbstractDict, ::Val{1}) + info(LOGGER, "Upgrading JLSO format from v1 to v2") + metadata = copy(raw_dict["metadata"]) + version = version_number(metadata["version"]) + @assert version ∈ semver_spec("1") + + if metadata["format"] == :serialize + metadata["format"] = :julia_serialize + end + + metadata["compression"] = :none + metadata["version"] = v"2" + + return Dict("metadata" => metadata, "objects" => get(raw_dict, "objects", Dict())) +end + +# Metadata changes to upgrade from v2 to v3 +function upgrade_jlso(raw_dict::AbstractDict, ::Val{2}) + info(LOGGER, "Upgrading JLSO format from v2 to v3") + metadata = copy(raw_dict["metadata"]) + version = version_number(metadata["version"]) + @assert version ∈ semver_spec("2") + + # JLSO v3 expects to be loading a compressed manifest + compression = get(metadata, "compression", :none) + project, manifest = _upgrade_env(get(metadata, "pkgs", nothing)) + + return Dict{String, Dict}( + "metadata" => Dict{String, Union{String, Vector{UInt8}}}( + "version" => "3", + "julia" => string(get(metadata, "julia", VERSION)), + "format" => string(get(metadata, "format", :julia_serialize)), + "compression" => string(compression), + "image" => get(metadata, "image", ""), + "project" => project, + "manifest" => read(compress(compression, IOBuffer(manifest))), + ), + "objects" => Dict{String, Vector{UInt8}}( + k => v for (k, v) in get(raw_dict, "objects", Dict()) + ), + ) +end + +# Used to convert the old "PkgName" => VersionNumber metadata to a +# Project.toml and Manifest.toml file. +function _upgrade_env(pkgs::Dict) + src_env = Base.active_project() + + try + mktempdir() do tmp + Pkg.activate(tmp) + + # We construct an array of PackageSpecs to avoid ordering problems with + # adding each package individually + try + Pkg.add([ + Pkg.PackageSpec(; name=key, version=value) for (key, value) in pkgs + ]) + catch e + # Warn about failure and fallback to simply trying to install the pacakges + # without version constraints. + warn(LOGGER) do + "Failed to construct an environment with the provide package version " * + "($pkgs): $e.\n Falling back to simply adding the packages." + end + Pkg.add([Pkg.PackageSpec(; name=key) for (key, value) in pkgs]) + end + + return _env() + end + finally + Pkg.activate(src_env) + end +end + +_upgrade_env(::Nothing) = ("", "") diff --git a/src/file_io.jl b/src/file_io.jl index ed66090..6f2e044 100644 --- a/src/file_io.jl +++ b/src/file_io.jl @@ -4,18 +4,30 @@ function Base.write(io::IO, jlso::JLSOFile) _versioncheck(jlso.version, WRITEABLE_VERSIONS) + + # Setup an IOBuffer for serializing the manifest + project_toml = sprint(Pkg.TOML.print, jlso.project) + # @show jlso.manifest + manifest_toml = read( + compress(jlso.compression, IOBuffer(sprint(Pkg.TOML.print, jlso.manifest))) + ) + bson( io, - Dict( - "metadata" => Dict( - "version" => jlso.version, - "julia" => jlso.julia, - "format" => jlso.format, - "compression" => jlso.compression, + # We declare the dict types to be more explicit about the output format. + Dict{String, Dict}( + "metadata" => Dict{String, Union{String, Vector{UInt8}}}( + "version" => string(jlso.version), + "julia" => string(jlso.julia), + "format" => string(jlso.format), + "compression" => string(jlso.compression), "image" => jlso.image, - "pkgs" => jlso.pkgs, + "project" => project_toml, + "manifest" => manifest_toml, + ), + "objects" => Dict{String, Vector{UInt8}}( + string(k) => v for (k, v) in jlso.objects ), - "objects" => jlso.objects, ) ) end @@ -23,33 +35,36 @@ end # `read`, unlike `load` does not deserialize any of the objects within the JLSO file, # they will be `deserialized` when they are indexed out of the returned JSLOFile object. function Base.read(io::IO, ::Type{JLSOFile}) - d = BSON.load(io) - _versioncheck(d["metadata"]["version"], READABLE_VERSIONS) - upgrade_jlso!(d) + parsed = BSON.load(io) + _versioncheck(parsed["metadata"]["version"], READABLE_VERSIONS) + d = upgrade_jlso(parsed) + compression = Symbol(d["metadata"]["compression"]) + + # Try decompressing the manifest, otherwise just return a dict with the raw data + manifest = try + Pkg.TOML.parse( + read( + decompress(compression, IOBuffer(d["metadata"]["manifest"])), + String + ) + ) + catch e + warn(LOGGER, e) + Dict("raw" => d["metadata"]["manifest"]) + end + return JLSOFile( - d["metadata"]["version"], - d["metadata"]["julia"], - d["metadata"]["format"], - d["metadata"]["compression"], + VersionNumber(d["metadata"]["version"]), + VersionNumber(d["metadata"]["julia"]), + Symbol(d["metadata"]["format"]), + compression, d["metadata"]["image"], - d["metadata"]["pkgs"], - d["objects"], + Pkg.TOML.parse(d["metadata"]["project"]), + manifest, + Dict{Symbol, Vector{UInt8}}(Symbol(k) => v for (k, v) in d["objects"]), ) end -function upgrade_jlso!(raw_dict::AbstractDict) - metadata = raw_dict["metadata"] - if metadata["version"] ∈ semver_spec("1") - if metadata["format"] == :serialize - metadata["format"] = :julia_serialize - end - metadata["compression"] = :none - metadata["version"] = v"2" - end - return raw_dict -end - - """ save(io, data) save(path, data) @@ -61,8 +76,8 @@ save(io::IO, data::Pair...; kwargs...) = save(io, Dict(data...); kwargs...) save(path::String, args...; kwargs...) = open(io -> save(io, args...; kwargs...), path, "w") """ - load(io, objects...) -> Dict{String, Any} - load(path, objects...) -> Dict{String, Any} + load(io, objects...) -> Dict{Symbol, Any} + load(path, objects...) -> Dict{Symbol, Any} Load the JLSOFile from the io and deserialize the specified objects. If no object names are specified then all objects in the file are returned. @@ -71,7 +86,7 @@ load(path::String, args...) = open(io -> load(io, args...), path) function load(io::IO, objects::String...) jlso = read(io, JLSOFile) objects = isempty(objects) ? names(jlso) : objects - result = Dict{String, Any}() + result = Dict{Symbol, Any}() for o in objects # Note that calling getindex on the jlso triggers the deserialization of the object diff --git a/src/metadata.jl b/src/metadata.jl index 1ebb00a..5dbe081 100644 --- a/src/metadata.jl +++ b/src/metadata.jl @@ -8,9 +8,14 @@ function _versioncheck(version::VersionNumber, valid_versions) )) end +function _versioncheck(version::String, valid_versions) + return _versioncheck(VersionNumber(version), valid_versions) +end # Cache of the versioninfo and image, so we don't compute these every time. const _CACHE = Dict( + :MANIFEST => "", + :PROJECT => "", :PKGS => Dict{String, VersionNumber}(), :IMAGE => "", ) @@ -28,6 +33,18 @@ function _pkgs() return _CACHE[:PKGS] end +function _env() + if isempty(_CACHE[:PROJECT]) && isempty(_CACHE[:MANIFEST]) + _CACHE[:PROJECT] = read(Base.active_project(), String) + _CACHE[:MANIFEST] = read( + joinpath(dirname(Base.active_project()), "Manifest.toml"), + String + ) + end + + return (_CACHE[:PROJECT], _CACHE[:MANIFEST]) +end + function _image() if isempty(_CACHE[:IMAGE]) && haskey(ENV, "JLSO_IMAGE") return ENV["JLSO_IMAGE"] @@ -35,3 +52,20 @@ function _image() return _CACHE[:IMAGE] end + +function Pkg.activate(jlso::JLSOFile, path=tempdir(); kwargs...) + mkpath(path) + open(io -> Pkg.TOML.print(io, jlso.project), joinpath(path, "Project.toml"), "w") + open(io -> Pkg.TOML.print(io, jlso.manifest), joinpath(path, "Manifest.toml"), "w") + Pkg.activate(path; kwargs...) +end + +function Pkg.activate(f::Function, jlso::JLSOFile, path=tempdir(); kwargs...) + curr_env = dirname(Base.active_project()) + try + Pkg.activate(jlso, path; kwargs...) + f() + finally + Pkg.activate(curr_env) + end +end diff --git a/src/serialization.jl b/src/serialization.jl index fff9644..8d018f6 100644 --- a/src/serialization.jl +++ b/src/serialization.jl @@ -26,7 +26,6 @@ decompress(::Compressor{:gzip_fastest}, io) = GzipDecompressorStream(io) compress(::Compressor{:gzip_smallest}, io) = GzipCompressorStream(io; level=9) decompress(::Compressor{:gzip_smallest}, io) = GzipDecompressorStream(io) - """ complete_compression(compressing_buffer) Writes any end of compression sequence to the compressing buffer; @@ -47,7 +46,7 @@ end Returns the deserialized object with the specified name. """ -function Base.getindex(jlso::JLSOFile, name::String) +function getindex(jlso::JLSOFile, name::Symbol) try buffer = IOBuffer(jlso.objects[name]) decompressing_buffer = decompress(jlso.compression, buffer) @@ -63,7 +62,7 @@ end Adds the object to the file and serializes it. """ -function Base.setindex!(jlso::JLSOFile, value, name::String) +function setindex!(jlso::JLSOFile, value, name::Symbol) buffer = IOBuffer() compressing_buffer = compress(jlso.compression, buffer) serialize(jlso.format, compressing_buffer, value) diff --git a/test/JLSOFile.jl b/test/JLSOFile.jl index 0a757a0..06adae3 100644 --- a/test/JLSOFile.jl +++ b/test/JLSOFile.jl @@ -16,6 +16,12 @@ @test jlso.objects[k] == expected end + + @testset "kwarg constructor" begin + jlso = JLSOFile(; a=collect(1:10), b="hello") + @test jlso[:b] == "hello" + @test haskey(jlso.pkgs, "BSON") + end end @testset "unknown format" begin @@ -27,10 +33,25 @@ end end @testset "show" begin - jlso = JLSOFile(datas["String"]) + jlso = JLSOFile(datas[:String]) expected = string( "JLSOFile([data]; version=v\"2.0.0\", julia=v\"$VERSION\", ", "format=:julia_serialize, image=\"\")" ) @test sprint(show, jlso) == sprint(print, jlso) end + +@testset "activate" begin + jlso = JLSOFile(datas[:String]) + mktempdir() do d + Pkg.activate(jlso, d) do + @show Base.active_project() + end + + @test ispath(joinpath(d, "Project.toml")) + @test ispath(joinpath(d, "Manifest.toml")) + + @test Pkg.TOML.parsefile(joinpath(d, "Project.toml")) == jlso.project + @test Pkg.TOML.parsefile(joinpath(d, "Manifest.toml")) == jlso.manifest + end +end diff --git a/test/backwards_compat.jl b/test/backwards_compat.jl index 02ec89c..5ffed31 100644 --- a/test/backwards_compat.jl +++ b/test/backwards_compat.jl @@ -1,23 +1,52 @@ @testset "upgrade_jlso" begin @testset "no change for current version" begin - d = Dict("metadata" => Dict("version" => v"2.0")) - upgrade_jlso!(d) - @test d == Dict("metadata" => Dict("version" => v"2.0")) + d = Dict("metadata" => Dict("version" => v"3.0")) + new_d = @suppress_out upgrade_jlso(d) + @test new_d == Dict("metadata" => Dict("version" => v"3.0")) end @testset "upgrade 1.0" begin d = Dict("metadata" => Dict("version" => v"1.0", "format"=>:serialize)) - upgrade_jlso!(d) - @test d == Dict("metadata" => Dict( - "version" => v"2.0", "format"=>:julia_serialize, "compression" => :none - )) + new_d = @suppress_out upgrade_jlso(d) + @test new_d["metadata"]["version"] == "3" + @test new_d["metadata"]["format"] == "julia_serialize" + @test new_d["metadata"]["compression"] == "none" + @test isempty(new_d["metadata"]["project"]) + @test isempty(new_d["metadata"]["manifest"]) + @test isempty(new_d["objects"]) @testset "Don't rename bson format" begin d = Dict("metadata" => Dict("version" => v"1.0", "format"=>:bson)) - upgrade_jlso!(d) - @test d == Dict("metadata" => Dict( - "version" => v"2.0", "format"=>:bson, "compression" => :none - )) + new_d = @suppress_out upgrade_jlso(d) + @test new_d["metadata"]["version"] == "3" + @test new_d["metadata"]["format"] == "bson" + @test new_d["metadata"]["compression"] == "none" + @test isempty(new_d["metadata"]["project"]) + @test isempty(new_d["metadata"]["manifest"]) + @test isempty(new_d["objects"]) + end + + @testset "Invalid VersionNumber" begin + d = Dict( + "metadata" => Dict( + "version" => v"1.0", "format" => :bson, + # We don't intend to go back an make a 0.3.14 release at any point. + "pkgs" => merge(pkgs, Dict("JLSO" => v"0.3.14")), + ) + ) + + new_d = @suppress_out upgrade_jlso(d) + @test !isempty(new_d["metadata"]["project"]) + @test !isempty(new_d["metadata"]["manifest"]) + + # Test that the project.toml has the JLSO dep, but not a specific version + # (fallback when package versions don't exist in the registry) + _project = Pkg.TOML.parse(new_d["metadata"]["project"]) + @test haskey(_project, "deps") + @test haskey(_project["deps"], "JLSO") + @test haskey(_project, "compat") + # Check that the compat section doesn't have our package version + @test !haskey(_project["compat"], "JLSO") end end end @@ -29,6 +58,7 @@ end @testset "Can still load old files" begin dir = joinpath(@__DIR__, "specimens") @testset "$fn" for fn in readdir(dir) - @test JLSO.load(joinpath(dir, fn)) == datas + jlso_data = @suppress_out JLSO.load(joinpath(dir, fn)) + @test jlso_data == datas end end diff --git a/test/file_io.jl b/test/file_io.jl index 526b48e..192b78d 100644 --- a/test/file_io.jl +++ b/test/file_io.jl @@ -7,6 +7,13 @@ seekstart(io) result = read(io, JLSOFile) + @test result.version == orig.version + @test result.julia == orig.julia + @test result.image == orig.image + @test result.manifest == orig.manifest + @test result.format == orig.format + @test result.compression == orig.compression + @test result.objects == orig.objects @test result == orig end end @@ -18,12 +25,27 @@ end @test jlso["data"] == v end - @testset "unsupported julia version" begin - jlso = JLSOFile(v"1.0", VERSION, :julia_serialize, :none, img, pkgs, Dict("data" => hw_5)) + @testset "unsupported julia version $jlso_version" for jlso_version in (v"1.0", v"2.0") + jlso = @suppress_out begin + JLSOFile( + jlso_version, + VERSION, + :julia_serialize, + :none, + img, + pkgs, + Dict("data" => hw_5), + ) + end # Test failing to deserialize data because of incompatible julia versions # will return the raw bytes - result = @test_warn(LOGGER, r"MethodError*", jlso["data"]) + result = if VERSION < v"1.2" + @test_warn(LOGGER, r"MethodError*", jlso["data"]) + else + @test_warn(LOGGER, r"TypeError*", jlso["data"]) + end + @test result == hw_5 # TODO: Test that BSON works across julia versions using external files? @@ -63,12 +85,19 @@ end bytes = take!(io) jlso = JLSOFile( - v"2.0", VERSION, :julia_serialize, :none, img, pkgs, Dict("data" => bytes) + v"3.0", + VERSION, + :julia_serialize, + :none, + img, + project, + manifest, + Dict(:data => bytes), ) # Test failing to deserailize data because of missing modules will # still return the raw bytes - result = @test_warn(LOGGER, r"KeyError*", jlso["data"]) + result = @test_warn(LOGGER, r"KeyError*", jlso[:data]) @test result == bytes end @@ -78,7 +107,7 @@ end bson( io, Dict( - "data" => AxisArray( + :data => AxisArray( rand(20, 10), Axis{:time}(14010:10:14200), Axis{:id}(1:10) @@ -92,7 +121,14 @@ end bytes = take!(io) jlso = JLSOFile( - v"1.0", VERSION, :bson, :none, img, pkgs, Dict("data" => bytes) + v"3.0", + VERSION, + :bson, + :none, + img, + project, + manifest, + Dict(:data => bytes), ) # Test failing to deserailize data because of missing modules will diff --git a/test/runtests.jl b/test/runtests.jl index b16742e..d38581a 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -3,12 +3,14 @@ using Dates using Distributed using InteractiveUtils using Memento +using Pkg using Random using Serialization +using Suppressor using Test using JLSO -using JLSO: JLSOFile, LOGGER, upgrade_jlso! +using JLSO: JLSOFile, LOGGER, upgrade_jlso # To test different types from common external packages using DataFrames diff --git a/test/specimens/v3_bson_gzip.jlso b/test/specimens/v3_bson_gzip.jlso new file mode 100644 index 0000000000000000000000000000000000000000..209744cba67a69d43012c6b4d30208ff7ff04c9c GIT binary patch literal 15366 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 literal 0 HcmV?d00001 diff --git a/test/specimens/v3_bson_gzip_fastest.jlso b/test/specimens/v3_bson_gzip_fastest.jlso new file mode 100644 index 0000000000000000000000000000000000000000..0a0b1e139fd3c11de00bf3e8341e58d25567bba8 GIT binary patch literal 17213 zcmeHvcT`i+(r*L=MT#P*fCz$!AfY6*C`F_Qf`ul%Bq5;*p*IDjDoqgSMU*PiL3&eq zN9i3A1nDTfzjLBQ@4Mgq*8Sdk-&=3J_4tEipP4=Lo8QddA^XfhObP-avPBv}$RH4i zjjgpE+7?1=>tu<6^d0#vISxn+k+w+uRT4|2HPYM$;tNQL`54+RPe*h0uV%h=B|EA7T{F&3?Ib{A>F0 z^#?dVEW-aPOR&p$mYe_sKt8B|7cHCx#!wn*i%~TJiW=Ywq~Z<|s9Z;|jLCr!AVtao zYXlI(|E_By0X#c@CJRC+L3I;g)tR8|Y=Ihw5DDRDJODC*vj%+gL$cT*kfVH%1tvh1 z*&j?4aQXB?oQtiFT1mZw_-&ON6iSt}x%XeQXiUXMJ-*2D=>ey*_F!l@d80s7X#Zu( zs5FnGBiye&s*losBG-B6;peTOsg?a5qgiXZb>IK74%auoXL=_s)x6ksPA-bSBsE%! z`%o4>EmrIlzr_~S8XIdf)w;AhwE&+HonHL(cJ^vrooTu9I~{thQC%gD?~ZblXA0$xRB3|3{auLPiNDi} zFMaqnX?9|^clv?PHtCs|qYSKqoSLEonU`%aO1Y1k?x(32T+*LyrL2h7)Aw?E3d)9YiM8P%c z%%kEYu&sCWVlqrx@3aeVMC-?|m7eIC?{jVPKwuX7o=+7C8+x@r zYh`n0baeQ7wpsm+66N!o4J$V8B|Y;#LSwQLmYhppmb-c$3iXAk%q|GGIhA+mWb08p z6)p;psV2&A>?g~g61gLPrZsKy^W}Se)fnQMj`8*>pVNL)E_E^r=^be6rzIwiZi68U zQ>uB|x7H$jwoCn=DvGr|)-C7$XzOZ2*G0xye@zyR-u~3M1uu`|jaG|Hq*Q#0p&?H( zfcL9G9VER6bt0@k?Wo9F9ZD z7fJci&jkguYjI7!$up~Wh6<`=tLILwj0x6GN(QK+Rxw42{qC}gnP_qrSuXzBHxcUt zzTi*`l-mBtd8uVw+kGvCvQ~~=)=sc*NtP|8mwy4&bsll48ubKquiXH2yXmjvhF{`` zc*9$%^F_jeky;JX2o^Rv`hsu5Rl^ZJikXJ2NtH8QJWZgP|IeMvZXE&8uhV3#RQKoxcOBb^@y3SD5`%x`NXR6a!WP zJF_zi5v{K;s+dKcn*m*x@2@;h1mS?A?iXaDLNPu882Y3t)Qiu;0+j+0ha;u7F(~)z zL(SEwh}PY6AXGUw0O|#?T^r_9f-t}#Q&0L3z}o^w;f+o(4$!}I&|LgNBIsWfM0Z7O z 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 CBUT0g literal 0 HcmV?d00001 diff --git a/test/specimens/v3_bson_gzip_smallest.jlso b/test/specimens/v3_bson_gzip_smallest.jlso new file mode 100644 index 0000000000000000000000000000000000000000..23f09238bb2ec14a77efc271ea8bb64cdd35d3a4 GIT binary patch literal 14616 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 AssI20 literal 0 HcmV?d00001 diff --git a/test/specimens/v3_julia_serialize_gzip.jlso b/test/specimens/v3_julia_serialize_gzip.jlso new file mode 100644 index 0000000000000000000000000000000000000000..6904ca900d6c14b1691dd772b4312fbe5b162d7a GIT binary patch literal 9771 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%0AftLtzRw+)3Un8Ah4i4jAlsEeH7RObRWNGaiQ1*U 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 literal 0 HcmV?d00001 diff --git a/test/specimens/v3_julia_serialize_gzip_smallest.jlso b/test/specimens/v3_julia_serialize_gzip_smallest.jlso new file mode 100644 index 0000000000000000000000000000000000000000..669c0c1e67d2366f676b8710cf661186729cbcc5 GIT binary patch literal 9771 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 "Hello World!", - "Vector" => [0.867244, 0.711437, 0.512452, 0.863122, 0.907903], - "Matrix" => [ + :String => "Hello World!", + :Vector => [0.867244, 0.711437, 0.512452, 0.863122, 0.907903], + :Matrix => [ 0.400348 0.892196 0.848164; 0.0183529 0.755449 0.397538; 0.870458 0.0441878 0.170899 ], - "DateTime" => DateTime(2018, 1, 28), - "ZonedDateTime" => ZonedDateTime(2018, 1, 28, tz"America/Chicago"), - "DataFrame" => DataFrame( + :DateTime => DateTime(2018, 1, 28), + :ZonedDateTime => ZonedDateTime(2018, 1, 28, tz"America/Chicago"), + :DataFrame => DataFrame( :a => collect(1:5), :b => [0.867244, 0.711437, 0.512452, 0.863122, 0.907903], :c => ["a", "b", "c", "d", "e"], :d => [true, true, false, false, true], ), - "Distribution" => Normal(50.2, 4.3), + :Distribution => Normal(50.2, 4.3), ) #== From 2c691f43e354a1fa4153c621e40b118754b7c03b Mon Sep 17 00:00:00 2001 From: rofinn Date: Tue, 19 Nov 2019 14:24:31 -0600 Subject: [PATCH 2/3] Revert just the breaking change to JSON.load with a comment in the docstring. --- src/file_io.jl | 10 ++++++---- test/backwards_compat.jl | 2 +- test/file_io.jl | 2 +- test/test_data_setup.jl | 2 ++ 4 files changed, 10 insertions(+), 6 deletions(-) diff --git a/src/file_io.jl b/src/file_io.jl index 6f2e044..180bdd3 100644 --- a/src/file_io.jl +++ b/src/file_io.jl @@ -76,21 +76,23 @@ save(io::IO, data::Pair...; kwargs...) = save(io, Dict(data...); kwargs...) save(path::String, args...; kwargs...) = open(io -> save(io, args...; kwargs...), path, "w") """ - load(io, objects...) -> Dict{Symbol, Any} - load(path, objects...) -> Dict{Symbol, Any} + load(io, objects...) -> Dict{String, Any} + load(path, objects...) -> Dict{String, Any} Load the JLSOFile from the io and deserialize the specified objects. If no object names are specified then all objects in the file are returned. + +Warning: This method will return `Dict{Symbol, Any}` in the next major release. """ load(path::String, args...) = open(io -> load(io, args...), path) function load(io::IO, objects::String...) jlso = read(io, JLSOFile) objects = isempty(objects) ? names(jlso) : objects - result = Dict{Symbol, Any}() + result = Dict{String, Any}() for o in objects # Note that calling getindex on the jlso triggers the deserialization of the object - result[o] = jlso[o] + result[String(o)] = jlso[o] end return result diff --git a/test/backwards_compat.jl b/test/backwards_compat.jl index 5ffed31..79bbd78 100644 --- a/test/backwards_compat.jl +++ b/test/backwards_compat.jl @@ -59,6 +59,6 @@ end dir = joinpath(@__DIR__, "specimens") @testset "$fn" for fn in readdir(dir) jlso_data = @suppress_out JLSO.load(joinpath(dir, fn)) - @test jlso_data == datas + @test jlso_data == load_datas end end diff --git a/test/file_io.jl b/test/file_io.jl index 192b78d..fae081f 100644 --- a/test/file_io.jl +++ b/test/file_io.jl @@ -148,7 +148,7 @@ end @testset "$fmt - $k" for fmt in (:bson, :julia_serialize), (k, v) in datas JLSO.save("$path/$fmt-$k.jlso", k => v; format=fmt) result = JLSO.load("$path/$fmt-$k.jlso") - @test result[k] == v + @test result[String(k)] == v end end end diff --git a/test/test_data_setup.jl b/test/test_data_setup.jl index 5a53d77..f1f21c1 100644 --- a/test/test_data_setup.jl +++ b/test/test_data_setup.jl @@ -27,6 +27,8 @@ const datas = Dict( :Distribution => Normal(50.2, 4.3), ) +const load_datas = Dict(String(k) => v for (k, v) in datas) + #== for format in (:bson, :julia_serialize) for compression in (:none, :gzip, :gzip_fastest, :gzip_smallest) From e8e02c056a82b74122d6e57c36ca5624e61fd242 Mon Sep 17 00:00:00 2001 From: rofinn Date: Tue, 19 Nov 2019 14:28:15 -0600 Subject: [PATCH 3/3] Another revert, but fix just the specific breaking change. --- Project.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Project.toml b/Project.toml index 6c37e90..932994d 100644 --- a/Project.toml +++ b/Project.toml @@ -2,7 +2,7 @@ name = "JLSO" uuid = "9da8a3cd-07a3-59c0-a743-3fdc52c30d11" license = "MIT" authors = ["Invenia Technical Computing Corperation"] -version = "1.2.0" +version = "1.2.2" [deps] BSON = "fbb218c0-5317-5bc6-957e-2ee96dd4b1f0"