Python 3.10

Table of Contents

Python 3.10 is here

Python 3.10 is now released. It has a few features worth talking about. Some of these features never existed before in Python (surprisingly!)

Structural Mattern Matching

In the traditional programming languages, this is usually referred to as the switch ...case statements. Although syntactically it looks like a switch ... case statement, it is a lot more than that.

It allows you to detect and deconstruct different structures the data is defined as, and lets you use patterns of your definition. Standard pattern matching is very literal and let’s you define explicitly. All in all, it adds good power to the language

Relevant Documents:

Now let’s take a look at Python Type checking using this structure. Normally, Type checking is not needed in Python, but for traditional language folks, this is a useful feature.

match value:
    case str():  # Handle strings first for performance reasons.
        return value
    case bool():  # Make sure booleans don't get treated as numbers
        return str(value)
    case decimal.Decimal() | float() | int():
        if use_l10n is False:
            return str(value)
        return number_format(value, use_l10n=use_l10n)
    case datetime.datetime():
        return date_format(value, 'DATETIME_FORMAT', use_l10n=use_l10n)
    case datetime.date():
        return date_format(value, use_l10n=use_l10n)
    case datetime.time():
        return time_format(value, 'TIME_FORMAT', use_l10n=use_l10n)
    case _:
        return value

Better Error Messages

Much of this Documentation describes the precision of the error messages. There are a lot of cases when debugging a large code base , one encounters errors that makes you wonder and guess the reasons behind the error messages. The classic language confusion of the message Syntax Error is one of them .

Here is one example of a small variable definition error. A simple commonly occurring error but the messages are a lot more explicit.


CountProjectOwners = 5
print(CountProject)
> NameError: name 'CountProject' is not defined. Did you mean: CountProjectOwners ?

Now let’s look at one common scenatio of forgetting to write “:”

if age > 21
    print("Age is greater than 21")

Now let’s run this code in 3.10 and see

% python3.10 age.py
if age > 21    
         ^
SyntaxError: expected ':'

Parenthesized Context Managers

With this feature, it allows multiple I/O streams statements to be combined in a single statement of with. e.g.

Say , for example, we had a line like …

with open('foo1.txt', 'r') as fooin, open('foo2.txt', 'w') as fooout:
    foout.write(fooin.read())

If this line is too long, we can split it using the traditional approach of using backslash \ e.g.

with open('foo1.txt', 'r') as fooin, \
     open('foo2.txt', 'w') as fooout:
    fooout.write(fooin.read())

With this new feature, the line can be split across multiple lines and kept within a pair of parentheses. e.g.

with (open('foo1.txt', 'r') as fooin,
      open('foo2.txt', 'w') as fooout):
    fooout.write(fooin.read())

Simple, but makes the code readable and clean.

Type Unions

There are a lot of cases where the data types itself are not precisely known but the function can complete execution within certain boundaries. e.g.

def f(x: int | float) -> float:    return x * 3.142f(1)  

this function will execute for both int and float as arguments, but will fail for str


f(3) # pass
f(5.5) # pass
f("hello")  # fail