Skip to content

Commit

Permalink
fix dict x == x to return missing if x contains it
Browse files Browse the repository at this point in the history
closes #34744

use `isequal` to compare keys in `ImmutableDict`
  • Loading branch information
JeffBezanson committed Feb 19, 2020
1 parent b0d1c1a commit 1c8f885
Show file tree
Hide file tree
Showing 3 changed files with 14 additions and 8 deletions.
10 changes: 6 additions & 4 deletions base/abstractdict.jl
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,9 @@ const secret_table_token = :__c782dbf1cf4d6a2e5e3865d7e95634f2e09b5902__
haskey(d::AbstractDict, k) = in(k, keys(d))

function in(p::Pair, a::AbstractDict, valcmp=(==))
v = get(a,p[1],secret_table_token)
v = get(a, p.first, secret_table_token)
if v !== secret_table_token
return valcmp(v, p[2])
return valcmp(v, p.second)
end
return false
end
Expand Down Expand Up @@ -474,14 +474,16 @@ function isequal(l::AbstractDict, r::AbstractDict)
end

function ==(l::AbstractDict, r::AbstractDict)
l === r && return true
if l === r
return any(ismissing, values(l)) ? missing : true
end
if isa(l,IdDict) != isa(r,IdDict)
return false
end
length(l) != length(r) && return false
anymissing = false
for pair in l
isin = in(pair, r, ==)
isin = in(pair, r)
if ismissing(isin)
anymissing = true
elseif !isin
Expand Down
8 changes: 4 additions & 4 deletions base/dict.jl
Original file line number Diff line number Diff line change
Expand Up @@ -746,7 +746,7 @@ ImmutableDict(KV::Pair, rest::Pair...) = ImmutableDict(ImmutableDict(rest...), K
function in(key_value::Pair, dict::ImmutableDict, valcmp=(==))
key, value = key_value
while isdefined(dict, :parent)
if dict.key == key
if isequal(dict.key, key)
valcmp(value, dict.value) && return true
end
dict = dict.parent
Expand All @@ -756,22 +756,22 @@ end

function haskey(dict::ImmutableDict, key)
while isdefined(dict, :parent)
dict.key == key && return true
isequal(dict.key, key) && return true
dict = dict.parent
end
return false
end

function getindex(dict::ImmutableDict, key)
while isdefined(dict, :parent)
dict.key == key && return dict.value
isequal(dict.key, key) && return dict.value
dict = dict.parent
end
throw(KeyError(key))
end
function get(dict::ImmutableDict, key, default)
while isdefined(dict, :parent)
dict.key == key && return dict.value
isequal(dict.key, key) && return dict.value
dict = dict.parent
end
return default
Expand Down
4 changes: 4 additions & 0 deletions test/dict.jl
Original file line number Diff line number Diff line change
Expand Up @@ -277,6 +277,8 @@ end

@test ismissing(Dict(1=>missing) == Dict(1=>missing))
@test isequal(Dict(1=>missing), Dict(1=>missing))
d = Dict(1=>missing)
@test ismissing(d == d)

@test Dict(missing=>1) == Dict(missing=>1)
@test isequal(Dict(missing=>1), Dict(missing=>1))
Expand Down Expand Up @@ -716,6 +718,8 @@ import Base.ImmutableDict
d5 = ImmutableDict(v...)
@test d5 == d2
@test collect(d5) == v

@test !haskey(ImmutableDict(-0.0=>1), 0.0)
end

@testset "filtering" begin
Expand Down

0 comments on commit 1c8f885

Please sign in to comment.