elixir icon indicating copy to clipboard operation
elixir copied to clipboard

Keyword.validate/2 has unpredictable behavior when accepted keys have duplicate entries

Open polvalente opened this issue 5 months ago • 1 comments

Elixir and Erlang/OTP versions

Erlang/OTP 27 [erts-15.2.1] [source] [64-bit] [smp:10:10] [ds:10:10:10] [async-threads:1] [jit]

Elixir 1.18.2 (compiled with Erlang/OTP 27)

Operating system

macOS

Current behavior

iex(1)> Keyword.validate!([a: 3, b: 2], [:a, :b, a: 1])
[a: 1, b: 2, a: 3]
iex(2)> Keyword.validate!([b: 2, a: 3], [:a, :b, a: 1])
[a: 3, b: 2]
iex(3)> v(1)[:a]
1
iex(4)> v(2)[:a]
3

In the example above, :a is given twice as an expected key, one with no default and another with default = 1. Depending on the order of the values passed in the first argument, it will assume the default instead of the passed value.

Expected behavior

Ideally, we should be erroring out when duplicate values are passed as accepted keys, because we don't accept duplicates in the first argument as well.

I can send a PR either way, just let me know the preferred solution!

polvalente avatar Jun 17 '25 15:06 polvalente

This is tricky because checking for duplicates will make it more expensive, potentially enough to show up on hot code paths. So it will depend if we can have a reasonably efficient implementation. Please do send a PR giving it a try!

josevalim avatar Jun 17 '25 15:06 josevalim

Closing in favor of the PR, even though we are not sure we can efficiently verify this, it depends on the implementation details.

josevalim avatar Jul 10 '25 15:07 josevalim