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 167ca59
Show file tree
Hide file tree
Showing 3 changed files with 19 additions and 11 deletions.
7 changes: 3 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,13 @@ function isequal(l::AbstractDict, r::AbstractDict)
end

function ==(l::AbstractDict, r::AbstractDict)
l === r && return true
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
15 changes: 12 additions & 3 deletions test/dict.jl
Original file line number Diff line number Diff line change
Expand Up @@ -277,6 +277,13 @@ 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)
d = Dict(1=>[missing])
@test ismissing(d == d)
d = Dict(1=>NaN)
@test d != d
@test isequal(d, d)

@test Dict(missing=>1) == Dict(missing=>1)
@test isequal(Dict(missing=>1), Dict(missing=>1))
Expand Down Expand Up @@ -425,7 +432,7 @@ mutable struct T10647{T}; x::T; end
a[1] = a
a[a] = 2
a[3] = T10647(a)
@test a == a
@test isequal(a, a)
show(IOBuffer(), a)
Base.show(Base.IOContext(IOBuffer(), :limit => true), a)
Base.show(IOBuffer(), a)
Expand All @@ -449,7 +456,7 @@ end

ca = copy(a)
@test length(ca) == length(a)
@test ca == a
@test isequal(ca, a)
@test ca !== a # make sure they are different objects

ca = empty!(ca)
Expand Down Expand Up @@ -490,7 +497,7 @@ end

ca = copy(a)
@test length(ca) == length(a)
@test ca == a
@test isequal(ca, a)
@test ca !== a # make sure they are different objects

ca = empty!(ca)
Expand Down Expand Up @@ -716,6 +723,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 167ca59

Please sign in to comment.