Highlights of Python 3.12: Improved Error Messages, Expanded f‑string Capabilities, and Type Annotation Enhancements
Python 3.12 introduces enhanced error messages for NameError, SyntaxError, and ImportError, expands f‑string capabilities with unrestricted expressions and deeper nesting, adds inline collection optimizations, and brings numerous type‑annotation improvements such as TypedDict unpacking, the override decorator, and new parameter‑type syntax.
Python 3.12 has been officially released, bringing a series of language‑level improvements that affect error reporting, string formatting, runtime optimizations, and static typing.
Improved error messages
Standard‑library modules now provide more informative NameError messages, suggesting possible causes such as missing imports or undefined variables. For example:
<code>>> sys.version_info
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'sys' is not defined. Did you forget to import 'sys'?</code>When a NameError occurs inside a method, the interpreter can also hint at missing self references:
<code>>> class A:
... def __init__(self):
... self.blech = 1
... def foo(self):
... somethin = blech
>>> A().foo()
Traceback (most recent call last):
File "<stdin>", line 1
somethin = blech
^^^^^
NameError: name 'blech' is not defined. Did you mean: 'self.blech'?</code>Incorrect ordering of import and from now yields a helpful SyntaxError suggestion, and ImportError points to the correct object name:
<code>>> import a.y.z from b.y.z
SyntaxError: Did you mean to use 'from ... import ...' instead?
>>> from collections import chainmap
ImportError: cannot import name 'chainmap' from 'collections'. Did you mean: 'ChainMap'?</code>New features
PEP 701 – f‑string semantic formatting
f‑strings now accept any valid Python expression, including backslashes, Unicode escapes, multiline expressions, comments, and repeated quote styles. Example of repeated quotes:
<code>>> songs = ['Take me back to Eden', 'Alkaline', 'Ascensionism']
>>> f"This is the playlist: {', '.join(songs)}"
'This is the playlist: Take me back to Eden, Alkaline, Ascensionism'</code>Nested f‑strings are no longer limited to four levels:
<code>>> f"""{f'''{f"{f"{f"{f"{1+1}"}"}"}"}"""
'2'</code>Multiline expressions and comments are now allowed inside f‑strings, improving readability:
<code>>> 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
... ])}"
'This is the playlist: Take me back to Eden, Alkaline, Ascensionism'</code>Backslashes and Unicode escapes can be used as well:
<code>>> print(f"This is the playlist: {'\n'.join(songs)}")
This is the playlist: Take me back to Eden
Alkaline
Ascensionism
>>> print(f"This is the playlist: {'\N{BLACK HEART SUIT}'.join(songs)}")
This is the playlist: Take me back to Eden♥Alkaline♥Ascensionism</code>More precise error locations are now reported for syntax errors, e.g.:
<code>>> my_string = f"{x z y}" + f"{1 + 1}"
File "<stdin>", line 1
(x z y)
^^^
SyntaxError: f-string: invalid syntax. Perhaps you forgot a comma?</code>PEP 709 – Inline collection behavior
The interpreter now treats dictionaries, lists, and sets as inline objects, allowing the VM to optimize them and potentially double execution speed; iterators are excluded.
PEP 688 – Buffer protocol exposure
Classes can implement __buffer__() to expose a buffer interface, and the new abstract base class collections.abc.Buffer standardizes this usage. The inspect.BufferFlags enum provides flag definitions for custom buffers.
PEP 692 – TypedDict for **kwargs
TypedDict can now be unpacked into **kwargs for more precise typing:
<code>from typing import TypedDict, Unpack
class Movie(TypedDict):
name: str
year: int
def foo(**kwargs: Unpack[Movie]):
...</code>PEP 698 – typing.override decorator
The new typing.override() decorator marks methods that must override a parent class method, enabling static type checkers to verify correctness.
<code>from typing import override
class Base:
def get_color(self) -> str:
return "blue"
class GoodChild(Base):
@override
def get_color(self) -> str:
return "yellow"
class BadChild(Base):
@override
def get_colour(self) -> str: # type‑checker error: does not override Base.get_color
return "red"</code>PEP 695 – Parameter‑type syntax
PEP 695 introduces a concise syntax for generic type parameters, simplifying annotations such as:
<code>def max[T](args: Iterable[T]) -> T:
...
class list[T]:
def __getitem__(self, index: int, /) -> T:
...
def append(self, element: T) -> None:
...</code>It also adds a new type keyword for creating TypeAliasType instances, e.g.:
<code>type Point = tuple[float, float]
type Point[T] = tuple[T, T]
type IntFunc[**P] = Callable[P, int] # ParamSpec
type LabeledTuple[*Ts] = tuple[str, *Ts] # TypeVarTuple</code>Other language changes (partial)
Environment variable PYTHONPERFSUPPORT , command‑line flag -X perf , and new sys.activate_stack_trampoline() APIs for Linux perf profiling.
MappingProxyType becomes hashable when the underlying dict is hashable.
The parser can now handle empty byte strings.
Garbage collection runs only at bytecode pause points and during PyErr_CheckSignals() , reducing GC interference with C extensions.
The walrus operator (:=) can be used inside comprehensions for assignment.
Slice objects are now hashable and can serve as dictionary keys.
sum() uses a more accurate algorithm.
Summary
Python 3.12 focuses heavily on type‑annotation enhancements and runtime efficiency. Improved error messages, richer f‑string semantics, inline collection optimizations, and a suite of new PEPs (701, 709, 688, 692, 698, 695) collectively make the language more expressive and performant, addressing long‑standing criticisms about dynamic typing and garbage‑collector overhead.
Python Programming Learning Circle
A global community of Chinese Python developers offering technical articles, columns, original video tutorials, and problem sets. Topics include web full‑stack development, web scraping, data analysis, natural language processing, image processing, machine learning, automated testing, DevOps automation, and big data.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.