“This is the first version of Python to default to the 64-bit installer on Windows. The installer now also actively disallows installation on Windows 7. "
“This is the first version of Python to use the 64-bit installer on Windows by default. The installer now also prevents installation on Windows 7. "
I have read the Python 3.9 release notes and related discussions. Based on the information, I wanted to write a comprehensive guide so that everyone can get an idea of the functions along with their detailed work.
UPD :
Transition to stable annual release cycles, see PEP 602
alec_kalinin
“Every new version of Python will now come out in October. Python 3.10 will be released in October 2021, Python 3.11 in October 2022. Buckfix will be released every two months. This is great news for me, now we can clearly plan to upgrade the python environment. "
PEP 584
This PEP suggests adding the merge ( | ) and update ( | = ) operators to the built-in dict class.
To merge: |
>>> a = {'milk': 'prostokvashino', 'heese': 'cheddar'}
>>> b = {'milk': 1, 'heese': 2, 'bread': 3}
>> > | b
{'milk': 1, 'heese': 2, 'bread': 3}
>>> b | a
{'milk': 'prostokvashino', 'heese': 'cheddar', 'bread': 3}
To update: | =
>>> a | = b
>>> a
{'milk': 1, 'heese': 2, 'bread': 3}
The key rule to remember is that if there are any key conflicts, then the rightmost value will be preserved.
Of course, many pythonists will have a question, why is this necessary, if there is already an option familiar to everyone
{**d1, **d2}
This question was answered in the PEP itself:
Unpacking dictionaries looks ugly and is not easy to detect. Few will be able to guess what this means when they first see it.
As Guido said :
I'm sorry about PEP 448 , but even if you know about ** d in a simpler context, if you were asking a typical Python user how to combine two dict into a new one, I doubt many people would think of {** d1, ** d2}. I know I forgot about it myself when this thread started!
Also {** d1, ** d2} doesn't work for dict subclasses like defaultdict
PEP 585
Generics type hints in standard collections.
Generic is a type that can be parameterized, a kind of container. Also known as parametric type or generic type.
This release includes universal syntax support for all standard collections currently available in the Typing module. We can use list or dict types as generic types instead of using typing.List or typing.Dict .
It was:
from typing import List
a: List[str] = list()
def read_files(files: List[str]) -> None:
pass
Became:
a: list[str] = list()
def read_files(files: list[str]) -> None:
pass
Complete list of types
tuple
list
dict
set
frozenset
type
collections.deque
collections.defaultdict
collections.OrderedDict
collections.Counter
collections.ChainMap
collections.abc.Awaitable
collections.abc.Coroutine
collections.abc.AsyncIterable
collections.abc.AsyncIterator
collections.abc.AsyncGenerator
collections.abc.Iterable
collections.abc.Iterator
collections.abc.Generator
collections.abc.Reversible
collections.abc.Container
collections.abc.Collection
collections.abc.Callable
collections.abc.Set # typing.AbstractSet
collections.abc.MutableSet
collections.abc.Mapping
collections.abc.MutableMapping
collections.abc.Sequence
collections.abc.MutableSequence
collections.abc.ByteString
collections.abc.MappingView
collections.abc.KeysView
collections.abc.ItemsView
collections.abc.ValuesView
contextlib.AbstractContextManager # typing.ContextManager
contextlib.AbstractAsyncContextManager # typing.AsyncContextManager
re.Pattern # typing.Pattern, typing.re.Pattern
re.Match # typing.Match, typing.re.Match
list
dict
set
frozenset
type
collections.deque
collections.defaultdict
collections.OrderedDict
collections.Counter
collections.ChainMap
collections.abc.Awaitable
collections.abc.Coroutine
collections.abc.AsyncIterable
collections.abc.AsyncIterator
collections.abc.AsyncGenerator
collections.abc.Iterable
collections.abc.Iterator
collections.abc.Generator
collections.abc.Reversible
collections.abc.Container
collections.abc.Collection
collections.abc.Callable
collections.abc.Set # typing.AbstractSet
collections.abc.MutableSet
collections.abc.Mapping
collections.abc.MutableMapping
collections.abc.Sequence
collections.abc.MutableSequence
collections.abc.ByteString
collections.abc.MappingView
collections.abc.KeysView
collections.abc.ItemsView
collections.abc.ValuesView
contextlib.AbstractContextManager # typing.ContextManager
contextlib.AbstractAsyncContextManager # typing.AsyncContextManager
re.Pattern # typing.Pattern, typing.re.Pattern
re.Match # typing.Match, typing.re.Match
PEP 615
IANA time zone database support in the standard library.
IANA time zones are often referred to as tz or zone info. There are a large number of IANA time zones with different search paths for specifying the IANA time zone for a date and time object. For example, we can pass the name of the search path as Continent / City to a datetime object to set its tzinfo.
dt: datetime = datetime(2000, 01, 25, 01, tzinfo=ZoneInfo("Europe/London"))
If we pass in the wrong key, an exception will be thrown
zoneinfo.ZoneInfoNotFoundError
PEP 616
New string functions to remove prefix and suffix. Two new functions have been added
to the str object.
- The first function removes the prefix.
str.removeprefix(prefix)
- The second function removes the suffix.
str.removesuffix(suffix)
>>> 'hello_world'.removeprefix ('hello_')
world
>>> 'hello_world'.removesuffix ('_world')
hello
PEP 617
Python 3.9 proposes to replace the current LL (1) -based Python parser with a new PEG-based parser that is high performance and stable.
The current CPython parser is based on LL (1). Subsequently, the grammar is based on LL (1), which allows it to be parsed with an LL (1) parser. The LL (1) parser works from top to bottom. In addition, it parses the input data from left to right. The current grammar is context free grammar, so the context of the tokens is not taken into account.
Python 3.9 proposes to replace it with a new PEG based parser, which means it will remove the current limitations of Python's LL grammar (1). In addition, fixes have been made to the current parser, adding a number of hacks that will be removed. As a result, this will reduce the cost of maintenance in the long run.
For example, while LL (1) parsers and grammars are easy to implement, constraints prevent them from expressing common constructs in a natural way for the language designer and reader. The parser only looks one token forward to distinguish between possibilities.
issue30966
Ability to cancel simultaneous futures .
A new parameter cancel_futures has been added to concurrent.futures.Executor.shutdown () .
This parameter contains all pending futures that have not yet started. Prior to version 3.9, the process waited for them to complete before exiting the executor.
A new parameter cancel_futures has been added to ThreadPoolExecutor and ProcessPoolExecutor . It works when the parameter value is True, then all pending futures will be canceled when the shutdown () function is called .
When shutdown ()is executed, the interpreter checks to see if the executor is garbage collected. If it is still in memory, it gets any pending items and then cancels the futures.
issue30966
A number of improvements have been made to the asyncio and multiprocessing library in this release.
For instance,
- The reuse_address parameter asyncio.loop.create_datagram_endpoint () is no longer supported due to significant security issues.
- Added new coroutines, shutdown_default_executor (), and asyncio.to_thread () coroutines . A new call to asyncio.to_thread () is used to run I / O-related functions on a separate thread to avoid blocking the event loop.
As for the enhancements to the multiprocessing library, a new close () method has been added to the multiprocessing.SimpleQueue class . This method explicitly closes the queue. This ensures that the queue is closed and does not stay longer than expected. It is important to remember that the get (), put (), empty () methods cannot be called after the queue is closed.
issue37444
Fixed bug with importing packages.
The main problem with importing Python libraries prior to the 3.9 release was inconsistent import behavior in Python when relative imports passed by its top-level package.
builtins .__ import __ () raised a ValueError while importlib .__ import __ () raised an ImportError.
Now it is corrected . __Import __ () now raises ImportError instead of ValueError.
issue40286
Generation of random bytes.
Another feature that was added in version 3.9 is random.Random.randbytes () . It can be used to generate random bytes.
We can generate random numbers, but what if we needed to generate random bytes? Prior to version 3.9, developers had to be creative to generate random bytes. Although we can use os.getrandom () , os.urandom (), or secrets.token_bytes (), we cannot generate pseudo-random patterns.
For example, to ensure that random numbers are generated with expected behavior and the process reproduces, we usually use seed with the random.Random module.
As a result, the random.Random.randbytes () method was introduced . It generates random bytes.
issue28029
Correction of the string replacement function.
The principle of the replace function is that for a given maximum argument to replace an occurrence, it replaces the character set from the string with the new character set.
To further explain the problem, prior to version 3.9 the replace function had inconsistent behavior:
One would expect to see blog
"" .replace ("", "blog", 1)
>>> ''
One would expect to see |
"" .replace ("", "|", 1)
>>> ''
"" .replace ("", "prefix")
>>> 'prefix'
issue39648, issue39479, issue39288, issue39310
Changes in the "math" module.
Returns the least common multiple of integer arguments:
>>> import math
>>> math.lcm(48,72,108)
432
Returns the greatest common divisor of integer arguments. The earlier version only supported two arguments. Added support for an arbitrary number of arguments:
>>> import math
>>> math.gcd(9,12,21)
3
Calculates the floating-point number closest to " x " in the direction of " y ".
>>> math.nextafter(2, -1)
1.9999999999999998
This method returns the value of the least significant bit of the floating point number x.
>>> 1 - math.ulp(1)
0.9999999999999998
>>> math.nextafter(1, -1) + math.ulp(1)
1.0
issue38870
The unparse method was added to the ast module.
The new method can be used to create a line of code and then execute it.
>>> import ast
>>> parsed = ast.parse('from sys import platform; print(platform)')
>>> unparsed_str = ast.unparse(parsed)
>>> print(unparsed_str)
from sys import platform
print(platform)
>>> exec(unparsed_str)
win32
issue39507, issue39509
Adding new codes to http.HTTPStatus.
" Save 418! "
418 IM_A_TEAPOT
103 EARLY_HINTS
425 TOO_EARLY
UPD :
PEP 614
Relaxing grammatical restrictions for decorators.
It was:
buttons = [QPushButton(f'Button {i}') for i in range(10)]
button_0 = buttons[0]
@button_0.clicked.connect
def spam():
...
button_1 = buttons[1]
@button_1.clicked.connect
def eggs():
...
Now you can remove unnecessary assignments and call directly:
buttons = [QPushButton(f'Button {i}') for i in range(10)]
@buttons[0].clicked.connect
def spam():
...
@buttons[1].clicked.connect
def eggs():
...
"The tuple must be enclosed in parentheses."
This is based on Guido's vision in the same letter. Quote:
But I will not allow commas. I cannot agree with this
@f, g def pooh(): ...
This can lead inexperienced programmers to the conclusion that multiple decorators can be called in a row this way. The parentheses are needed to clarify things without additional restrictions or complex syntax.
issue17005
The new graphlib module provides functionality for topological sorting of a graph of hashed nodes.
More details can be found in the documentation .
UPD :ifinik
>>> from graphlib import TopologicalSorter
>>> graph = {'E': {'C', 'F'}, 'D': {'B', 'C'}, 'B': {'A'}, 'A': {'F'}}
>>> ts = TopologicalSorter(graph)
>>> tuple(ts.static_order())
('C', 'F', 'E', 'A', 'B', 'D')
>>> tuple(ts.static_order())
('F', 'C', 'A', 'E', 'B', 'D')
The graph can be transferred not immediately, but fill in the TopologicalSorter using the add method . In addition, the class is adapted to parallel computing and can be used, for example, to create a task queue.
issue37630, issue40479
Updating hashlib.
Hashlib can now use SHA3 and SHAKE XOF hashes from OpenSSL.
Built-in hash modules can now be disabled or selectively enabled, for example to enforce an OpenSSL-based implementation.
Optimization
A summary of the performance improvements from Python 3.4 to Python 3.9:
Python version 3.4 3.5 3.6 3.7 3.8 3.9
-------------- --- --- --- --- --- ---
Variable and attribute read access:
read_local 7.1 7.1 5.4 5.1 3.9 4.0
read_nonlocal 7.1 8.1 5.8 5.4 4.4 4.8
read_global 15.5 19.0 14.3 13.6 7.6 7.7
read_builtin 21.1 21.6 18.5 19.0 7.5 7.7
read_classvar_from_class 25.6 26.5 20.7 19.5 18.4 18.6
read_classvar_from_instance 22.8 23.5 18.8 17.1 16.4 20.1
read_instancevar 32.4 33.1 28.0 26.3 25.4 27.7
read_instancevar_slots 27.8 31.3 20.8 20.8 20.2 24.5
read_namedtuple 73.8 57.5 45.0 46.8 18.4 23.2
read_boundmethod 37.6 37.9 29.6 26.9 27.7 45.9
Variable and attribute write access:
write_local 8.7 9.3 5.5 5.3 4.3 4.2
write_nonlocal 10.5 11.1 5.6 5.5 4.7 4.9
write_global 19.7 21.2 18.0 18.0 15.8 17.2
write_classvar 92.9 96.0 104.6 102.1 39.2 43.2
write_instancevar 44.6 45.8 40.0 38.9 35.5 40.7
write_instancevar_slots 35.6 36.1 27.3 26.6 25.7 27.7
Data structure read access:
read_list 24.2 24.5 20.8 20.8 19.0 21.1
read_deque 24.7 25.5 20.2 20.6 19.8 21.6
read_dict 24.3 25.7 22.3 23.0 21.0 22.5
read_strdict 22.6 24.3 19.5 21.2 18.9 21.6
Data structure write access:
write_list 27.1 28.5 22.5 21.6 20.0 21.6
write_deque 28.7 30.1 22.7 21.8 23.5 23.2
write_dict 31.4 33.3 29.3 29.2 24.7 27.8
write_strdict 28.4 29.9 27.5 25.2 23.1 29.8
Stack (or queue) operations:
list_append_pop 93.4 112.7 75.4 74.2 50.8 53.9
deque_append_pop 43.5 57.0 49.4 49.2 42.5 45.5
deque_append_popleft 43.7 57.3 49.7 49.7 42.8 45.5
Timing loop:
loop_overhead 0.5 0.6 0.4 0.3 0.3 0.3
The test script displays the time in nanoseconds. Tests were performed on an Intel Core i7-4960HQ processor . The test code can be found in the repository at " Tools / scripts / var_access_benchmark.py " .
Thank you for attention.
Link to the official Python 3.9 manual .
Unsubscribe in the comments if you missed something.