Python in 2021 — Timeline and upcoming features | by Ankit Gupta | Towards Data Science

We are currently living in the stable age of Python 3.8 and the latest stable version of Python, 3.8.4, was released last week. Python 3.9 is already in the beta phase of its development and a beta version (3.9.0b4) was pre-released on July 3, 2020, with the fifth beta pre-release scheduled for tomorrow. The first stable release of 3.9 is expected in October 2020. The development of Python 3.10, too, has kicked-off in May 2020 and the first beta version is expected in May 2021.
For Python lovers, clearly, interesting times lie ahead. Browsing through the release schedules of three versions (3.8, 3.9, and 3.10) urged me to compile the key dates in the interesting upcoming timeline of Python’s development.
“My mom always said life was like a box of chocolates. You never know what you’re gonna get.” — Forrest Gump
Usually, there are 4–5 beta releases in the development cycle, and no new features are introduced in a version after the first beta release. For 3.8, beta-1 was released in June 2019 and for 3.9, beta-1 was released in May 2020. Although the future Python 3.10 has just initiated, the official website already provides a sneak-peak into some of its Highlights.
This post is intended to provide a brief overview of the timeline and a preview of the highlight features of the upcoming new Python version, adapting the official examples from Python’s website. Please note that we can expect more new features in Version 3.10 and I will keep updating the list below over time.
A new method bit_count()will be introduced that will return the number of ones present in the binary representation of an integer number. The result will be independent of the sign of the integer. One use case of this functionality is in Information Theory, where for two equal-lengthed strings, you can find the total count of places at which the two strings differ. This difference is referred to as the Hamming Distance (see Wiki). Read here for the history of this functionality in Python.
Under the hood, this method simply calls the count method of the strtype asstr.count('1'). The following example explains it
# Positive integer >>> num = 108# Let's first get the binary representation of num>>> bin(num)'0b1101100'>>> num.bit_count()4# Negative integer>>> num = -108>>> bin(num)'-0b1101100'>>> num.bit_count()4# Under the hood>>> bin(num).count('1')
A new, optional keyword argument strict will be added to the zip function. If you passstrict=True, the iterables that you are zipping must be of equal length, or else a ValueError will be raised. Until Python 3.9, if you are zipping two lists of unequal length, you would get the output with the length equal to the smaller list.
As you can see in the following example, before Python 3.10, the zip() function ignored the unmatched 'D' in the first list. By contrast, Python 3.10 will raise a ValueError. Given the intuitiveness of zipping an equal number of items, I like this feature as it wakes you up to re-inspect your input. Read more on this issue at PEP 618.
Before Python 3.10
>>> list(zip(['A', 'B', 'C', 'D'], ['Apple', 'Ball', 'Cat']))[('A', 'Apple'), ('B', 'Ball'), ('C', 'Cat')]
In Python 3.10
>>> list(zip(['A', 'B', 'C', 'D'], ['Apple', 'Ball', 'Cat'],             strict=True))Traceback (most recent call last):  ...ValueError: zip() argument 1 is longer than argument 2
The three key methods of dictionaries, keys(), values() and items(), returns set-like objects that respectively correspond to a dynamic view on dictionaries’ keys, values, and items. Any change you make in either of these views will also be reflected in the original dictionary.
In Python 3.10, all the returned views from the above three methods will have an additional attribute called mapping that will return a read-only proxy of the mapping. This read-only proxy will wrap the original dictionary which is being referred to by the view. The following example illustrates it:
Let’s define a dictionary and store its keys and values in separate variables
>>> fruits = {'Mangos': 12, 'Figs': 100, 'Guavas': 3, 'Kiwis': 70}>>> keys = fruits.keys()>>> values = fruits.values()>>> list(keys)['Mangos', 'Figs', 'Guavas', 'Kiwis']
Now let’s delete two elements from this dictionary using thedel statement. If you now print the keys and values, you will see that it returns only the remaining items. The changes in the original dictionary are now reflected in the views (keys and valueshere).
>>> del fruits['Figs']>>> del fruits['Guavas']>>> print (list(keys), list(values))['Mangos', 'Kiwis'] [12, 70]
Now, with mapping, you will be able to still get back a read-only proxy of the original dictionary. Cool! Isn’t it?
# returns a read-only proxy of the original dictionary>>> values.mappingmappingproxy({'Mangos': 12, 'Figs': 100, 'Guavas': 3, 'Kiwis': 70})>>> values.mapping['Guavas']3
The alias support for the Abstract Base Classes (ABCs) of the collections module will be dropped from Python 3.10 onwards. So it’s a good time to stop ignoring the corresponding Deprecation Warnings and adapt your code.
Up to Python 3.9.0b4 (Released on July 3, 2020)
Importing any of these ABCs directly from thecollections module would result until now in the DeprecationWarning
>>> from collections import ABC_NameDeprecationWarning: Using or importing the ABCs from 'collections' instead of from 'collections.abc' is deprecated since Python 3.3,and in 3.9 it will stop working
This brings me to the end of this article. As Python 3.10 will announce further Release Highlights, I will keep appending them to this article. Stay tuned and let’s look forward to Python 3.10. You can follow the release schedules for the current and upcoming versions here: 3.8, 3.9, 3.10. If you also want to stay updated with the latest features in Matplotlib and Scikit-learn, read my recent articles on What’s new in Matplotlib 3 and New features in Scikit-learn.