About Dictionary Based Syntax Errors~Python 3.10

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.

What coding IDE are you using?

With my IDE both blocks raise SyntaxError

dict1

  • key3: "Ok."

dict2

  • key6: "No commas!"

Thank you for your fast reply.
I also get errors in both situations. My main question was more about what syntax error I get.
In dict1, I get:

SyntaxError: perhaps you forgot a comma?

In dict2:

SyntaxError: expression expected after dictionary key and ':'

So, my question is:
Why do I not get the same error in the second dict ?

BTW, I am using IDLE :wink:

No worries.

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.

1 Like

I know this won’t help you but as an FYI:

With IDLE3.6.9 it simply flags the offending lines and pops up with “Syntax Error” with no kind of help message at all.

These new error messages were introduced in 3.10 I believe.
Older versions had very unhelpful SyntaxErrors like you see.

Thank you.

Yes, I did read somewhere about that very feature.

I’m kinda stuck on 3.6 until my OS provider gets to updating things (maybe it has and I need to be pro-active) or I distro-hop.

I did try to up-grade to 3.8, but that simply crashed my Window manager, so I had to ‘Time Shift’ back again.

Thank you both @saaketp and @rob42 for heading up. I have tried running it with 3.9 and yes, I didn’t get any specific errors.

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’.

@rob42, :joy:
You are definitely right, but mustn’t you at least try to “please all of the people”?

1 Like

:grinning: yes, you can try, but you gunna fail! It’s an impossible task!!

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.

1 Like

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.

2 Likes

Thank you; I’ll have a look at it.

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!”
:slightly_smiling_face:

1 Like

I didn’t mean such a “deep” reason. :slightly_smiling_face: 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:

>>> key = "Jules"
>>> key2 = "Potato"
>>> key3 = "Doctor"
>>> key4 = "Computer"
>>> key5 = "Chair"
>>> key6 = "Answers"
>>> no_comma_dict2 = {
...     key: {
...         key2: "Here is a comma ->",
...         key3: "That's right." 
...         },
...     key4: {
...         key5: "Huh"
...         key6: "No commas"
  File "<stdin>", line 6
    key4: {
        ^
SyntaxError: expression expected after dictionary key and ':'

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.

2 Likes

@sandraC @ferdnyc

:wave: Hi, I’m one of the core devs in charge of the Python "complex and inscrutable” parser :slight_smile: . 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 :wink:

3 Likes

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.

Yay! That’s good news, awesome.

In fairness, 3.10.6 didn’t even exist yet, when @sandraC originally posted this question back in May. It was still 3 months from being born.

But now that the fix has been committed, we can enjoy a more scrutable1 pyparser!

Notes

  1. (I’m not sure that’s really a word, but just roll with it.)
1 Like