Skip to content

Commit

Permalink
Rename binding has -> haskey (#694)
Browse files Browse the repository at this point in the history
* Remove exported has binding has and rename it to haskey

This was changed in an old Julia commit and renamed to haskey.

* Apply suggestions from code review

Co-authored-by: jmert <[email protected]>
  • Loading branch information
musm and jmert authored Oct 10, 2020
1 parent f01ad31 commit 229d335
Show file tree
Hide file tree
Showing 3 changed files with 95 additions and 25 deletions.
41 changes: 18 additions & 23 deletions src/HDF5.jl
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ export
g_create, g_open, get_access_properties, get_create_properties,
get_chunk, get_datasets,
h5open, h5read, h5rewrite, h5writeattr, h5readattr, h5write,
has, iscontiguous, ishdf5, ismmappable, name,
iscontiguous, ishdf5, ismmappable, name,
o_copy, o_delete, o_open, p_create,
readmmap, @read, @write, root, set_dims!, t_create, t_commit

Expand Down Expand Up @@ -653,7 +653,7 @@ function gettype(parent, path::String)
end
# Get the root group
root(h5file::File) = g_open(h5file, "/")
root(obj::Union{Group, Dataset}) = g_open(file(obj), "/")
root(obj::Union{Group,Dataset}) = g_open(file(obj), "/")
# getindex syntax: obj2 = obj1[path]
#getindex(parent::Union{HDF5File, HDF5Group}, path::String) = o_open(parent, path)
getindex(dset::Dataset, name::String) = a_open(dset, name)
Expand All @@ -675,17 +675,14 @@ function getindex(parent::Union{File,Group}, path::String; pv...)
end

# Path manipulation
function split1(path::String)
off = findfirst(isequal('/'),path)
if off === nothing
return path, nothing
function split1(path::AbstractString)
ind = findfirst('/', path)
isnothing(ind) && return path, nothing
if ind == 1 # matches root group
return "/", path[2:end]
else
if off == 1
# Matches the root group
return "/", path[2:end]
else
return path[1:prevind(path, off)], path[nextind(path, off):end]
end
indm1, indp1 = prevind(path, ind), nextind(path, ind)
return path[1:indm1], path[indp1:end] # better to use begin:indm1, but only available on v1.5
end
end

Expand Down Expand Up @@ -901,25 +898,23 @@ function setindex!(parent::Union{File,Group}, val, path::String; pv...)
end

# Check existence
function exists(parent::Union{File,Group}, path::String, lapl::Properties)
function Base.haskey(parent::Union{File,Group}, path::AbstractString, lapl::Properties=Properties())
first, rest = split1(path)
if first == "/"
parent = root(parent)
elseif !h5l_exists(parent.id, first, lapl.id)
return false
end
ret = true
if rest !== nothing && !isempty(rest)
exists = true
if !isnothing(rest) && !isempty(rest)
obj = parent[first]
ret = exists(obj, rest, lapl)
exists = haskey(obj, rest, lapl)
close(obj)
end
ret
return exists
end
exists(attr::Attributes, path::String) = h5a_exists(checkvalid(attr.parent).id, path)
exists(dset::Union{Dataset,Datatype}, path::String) = h5a_exists(checkvalid(dset).id, path)
exists(parent::Union{File,Group}, path::String) = exists(parent, path, Properties())
has(parent::Union{File,Group,Dataset}, path::String) = exists(parent, path)
Base.haskey(attr::Attributes, path::AbstractString) = h5a_exists(checkvalid(attr.parent).id, path)
Base.haskey(dset::Union{Dataset,Datatype}, path::AbstractString) = h5a_exists(checkvalid(dset).id, path)

# Querying items in the file
info(obj::Union{Group,File}) = h5g_get_info(checkvalid(obj).id)
Expand Down Expand Up @@ -1143,7 +1138,7 @@ end
# "Plain" (unformatted) reads. These work only for simple types: scalars, arrays, and strings
# See also "Reading arrays using getindex" below
# This infers the Julia type from the HDF5.Datatype. Specific file formats should provide their own read(dset).
const DatasetOrAttribute = Union{Dataset, Attribute}
const DatasetOrAttribute = Union{Dataset,Attribute}

function read(obj::DatasetOrAttribute)
dtype = datatype(obj)
Expand Down Expand Up @@ -1442,7 +1437,7 @@ for (privatesym, fsym, ptype, crsym) in
end
# Write to already-created objects
# Scalars
function write(obj::DatasetOrAttribute, x::Union{T, Array{T}}) where {T<:Union{ScalarType,String,Complex{<:ScalarType}}}
function write(obj::DatasetOrAttribute, x::Union{T,Array{T}}) where {T<:Union{ScalarType,String,Complex{<:ScalarType}}}
dtype = datatype(x)
try
writearray(obj, dtype.id, x)
Expand Down
4 changes: 4 additions & 0 deletions src/deprecated.jl
Original file line number Diff line number Diff line change
Expand Up @@ -220,3 +220,7 @@ end

### Changed in PR#695
@deprecate names(x::Union{Group,File,Attributes}) keys(x)

### Changed in PR#694
@deprecate has(parent::Union{File,Group,Dataset}, path::String) Base.haskey(parent, path)
@deprecate exists(parent::Union{File,Group,Dataset,Datatype,Attributes}, path::String) Base.haskey(parent, path) false
75 changes: 73 additions & 2 deletions test/plain.jl
Original file line number Diff line number Diff line change
Expand Up @@ -251,9 +251,9 @@ close(fr)

# Test object deletion
fr = h5open(fn, "r+")
@test exists(fr, "deleteme")
@test haskey(fr, "deleteme")
o_delete(fr, "deleteme")
@test !exists(fr, "deleteme")
@test !haskey(fr, "deleteme")
close(fr)

# Test the h5read interface
Expand Down Expand Up @@ -629,3 +629,74 @@ close(hfile)

rm(fn)
end # show tests

@testset "split1" begin

@test HDF5.split1("a") == ("a", nothing)
@test HDF5.split1("/a/b/c") == ("/", "a/b/c")
@test HDF5.split1("a/b/c") == ("a", "b/c")
@test HDF5.split1(GenericString("a")) == ("a", nothing)
@test HDF5.split1(GenericString("/a/b/c")) == ("/", "a/b/c")
@test HDF5.split1(GenericString("a/b/c")) == ("a", "b/c")

# The following two paths have the same graphemes but different code unit structures:
# the first one is
# <latin small letter a with circumflex> "/" <greek small leter alpha>
# while the second one is
# "a" <combining circumflex accent> "/" <greek small letter alpha>
circa = "â" # <latin small leter a with circumflex>
acomb = "" # "a" + <combining circumflex accent>
path1 = circa * ""
path2 = acomb * ""
# Sanity checks that the two strings are different but equivalent under normalization
@test path1 != path2
@test Base.Unicode.normalize(path1, :NFC) == Base.Unicode.normalize(path2, :NFC)
# Check split1 operates correctly
@test HDF5.split1(path1) == (circa, "α")
@test HDF5.split1(path2) == (acomb, "α")
@test HDF5.split1("/" * path1) == ("/", path1)
@test HDF5.split1("/" * path2) == ("/", path2)

end # split1 tests


@testset "haskey" begin
fn = tempname()
hfile = h5open(fn, "w")

group1 = g_create(hfile, "group1")
group2 = g_create(group1, "group2")

@test haskey(hfile, GenericString("group1"))
@test !haskey(hfile, GenericString("groupna"))
@test haskey(hfile, "group1/group2")
@test !haskey(hfile, "group1/groupna")

dset1 = d_create(hfile, "dset1", datatype(Int), dataspace((1,)))
dset2 = d_create(group1, "dset2", datatype(Int), dataspace((1,)))

@test haskey(hfile, "dset1")
@test !haskey(hfile, "dsetna")
@test haskey(hfile, "group1/dset2")
@test !haskey(hfile, "group1/dsetna")

meta1 = a_create(dset1, "meta1", datatype(Bool), dataspace((1,)))
@test haskey(dset1, "meta1")
@test !haskey(dset1, "metana")


attribs = attrs(hfile)
attribs["test1"] = true
attribs["test2"] = "foo"

haskey(attribs, "test1")
haskey(attribs, "test2")
!haskey(attribs, "testna")

attribs = attrs(dset2)
attribs["attr"] = "foo"
haskey(attribs, GenericString("attr"))

close(hfile)
rm(fn)
end # haskey tests

0 comments on commit 229d335

Please sign in to comment.