<#19486 Fail on duplicate keys in the override dic...
# github-notifications
c
#19486 Fail on duplicate keys in the override dictionary of a BUILD target Issue created by AlexTereshenkov Is your feature request related to a problem? Please describe. Pants should check if there are duplicates in the dictionary provided in the
overrides
field of a target in a BUILD file. This is because the later key would override whatever was set before, very likely this is undesired.
Copy code
python_sources(
    name="lib",
    overrides={
        "main.py": {"dependencies": ["//:reqs#pytest"]},
        },
)
yields
Copy code
$ pants dependencies helloworld/main.py          
//:reqs#ansicolors
//:reqs#pytest
helloworld/greet/greeting.py:lib
helloworld/main.py:lib
and
Copy code
python_sources(
    name="lib",
    overrides={
        "main.py": {"dependencies": ["//:reqs#pytest"]},
        "main.py": {"dependencies": []},
        },

)
yields
Copy code
$ pants dependencies helloworld/main.py
//:reqs#ansicolors
helloworld/greet/greeting.py:lib
helloworld/main.py:lib
Describe the solution you'd like I believe a user would never want to have a second key in the dictionary of the
overrides
field and we should fail if we find one. Describe alternatives you've considered Pants already fails when a field in the target declaration is passed twice which is helpful:
Copy code
pants dependencies helloworld/main.py
11:16:53.00 [ERROR] 1 Exception encountered:

Engine traceback:
  in `dependencies` goal
  in Find targets from input specs

MappingError: Failed to parse ./helloworld/BUILD:
SyntaxError: keyword argument repeated: name (<string>, line 5)
We should have something similar but for the
overrides
field as well. This may be not trivial as the dictionary is evaluated when loaded into Python so by nature there are no duplicate keys in the dictionary once it's loaded. I wonder whether we'll have to construct an AST and inspect the keys. Additional context One can currently use custom tooling to query the overrides, e.g. Given
Copy code
python_sources(
    name="lib",
    overrides={
        "main.py": {"dependencies": ["//:reqs#pytest"]},
        "main.py": {"dependencies": []},
        },
)
one can do
Copy code
$ echo $(~/Applications/buildozer-linux-amd64 -stdout 'print name overrides' -:%python_sources < helloworld/BUILD) | grep -o '{.*' > overrides.json

$ cat overrides.json     
{ "main.py": {"dependencies": ["//:reqs#pytest"]}, "main.py": {"dependencies": []}, }

# now in Python
from pprint import pprint
import ast

with open("overrides.json") as fh:
    data = ast.parse(fh.read())

pprint(ast.dump(data))
("Module(body=[Expr(value=Dict(keys=[Constant(value='main.py'), "
 "Constant(value='main.py')], "
 "values=[Dict(keys=[Constant(value='dependencies')], "
 "values=[List(elts=[Constant(value='//:reqs#pytest')], ctx=Load())]), "
 "Dict(keys=[Constant(value='dependencies')], values=[List(elts=[], "
 'ctx=Load())])]))], type_ignores=[])')

for i in data.body[0].value.keys:
    print(i.value)    
    
main.py
main.py
however, it may be very expensive to construct AST for every
overrides
field. pantsbuild/pants