Python 3.12 is Here!

It's October 2023 and Python 3.12 has landed. We look at the most significant new features available to Python programmers.

Bcorp Logo

Python 3.12 is Here

Autumn has started to take hold in the UK and it's not just the leaves that have started to fall...Python 3.12 has just dropped this week too! 

The last major release, Python 3.11 has been around nearly a year and there have been several minor updates along the way.

Python 3.12 contains several new language features such as improves to formatted strings, one Global Interpreter Lock (GIL) per sub-interpreter, an override decorator and improved performance. 

Let's take a look at some of the most significant new features...

Python Performance

Python 3.12 is a significant update / release for all Python developers thanks to the promise of tangible speed improvements. Now I know you may have heard this before...when Python 3.11 came out, one of the big claims was for a faster Python, and yes that claim is being repeated here again; but those claims are related. The performance optimisations are part of an ongoing project aimed at tuning the Python runtime and this work continues into 3.12.

Python 3.12 builds upon 3.11's bytecode conversion improvements (such as identifying frequently executed and specialized blocks of code). This streamlining of the Python interpreter means applications can potentially start up and run faster.

Lower Memory Management Overhead

Improvements made to the way that objects are stored in memory reduces the memory overhead associated with new instances, this will reduce the memory utilization of a program and thus require fewer and less frequent garbage collection operations.

Per Interpreter Global Interpreter Lock (GIL)

This change in Python may not seem that exciting but it has a fundamental impact on all multi-threaded applications (for more information see PEP 684).

In previous versions of Python, the GIL was a global lock within the underlying CPython interpreter that was designed to avoid potential deadlocks between multiple tasks. It was designed to protect access to Python objects by preventing multiple threads from executing at the same time.

This approach prevents multithreaded Python programs from taking full advantage of multiprocessor systems in certain situations.

This is because in order to execute, a thread must obtain the GIL and only one thread at a time could hold the GIL (that is the lock it represents). This means that Python acted like a single CPU machine; only one thing could run at a time. A Thread would only give up the GIL if it slept, had to wait for something (such as some I/O) or it had held the GIL for a certain amount of time. It was thus impossible for standard Python threads to take advantage of the multiple CPUs typically available on modern computer hardware.

This has changed in Python 3.12. PEP 684: A Per-Interpreter GIL introduces a separate GIL for each sub-interpreter, this allows a program to take advantage of multiple CPU cores on a machine. Unfortunately, this feature is only available through he C-API provided with Python but a Python API is anticipated for Python 3.13.

Improvements to f-strings

Python 3.12 is Here

F-strings or formatted strings allow expressions to be embedded within a string template, for example:

age = 10
message = f'Hi you are {age} years old'

In the above the string saved into the variable message is a f-string template with the value inside the curly brackets replacing that expression in the string generated, the output would therefore be:

Hi you are 10 years old

PEP 701 Syntactic formalization of f-strings lifts some of the restrictions on the usage if f-strings. Expression components within the curly brackets within the f-string can now be any valid Python expressions including strings that reuse the ame quotes as the containing f-string, multi-line expressions, comments, backslashes and Unicode escape sequences.For example, you can now write:

msg = f"This is the playlist: {", ".join([
     'Take me back to Eden',  # My, my, those eyes like fire
     'Alkaline',              # Not acid nor alkaline
     'Ascensionism'           # Take to the broken skies at last

which produces:

'This is the playlist: Take me back to Eden, Alkaline, Ascensionism'

Improved Error Messages

As with Python 3.11, an attempt has been made to improve the error messages generated by the Python runtime. For example, Modules from the standard library are now potentially suggested as part of the error messages displayed by the interpreter when a NameError is raised to the top level.

Python 3.12 is Here

Type Hint Improvements

Improvements have also been suggested to the type hint facilities available in Python 3.12. Type Hints allow typing information to be provided when functions and methods are defined. These type hints are extremely useful and can help a developer understand what types are expected by a function or a method and indeed what types are likely to be returned. Recent versions of Python, including 3.10 and 3.11 have increased the support for Type Hints so that they are now quite usable. Python 3.12 continues this trend by adding additional support for **kwargs and a new override decorator for use with inheritance.

The new decorator typing.override() has been added to the typing module. It indicates to type checkers that the method is intended to override a method in a superclass. This allows type checkers to catch mistakes where a method that is intended to override something in a base class does not in fact do so.

For example:

from typing import override
class Base:
   def do_something(self):
class Child(Base):
   def do_something(self):
       print('something else')

In the above example, the class Base defines a method do_something() that will print out the message something. The class Child then extends Base and indicates that it is defining a method do_something() that should override the version define din the parent class. In this case the subclass method prints out something else. However, if the method was incorrectly named, such as dosomething() and we marked it as being overridden then the type hint checker would indicate an error.

Low Impact Monitoring

This new features defines a new API for profilers, debuggers and other monitoring style tools (see PEP 669). The advantage of this new API is that it provides support for near-zero overhead debuggers and monitoring tools.


These are the main new features in Python 3.12. Even if you are not interested in most of the new language features you should consider upgrading to Python 3.12 for the potential runtime performance benefits. Once you have done this you may find the new features worth exploring in more detail.

Would you like to know more?

We've got lots of great Python training courses to choose from:

Share this post on:

We would love to hear from you

Get in touch

or call us on 020 3137 3920

Get in touch