Release of the Python 3.9 programming language

After a year of development submitted significant programming language release Python 3.9. Python 3.9 was the first release after transition project on new cycle preparation and maintenance of releases. New major releases will now be generated once a year, and corrective updates will be released every other month. Each significant branch will be supported for a year and a half, after which patches with vulnerabilities will be formed for it for another three and a half years.

Work on a new branch now starts five months before the release of the next branch, i.e. concurrent with the release of Python 3.9 started alpha testing of the Python 3.10 branch. The Python 3.10 branch will be in alpha releases for seven months, during which new features will be added and bugs will be fixed. After that, beta versions will be tested for three months, during which the addition of new features will be prohibited and all attention will be paid to fixing bugs. The last two months before the release, the branch will be at the release candidate stage, at which the final stabilization will be performed.

Among added innovations in Python 3.9:

  • In dictionaries defined with the built-in dict class, appeared support for merge operators "|" and "|=" updates, which supplement the {**d1, **d2} and dict.update methods previously offered for concatenating dictionaries.

    >>> x = {"key1": "value1 from x", "key2": "value2 from x"}
    >>> y = {"key2": "value2 from y", "key3": "value3 from y"}

    >>> x | y
    {'key1': 'value1 from x', 'key2': 'value2 from y', 'key3': 'value3 from y'}

    >>> y | x
    {'key2': 'value2 from x', 'key3': 'value3 from y', 'key1': 'value1 from x'}

  • The built-in collection of types includes list, dict, and tuple, which can be used as base types without being imported from the typing module. Those. instead of typing.List, typing.Dict and typing.Tuple can now be specified
    just list, dict and tuple:

    def greet_all(names: list[str]) -> None:
    for names in names:
    print("Hello", name)

  • Are provided flexible means for annotating functions and variables. To attach annotations, a new Annotated type has been added to the typing module, which extends existing types with additional metadata that can be used in static analysis or for run-time optimizations. To access metadata from code, the include_extras parameter has been added to the typing.get_type_hints() method.

    charType = Annotated[int, ctype("char")] UnsignedShort = Annotated[int, struct2.ctype('H')]

  • softened grammar requirements for decorators - any expression suitable for use in if and while blocks can now be used as a decorator. The change allowed to significantly improve the readability of the PyQt5 code and simplify the maintenance of this module:

    It was:
    button_0 = buttons[0] @button_0.clicked.connect

    Now you can write:
    @buttons[0].clicked.connect

  • To the standard library added module zone info, which includes information from the IANA time zone database.

    >>> from zoneinfo import ZoneInfo
    >>> from datetime import datetime, timedelta
    >>> # Summer time
    >>> dt = datetime(2020, 10, 31, 12, tzinfo=ZoneInfo("America/Los_Angeles"))
    >>>print(dt)
    2020-10-31 12:00:00-07:00

    >>> dt.tzname()
    'PDT'

    >>> # Standard time
    >>> dt += timedelta(days=7)
    >>>print(dt)
    2020-11-07 12:00:00-08:00

    >>> print(dt.tzname())
    PST

  • The graphlib module has been added, in which implemented support for topological sorting of graphs.
  • Suggested new methods for removing prefixes and line endings - str.removeprefix(prefix) and str.removesuffix(suffix). Methods have been added to the str, bytes, bytearray, and collections.UserString objects.

    >>> s = "FooBar"
    >>> s.removeprefix("Foo")
    'Pub'

  • Involved new parser PEG (Parsing Expression Grammar), which replaced the parser LL(1). The use of the new parser made it possible to get rid of some of the "hacks" used to circumvent the restrictions in LL(1), and significantly reduced the labor costs for maintaining the parser. In terms of performance, the new parser is about on par with the old one, but it is significantly ahead of it in terms of flexibility, which allows you to feel more free to design new features of the language. The old parser code has been kept for now and can be reverted with the "-X oldparser" flag or the "PYTHONOLDPARSER=1" environment variable, but will be removed in the 3.10 release.
  • Provided by the ability for C-extension methods to access the state of the modules in which they are defined using direct pointer dereference instead of finding the module state using the PyState_FindModule function. The change improves the performance of C modules by reducing or completely eliminating the overhead for checking the module state. To associate a module with a class, the PyType_FromModuleAndSpec() C function is proposed, to get the module and its state, the PyType_GetModule() and PyType_GetModuleState() C functions, and to provide an access method to the class in which it is defined, the PyCMethod C function and the METH_METHOD flag .
  • Garbage collector spared from locking collections that include reanimated objects that remain externally accessible after the finalizer has run.
  • Added method os.pidfd_open, which allows the Linux kernel subsystem "pidfd" to be used to handle the PID reuse situation (pidfd is associated with a specific process and does not change, while a PID can be associated with another process after the current process associated with this PID terminates).
  • Support for the Unicode specification has been updated to version 13.0.0.
  • Eliminated memory leak when re-initializing the Python interpreter in the same process.
  • The performance of the built-in types range, tuple, set, frozenset, list and dict has been optimized, realized by using the Vectorcall shortcut protocol for faster access to objects written in the C language.
  • The _abc, audioop, _bz2, _codecs, _contextvars, _crypt, _functools, _json, _locale, operator, resource, time, and _weakref modules have been moved to load from initialization in several stages.
  • The audioop, ast, grp, _hashlib, pwd, _posixsubprocess, random, select, struct, termios, and zlib standard library modules have been moved to use the restricted stable ABI, which solves the problem of the operability of extension module assemblies for different versions of Python (upgrading the version does not require rebuilding extension modules, and modules built for 3.9 will be able to work in the 3.10 branch).
  • The asyncio module has deprecated the reuse_address option due to potential security issues (Linux's use of SO_REUSEADDR for UDP allows different processes to attach listening sockets to a UDP port).
  • New optimizations have been added, for example, improved performance of signal handlers in multithreaded applications, increased speed of the subprocess module in the FreeBSD environment, and faster assignment of temporary variables (assigning a variable in the expression "for y in [expr]" is now as efficient as the expression "y = expr "). In general, most tests show performance degradation compared to the 3.8 branch (speedup is observed only in the write_local and write_deque tests):

    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

  • Removed many Python 2.7 functions and methods that were previously deprecated and resulted in a DeprecationWarning in a previous release, including the unescape() method in html.parser.HTMLParser,
    tostring() and fromstring() on array.array, isAlive() on threading.Thread, getchildren() and getiterator() on ElementTree, sys.getcheckinterval(), sys.setcheckinterval(), asyncio.Task.current_task(), asyncio.Task.all_tasks(), base64.encodestring() and base64.decodestring().

Source: opennet.ru

Add a comment