What is new in Python 3.11?
Python 3.11 is a significant release of the programming language, bringing with it a number of new features and improvements. It’s faster overall than Python 3.10 on most benchmarks, uses less memory, and starts up faster. It also has a number of new and refined features that improve the developer experience, such as exception groups, exception notes, and fine-grained error locations in tracebacks.
New features
Here’s a list of features that are introduced in Python 3.11:
Exception groups
Exception notes
The
tomlliblibraryVariadic generics
Marking TypedDict options
Self type
Arbitrary literal string type
Data class transforms
Exception groups
Exception groups are a new feature in Python 3.11 that allows us to group multiple exceptions and handle them collectively. This can be useful for a variety of reasons, such as:
To simplify error handling in complex code
To provide more context to users when errors occur
To handle multiple errors in a single handler
Exception notes
Exception notes are a way to document the different types of exceptions that a piece of code can raise. Other developers can use this information to understand the potential risks of using the code and write code that handles exceptions gracefully. Exception notes should be clear, concise, and informative. They should include the following information:
The name of the exception type
A description of the conditions under which the exception is raised
The recommended way to handle the exception
Some benefits of writing exception notes can be:
Helping other developers understand the potential risks of using our code
Helping developers write code that gracefully handles exceptions
Helping us debug our code
Helping make our code more robust and reliable
The tomllib library
In Python 3.10, there’s no built-in library to parse TOML files, and we need third-party libraries, such as tomli, to handle TOML files. However, we don’t need to do that anymore because Python 3.11 introduced the tomllib library that aids in parsing TOML files. We can load and read TOML data through the library but not write it. It’s based on the third-party tomli library.
Note: TOML, which stands for Tom’s Obvious, Minimal Language, is an easily readable configuration file format because of its simple syntax. It was created to address some shortcomings of other configuration file formats.
The two main functions of the tomllib library are:
load(): It loads data from.tomlfiles.loads(): It loads data fromstr.
Here’s an example of parsing TOML files in Python 3.11:
import tomllibwith open('t.toml') as Sample:toml_data = tomllib.loads(Sample.read())print(toml_data)
In the code above:
Line 1: We import the
tomlliblibrary.Lines 3–4: Using
with open(), the code readst.toml, loads the content using thetomlliblibrary, and assigns parsed data to the variabletoml_data.Line 6: The
print(toml_data)statement prints the parsed data.
Variadic generics
Python 3.11 introduces a new feature called variadic generics. Variadic generics allow us to pass a variable number of type arguments to a generic function or class.
For example, the following generic function takes a variable number of type arguments:
def my_function(*args: Type[Any]) -> None:for arg in args:print(arg)my_function(int, str, float)
Here’s the explanation:
Line 1: This line defines a function called
my_function()with a parameter*argsthat tells Python that the function can take a variable number of arguments. TheType[Any]type hint tells Python that the arguments to the function must be of typeAny. This means that the function can be called with any type of argument and themy_function()function doesn’treturna value.Lines 2–3: This line starts a
forloop that iterates over theargsparameter. For each argument, the function prints the argument to the console.Line 5: This line calls the
my_function()function with three arguments:int,str, andfloat.
Variadic generics can be very useful for writing generic code that can handle a variety of different types.
Marking TypedDict options
This feature allows us to mark certain options in a TypedDict as required or optional.
For example, the following TypeDict has two options: name and age:
my_type_dict: TypedDict = {"name": str,"age": Optional[int]}print(my_type_dict)
Here’s the explanation:
Line 1: This line declares a variable called
my_type_dictand assigns it to aTypedDictobject.Lines 2–3: The
TypedDictobject has two keys:nameandage. Thenamekey has the typestrand theagekey has the typeOptional[int]. This means that thenamekey must contain a string value and theagekey can contain an integer value or beNone.Line 5: This line prints the
my_type_dictto the console.
The Self type
The Self type in Python 3.11 is a new type annotation that allows us to specify the return type of a method as the same type as the class in which the method is defined. This can be useful for improving the type safety of our code and making it more readable.
Here’s an example:
class Person:def __init__(self, name: str) -> None:self.name = namedef greet(self: Self) -> Self:print(f"My name is {self.name}")return selfperson = Person("Alice")
Here’s the explanation:
Line 1: This line defines a class called
Person.Line 2: This line defines a constructor for the
Personclass. The constructor takes anameparameter of typestr.Line 3: This line assigns the value of the
nameparameter to theself.nameattribute.Line 5: This line defines a method called
greet(). Thegreet()method takes no parameters and returns an instance of thePersonclass by using theSelftype hint.Line 6: This line prints the message “My name is
name” to the console. Thenameis replaced by the value given in the method parameter.Line 7: This line returns an instance of the
Personclass.Line 9: This line creates a new instance of the
Personclass and assigns it to thepersonvariable and adds the value ofnameas the parameter.
Arbitrary literal string type
Arbitrary literal string type is a new feature in Python 3.11 that allows us to specify the type of a variable as any literal string value. This can be useful for ensuring that variables only contain valid string values, and for making our code more readable.
To use the arbitrary literal string type, we can use the LiteralString type hint. For example, the following code is valid:
my_variable: LiteralString = "Hello, world!"print(my_variable)
In the code above, the LiteralString type hint is used, which indicates that my_variable should have the exact value, "Hello, world!".
Data class transforms
In Python 3.11, we can use the dataclasses module to create data classes, which can simplify the creation of classes that primarily store data. These classes automatically generate special methods like __init__, __eq__, __ne__, and __repr__ based on the class attributes. The dataclass_transform decorator is used to mark a function, class, or metaclass as performing runtime “magic” that transforms a class, endowing it with dataclass-like behaviors.
Here’s an example of how to use dataclass–tranform in Python 3.11:
import typingfrom typing import Type, TypeVar, Anyimport dataclasses_T = TypeVar("_T")@typing.dataclass_transform()def create_model(cls: Type[_T]) -> Type[_T]:cls = dataclasses.dataclass(cls) # Automatically create __init__, __eq__, and __ne__ methodsreturn cls# The create_model decorator can now be used to create new model classes:@create_modelclass CustomerModel:id: intname: strc = CustomerModel(327, "Eric Idle")print(c)
Here’s the explanation:
Line 1–3: Import all the necessary modules.
Line 5: Define the type variable named
_T. This is used to represent any type.Line 7: Decorate the upcoming method with
typing.dataclass_transform(), which tells the type checker that thecreate_model()method performs dataclass-like transformations.Lines 8–10: Define the
create_model()method which takes a type object as input and returns a transformed object. It usesdataclasses.dataclass()decorator to automatically create the__init__,__eq__, and__ne__methods for the type object.Line 13: Decorate the
CustomerModelclass with thecreate_model()decorator.Lines 14–16: Define the
CustomerModelclass which has two variables:idandname.Line 18: Create an instance of the
CustomerModelclass namedcand assign values to the variable fields.Line 19: Print the values stored in
c.
Improved features
A lot of features and functions were improved and modified in Python 3.11. Some of them are as follows:
Faster CPython
Improvements in the
hashlibmoduleFine-grained error location in tracebacks
The
-Pcommand-line option
Faster CPython
Python 3.11 includes a number of optimizations that make the CPython interpreter faster. These optimizations include:
The new bytecode optimizer in Python 3.11 can generate more efficient code by performing a number of optimizations, including
,constant folding Replaces constant expressions with their evaluated values ,dead code elimination Removes the code that’s never executed , andcommon subexpression elimination Replaces multiple occurrences of the same subexpression with a single occurrence .loop optimization Moves invariant code out of loops and optimizes loop control structures The new garbage collector in Python 3.11 is more efficient and uses less memory by using a number of techniques, including
,generational garbage collection Divides objects into generations based on age and collects garbage from older generations more frequently , andreference counting Tracks the number of references to each object and garbage-collecting objects without any references .tricolor marking Tracks the reachability of objects and garbage-collecting objects that aren’t reachable from the root set of objects The new memory allocator in Python 3.11 is more efficient and reduces fragmentation by using a number of techniques, including
,bump pointer allocation Allocates memory from a contiguous memory region and moves the pointer to the next available memory block after each allocation , andfree list allocation Maintains a list of free memory blocks and allocates new blocks from the list .slab allocation Allocates memory in slabs of a fixed size
Improvements in the hashlib module
The following improvements have been made to hashlib modules in Python 3.11:
The
hashlib.blake2b()andhashlib.blake2s()functions now prefer thelibb2library over the vendored copy. It improves performance significantly, especially on systems with a recent version of OpenSSL installed.The
hashlibmodule now prefers optimized SHA-3 and SHAKE implementations from OpenSSL. This can also improve performance on systems with OpenSSL installed.A new
hashlib.file_digest()function has been added. This function allows us to efficiently compute the hash of a file or file-like object. Here‘s an example of how to use the method:
import hashlibdef get_file_hash(filename, digest="sha256"):with open(filename, "rb") as f:return hashlib.file_digest(f, digest).hexdigest()file_hash = get_file_hash("myfile.txt")print(file_hash)
Here’s the explanation of the code:
Line 1: Import the
hashlibmodule.Lines 3–5: Define a method
get_file_hash()with arguments:filenameanddigest. The defaultdigestalgorithm is set toSHA256.Line 7: Compute the hash of
myfile.txtusing theget_file_hash()method and save the results in thefile_hashvariable.Line 8: Print the hash of the file
Fine-grained error location in tracebacks
Python 3.11 introduced a new feature called fine-grained error location in tracebacks. This feature provides more detailed information about the location of errors in Python code.
For an example, run the following code:
def my_function(x):return x / 0my_function(1)
This output section shows the traceback that tells us that the error occurred on line 2 of the my_function() function in the main.py file.
The -P command-line option
The new -P command-line option and PYTHONSAFEPATH environment variable in Python 3.11 allow us to disable the automatic prepending of potentially unsafe paths to sys.path. This can be useful for improving security and reducing the risk of arbitrary code execution.
Deprecated features
Deprecated features and APIs are those that are no longer recommended for use and will be removed in future versions of Python. This can be done for a variety of reasons, such as security vulnerabilities, performance problems, or because the feature is no longer needed. Here’s a list of features/APIs that are deprecated in Python 3.11 and will be removed in later versions:
Py_UNICODEencoder APIs have been converted to static inline functions, which are more efficient and easier to use.A variety of Python APIs that have been deprecated for various reasons. For example, the
pickle.Unpicklerclass is deprecated because it’s vulnerable to security attacks.
It’s important to note that deprecated features and APIs are still functional in Python 3.11. However, it’s recommended to avoid using them if possible because they may be removed in future versions of Python.
Conclusion
Python 3.11 is a major release of the Python programming language, with a number of new features and improvements that make it faster, more reliable, and more user-friendly. Some of the most notable changes include faster performance, improved type safety, new language features, and an improved standard library.
It’s recommended to upgrade to Python 3.11. The upgrade process is relatively straightforward, and the benefits of using Python 3.11 are well worth it.
Free Resources