Better Error Messages

00:00 In the previous lesson, I gave you an overview of the course. In this lesson, I’ll be talking about the error message improvements introduced in Python 3.10.

00:10 Many different kinds of errors raised by the compiler have been improved. This includes better indication of where the error happened and better indication of what the error was and where on the line it took place.

00:24 In the top window, I’m going to show you Python 3.9, while in the bottom window, I’ll show you the new differences in 3.10. I’ll start out first with a bunch of errors with dictionaries and comprehensions.

00:41 Strictly speaking, this first one isn’t a comprehension, but it’s very similar. It’s an embedded generator. Statements like these must be wrapped in parentheses to be legal.

00:55 In Python 3.10, the same error gives a better indication of where the problem lies within the statement, highlighting the entire generator expression. This next one is an actual comprehension. To better understand the problem, let’s first look at some working code.

01:16 This is a dictionary instantiated using the standard library’s zip() function. Here, zip() is taking the first item from the first string and combining it with the first item of the second string and creating a tuple.

01:29 It does this for all the items in both strings, and then these tuples are turned into key-value pairs by the dictionary.

01:43 Here is the exact same thing, but using the dictionary comprehension instead. With me so far? Okay. Let’s cause a problem. Like with the embedded generator before, parentheses are required.

02:01 This error isn’t too helpful. It says the syntax is invalid but not why, and it points to the for keyword instead of the x, y part that actually caused the problem. Now let’s look at this in 3.10.

02:18 That’s much better, isn’t it? How about some easy to make dictionary mistakes?

02:34 Here, I’ve missed the comma after "February". And the 3.10 version.

02:48 3.10 is much more specific. Let’s do something else. This time, instead of the comma, I’ll miss the value altogether.

03:04 Another very generic message… which is far improved in 3.10! Consider this small program in the top window where the months dict is missing its closing brackets. Let me run this in 3.9.

03:31 Good old invalid syntax. And now in 3.10. You see not only what went wrong, but exactly which opening bracket was mismatched. Now let’s look at improvements around exception blocks. Once again, I’m back to Python 3.9 in the top window and 3.10 in the bottom.

03:56 Exception blocks can catch multiple exceptions through the use of parentheses. Let me show you a working example.

04:17 And now, here’s what happens if you forget the parentheses.

04:28 Let’s try that in 3.10.

04:37 In 3.10, there’s a highlight line showing you where the cause is and a nice clear message to go with the SyntaxError. What about if you forget your except clause that goes with the try block?

05:01 Your usual vagueness here. And in 3.10,

05:11 much improved. There are also improvements in other kinds of blocks as well. Missing colons go from invalid syntax to a specific indication of what you forgot.

05:34 A lot of programming languages allow value assignment inside of a condition block. This makes for a tricky-to-find bug. If you accidentally use a single equals (=) instead of a double (==), you assign the value and that returns True. Because this problem was so common, Python decided to disallow assignment in condition blocks.

05:54 Python eventually added the walrus operator (:=) to allow this, but it is still a special operator. Regular value assignment can’t happen in a condition clause.

06:03 Here’s an example of 3.9’s SyntaxError. And now the improvement in 3.10. There’s a nice little hint there to go with it. f-strings are one of my favorite Python features.

06:23 I can’t imagine going back to the days of %s or .format(). Although they are very powerful, there are still some restrictions within an f-string.

06:31 One of those restrictions is the use of the star operator (*). If you haven’t seen the star operator before, it’s used to expand a list in place. Let me start with a working example.

06:47 Consider this list containing the months from quarter one, and then another from quarter two. You can combine these into the first half of the year list by expanding them with the star operator.

07:06 That’s great, but you’re not allowed to do that in an f-string.

07:17 The improvement in 3.10 isn’t a lot, but it does explicitly make an indication of the problem. Not as drastic as some of the other improvements, but still useful.

07:36 Python’s use of whitespace for coding blocks is the favorite complaint of non-Pythonistas. However you feel about it, the error message when you forget to do it has at least improved. Here’s 3.9.

07:59 And a subtle improvement in 3.10 that indicates the block type that expected the indent. Some command line terminals now support suggestions when you make a typo. Now, Python’s REPL supports the same concept.

08:15 Note that underneath, this is all implemented in a method called PyErr_Display(), and not all REPLs use this method for error management. But for those that do, you get the new feature. Let me import collections.

08:31 And in 3.9, I’ll misspell namedtuple. Now I’m going to create a variable named fool, and then access foo instead. Let’s try these in 3.10.

08:53 Did I mean namedtuple? Well, yes indeed, I did. Fool me once, shame on you. Fool me twice, don’t be foo-ed again. That’s it for the errors. Next up, Python’s answer to switch.

Become a Member to join the conversation.