Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Duplicate keys in mapping #140

Open
sstroemer opened this issue May 28, 2024 · 1 comment · May be fixed by #141
Open

Duplicate keys in mapping #140

sstroemer opened this issue May 28, 2024 · 1 comment · May be fixed by #141

Comments

@sstroemer
Copy link

sstroemer commented May 28, 2024

As of the YAML specs, keys of mappings need to be unique: "The content of a mapping node is an unordered set of key/value node pairs, with the restriction that each of the keys is unique."

This is not accounted for, which leads to duplicate entries silently being overwritten:

YAML.load("x: 3")         # Dict{Any, Any} with 1 entry: "x" => 3
YAML.load("x: 3\nx: 4")   # Dict{Any, Any} with 1 entry: "x" => 4     (<-- this is wrong)

A bandaid fix (if anyone stumbles on this) would be:

@kwdef struct UniqueKeyDict{T1, T2} <: AbstractDict{T1, T2}
    dict::Dict{T1, T2} = Dict{T1, T2}()
end

function Base.setindex!(ukd::UniqueKeyDict, value, key)
    haskey(ukd.dict, key) && error("Key $key already exists in dictionary.")
    ukd.dict[key] = value
end

YAML.load("x: 3")                                               # Dict{Any, Any} with 1 entry: "x" => 3
YAML.load("x: 3\nx: 4")                                         # Dict{Any, Any} with 1 entry: "x" => 4
YAML.load("x: 3"; dicttype=UniqueKeyDict{Any, Any}).dict        # Dict{Any, Any} with 1 entry: "x" => 3
YAML.load("x: 3\nx: 4"; dicttype=UniqueKeyDict{Any, Any}).dict  # throws an error

Note that the internal dict field can then be used for further processing. Similar workarounds are of course valid for OrderedDict or similar types.

@sstroemer sstroemer linked a pull request May 28, 2024 that will close this issue
@kescobo
Copy link
Collaborator

kescobo commented May 29, 2024

Using insert! from Dictionaries.jl is how I would do it (though to be clear, I'm not advocating adding that dependency)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants