I was working on a new project which was based on dictionaries and recognized some weird(?) things about syntax errors which pop out when you do not separate the key:value pairs with commas.
I have created an example to ask my question better:
# Dummy Keys
key = "Jules"
key2 = "Potato"
key3 = "Doctor"
key4 = "Computer"
key5 = "Chair"
key6 = "Answers"
no_comma_dict1 = {
key: {
key2: "Please put a comma here->" # syntax err: perhaps you forgot a comma
key3: "Ok."
},
key4: {
key5: "Is this what you were expecting ->",
key6: "Yes, exactly."
}
}
In the code block above, I have a dict of two sub-dicts. I havenât put a comma between the key-value pairs in the first sub-dict and got a syntax error about commas as expected.
no_comma_dict2 = {
key: {
key2: "Here is a comma ->",
key3: "That's right."
},
key4: { #syntax err: expression expected after dictionary key and ':' --- why not the same ^ error?
key5: "Huh"
key6: "No commas!"
}
}
Here, I have done the same thing inside the second sub-dict and the error I got wasnât about commas. Can someone please help me with understanding this - am I missing something? Or, is it a âbugâ? If yes, is it possible to make an improvement?
Thanks in advance.
I see what youâre driving at. Sorry Iâm no help here as my IDE (Wing) simply complains about âbad Syntaxâ and then leaves me to sort out where I messed up.
I kinda think that what youâre pumping into is a case of âyou canât please all of the people, all of the timeâ. The system is trying to be as helpful as it can be, given what it âknowsâ.
Iâm doing some guess work, but I think this can explain the reason for the different error messages.
These error messages are defined in the python grammar file
The one about comma is actually the less general one, that just happened to be more helpful for in this case (I guess). It is raised for any invalid expression, whether it makes sense to have comma there or not.
The other one about dict key and value is raised in the second case, because it knows that youâre defining a dict there, maybe because it parsed the other key: value already. In the first case, the error happens while it was parsing the first value, so it doesnât know that you are defining a key: value pair for a dict.
If you want improved error messages with Python 3.6+, you might want to use friendly/friendly-traceback. In both cases shown by OP, friendly highlights correctly the location of the error and makes the correct suggestion of adding a comma where it is missing.
To be fair, itâs seldom that I get into a situation where I canât figure out what said syntax error Iâve created. If I do, then I think to myself âRob, you can make that code way simpler!â
I didnât mean such a âdeepâ reason. Just a reason about my example code(to check if i have missed some points). But, really thank you for sharing your thoughts and the related piece of the src code with us.
( also thank you, @rob42; for wasting your time with this :).
It seems, there is no more need to discuss on this topic. It is just a field which needs improvement. I am not sure if it is important enough to create an (âenchancementâ) issue on GH, but I decided not to.
The interesting thing here, actually, isnât so much the form of the error, but where it occurs. If you enter the second example interactively in the Python 3.10 REPL, hereâs the error message thatâs spit out:
Itâs decided the syntax error is with the key4 expression, in this case; nothing to do with key5 or key6 at all, itâs backtracked even farther than before, in flagging the error location.
Same thing if you enter it all on one line (canât decide whether that makes it better or worse):
>>> no_comma_dict2 = { key: { key2: "Here is a comma ->", key3: "That's right." }, key4: { key5: "Huh" key6: "No commas" } }
File "<stdin>", line 1
no_comma_dict2 = { key: { key2: "Here is a comma ->", key3: "That's right." }, key4: { key5: "Huh" key6: "No commas" } }
^
SyntaxError: expression expected after dictionary key and ':'
Ultimately I think it just comes down to âthe parser is complex and inscrutableâ. Pretty much all error messages are at least improved over earlier Python releases⊠even if different positions on the parse tree are still treated differently at times.
Hi, Iâm one of the core devs in charge of the Python "complex and inscrutableâ parser . This problem has been already fixed in Python 3.10.6 in this commit:
This is what you get in 3.10.6+:
File "/Users/pgalindo3/github/python/main/lel.py", line 1
x = { key: { key2: "dsfsdf", key3: "dsfsdf" }, key3: { key5: "dsfsdf" key6: "dsfsdf" }}
^^^^^^^^^^^^^
SyntaxError: invalid syntax. Perhaps you forgot a comma?
this is one of the reasons you should always use the latest bug fix version
Interesting. My guess is that, in that case, the parser isnât sure whether youâre attempting to write a set or a dict, or possibly a set/dict comprehension, and itâs really hard to provide useful messages when thereâs that many possibilities. Once youâve established that itâs definitely a dict, there are fewer possibilities (you might have {key: value for...} or {key:value, key: value} but thatâs all), so itâs easier to try to guess at a probable solution.