Was ist neu in Python 3.9

Editor:

Łukasz Langa

Dieser Artikel erklärt die neuen Funktionen in Python 3.9 im Vergleich zu 3.8. Python 3.9 wurde am 5. Oktober 2020 veröffentlicht. Vollständige Details finden Sie im Changelog.

Siehe auch

PEP 596 - Zeitplan für die Veröffentlichung von Python 3.9

Zusammenfassung – Release-Highlights

Neue Syntaxfunktionen

  • PEP 584, Union-Operatoren zu dict hinzugefügt;

  • PEP 585, Type Hinting Generics in Standard Collections;

  • PEP 614, gelockerte Grammatikbeschränkungen für Decorators.

Neue eingebaute Funktionen

  • PEP 616, String-Methoden zum Entfernen von Präfixen und Suffixen.

Neue Funktionen in der Standardbibliothek

  • PEP 593, flexible Funktions- und Variablenannotationen;

  • os.pidfd_open() hinzugefügt, die eine prozessverwaltung ohne Race Conditions und Signale ermöglicht.

Interpreter-Verbesserungen

  • PEP 573, schneller Zugriff auf Modulzustand aus Methoden von C-Erweiterungstypen;

  • PEP 617, CPython verwendet jetzt einen neuen Parser, der auf PEG basiert;

  • eine Reihe von Python-Builtins (range, tuple, set, frozenset, list, dict) werden jetzt mithilfe von PEP 590 vectorcall beschleunigt;

  • Garbage Collection blockiert nicht mehr bei wiederbelebten Objekten;

  • eine Reihe von Python-Modulen (_abc, audioop, _bz2, _codecs, _contextvars, _crypt, _functools, _json, _locale, math, operator, resource, time, _weakref) verwenden nun die Multiphase-Initialisierung gemäß PEP 489;

  • eine Reihe von Standardbibliotheksmodulen (audioop, ast, grp, _hashlib, pwd, _posixsubprocess, random, select, struct, termios, zlib) verwenden nun die stabile ABI gemäß PEP 384.

Neue Bibliotheksmodule

  • PEP 615, die IANA Zeitzonendatenbank ist jetzt in der Standardbibliothek im Modul zoneinfo vorhanden;

  • eine Implementierung einer topologischen Sortierung eines Graphen wird nun im neuen Modul graphlib bereitgestellt.

Änderungen im Release-Prozess

  • PEP 602, CPython übernimmt einen jährlichen Release-Zyklus.

Sie sollten in Ihrem Code nach DeprecationWarning suchen

Als Python 2.7 noch unterstützt wurde, wurde viel Funktionalität in Python 3 zur Abwärtskompatibilität mit Python 2.7 beibehalten. Mit dem Ende der Unterstützung für Python 2 wurden diese Abwärtskompatibilitätsschichten entfernt oder werden bald entfernt. Die meisten davon haben jahrelang eine DeprecationWarning ausgegeben. Zum Beispiel gibt die Verwendung von collections.Mapping anstelle von collections.abc.Mapping seit Python 3.3, veröffentlicht 2012, eine DeprecationWarning aus.

Testen Sie Ihre Anwendung mit der Kommandozeilenoption -W default, um DeprecationWarning und PendingDeprecationWarning zu sehen, oder sogar mit -W error, um sie als Fehler zu behandeln. Warnungsfilter kann verwendet werden, um Warnungen von Drittanbieter-Code zu ignorieren.

Python 3.9 ist die letzte Version, die diese Python 2-Abwärtskompatibilitätsschichten bereitstellt, um Python-Projektbetreuern mehr Zeit zu geben, die Entfernung der Python 2-Unterstützung zu organisieren und die Unterstützung für Python 3.9 hinzuzufügen.

Aliase zu abstrakten Basisklassen im Modul collections, wie z.B. collections.Mapping Alias zu collections.abc.Mapping, bleiben aus Gründen der Abwärtskompatibilität für eine letzte Veröffentlichung erhalten. Sie werden aus Python 3.10 entfernt.

Im Allgemeinen versuchen Sie, Ihre Tests im Python Development Mode auszuführen, was dazu beiträgt, Ihren Code für die nächste Python-Version vorzubereiten.

Hinweis: Eine Reihe bereits vorhandener Deprecations wurden ebenfalls in dieser Python-Version entfernt. Konsultieren Sie den Abschnitt Entfernt.

Neue Funktionen

Dictionary Merge & Update Operatoren

Merge (|) und Update (|=) Operatoren wurden der integrierten Klasse dict hinzugefügt. Diese ergänzen die bestehenden Methoden dict.update und {**d1, **d2} zum Zusammenführen von Dictionaries.

Beispiel

>>> 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'}

Siehe PEP 584 für eine vollständige Beschreibung. (Beigetragen von Brandt Bucher in bpo-36144.)

Neue String-Methoden zum Entfernen von Präfixen und Suffixen

str.removeprefix(prefix) und str.removesuffix(suffix) wurden hinzugefügt, um leicht ein unnötiges Präfix oder Suffix aus einem String zu entfernen. Entsprechende Methoden für bytes, bytearray und collections.UserString wurden ebenfalls hinzugefügt. Siehe PEP 616 für eine vollständige Beschreibung. (Beigetragen von Dennis Sweeney in bpo-39939.)

Type Hinting Generics in Standard Collections

In Typannotationen können Sie jetzt integrierte Sammlungsdatentypen wie list und dict als generische Typen verwenden, anstatt die entsprechenden großgeschriebenen Typen (z. B. List oder Dict) aus typing zu importieren. Einige andere Typen in der Standardbibliothek sind ebenfalls jetzt generisch, zum Beispiel queue.Queue.

Beispiel

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

Siehe PEP 585 für weitere Details. (Beigetragen von Guido van Rossum, Ethan Smith und Batuhan Taşkaya in bpo-39481.)

Neuer Parser

Python 3.9 verwendet einen neuen Parser, der auf PEG anstelle von LL(1) basiert. Die Leistung des neuen Parsers ist ungefähr vergleichbar mit der des alten Parsers, aber der PEG-Formalismus ist flexibler als LL(1) bei der Gestaltung neuer Sprachmerkmale. Wir werden diese Flexibilität ab Python 3.10 nutzen.

Das Modul ast verwendet den neuen Parser und erzeugt denselben AST wie der alte Parser.

In Python 3.10 wird der alte Parser gelöscht, ebenso wie alle Funktionen, die davon abhängen (hauptsächlich das Modul parser, das seit langem als veraltet gilt). Nur in Python 3.9 können Sie mit einem Kommandozeilenschalter (-X oldparser) oder einer Umgebungsvariable (PYTHONOLDPARSER=1) zum LL(1)-Parser zurückschalten.

Siehe PEP 617 für weitere Details. (Beigetragen von Guido van Rossum, Pablo Galindo und Lysandros Nikolaou in bpo-40334.)

Andere Sprachänderungen

  • __import__() wirft jetzt ImportError anstelle von ValueError, was früher auftrat, wenn ein relativer Import über sein Top-Level-Paket hinausging. (Beigetragen von Ngalim Siregar in bpo-37444.)

  • Python erhält nun den absoluten Pfad des auf der Kommandozeile angegebenen Skriptnamens (z. B. python3 script.py): das Attribut __file__ des Moduls __main__ wurde zu einem absoluten Pfad anstelle eines relativen Pfads. Diese Pfade bleiben gültig, nachdem das aktuelle Verzeichnis durch os.chdir() geändert wurde. Als Nebeneffekt zeigt der Traceback in diesem Fall auch den absoluten Pfad für Frames des Moduls __main__ an. (Beigetragen von Victor Stinner in bpo-20443.)

  • Im Python Development Mode und in der Debug-Build werden die Argumente encoding und errors jetzt für String-Codierungs- und Decodierungsoperationen überprüft. Beispiele: open(), str.encode() und bytes.decode().

    Standardmäßig wird für beste Leistung das Argument errors nur beim ersten Codierungs-/Decodierungsfehler überprüft, und das Argument encoding wird manchmal für leere Strings ignoriert. (Beigetragen von Victor Stinner in bpo-37388.)

  • "".replace("", s, n) gibt nun s anstelle eines leeren Strings für alle nicht-nullen n zurück. Es ist nun konsistent mit "".replace("", s). Es gibt ähnliche Änderungen für bytes und bytearray Objekte. (Beigetragen von Serhiy Storchaka in bpo-28029.)

  • Jeder gültige Ausdruck kann nun als Decorator verwendet werden. Zuvor war die Grammatik viel restriktiver. Siehe PEP 614 für Details. (Beigetragen von Brandt Bucher in bpo-39702.)

  • Verbesserte Hilfe für das Modul typing. Docstrings werden nun für alle Sonderformen und speziellen generischen Aliase (wie Union und List) angezeigt. Die Verwendung von help() mit einem generischen Alias wie List[int] zeigt die Hilfe für den entsprechenden konkreten Typ an (in diesem Fall list). (Beigetragen von Serhiy Storchaka in bpo-40257.)

  • Paralleles Ausführen von aclose() / asend() / athrow() ist nun verboten, und ag_running spiegelt nun den tatsächlichen Ausführungsstatus des asynchronen Generators wider. (Beigetragen von Yury Selivanov in bpo-30773.)

  • Unerwartete Fehler beim Aufruf der Methode __iter__ werden nicht mehr durch TypeError im in Operator und in den Funktionen contains(), indexOf() und countOf() des Moduls operator maskiert. (Beigetragen von Serhiy Storchaka in bpo-40824.)

  • Nicht in Klammern gesetzte Lambda-Ausdrücke können nicht mehr der Ausdrucksteil in einer if-Klausel in Comprehensions und Generatorausdrücken sein. Siehe bpo-41848 und bpo-43755 für Details.

Neue Module

zoneinfo

Das Modul zoneinfo bringt Unterstützung für die IANA Zeitzonendatenbank in die Standardbibliothek. Es fügt zoneinfo.ZoneInfo hinzu, eine konkrete datetime.tzinfo-Implementierung, die auf den Zeitzonendaten des Systems basiert.

Beispiel

>>> from zoneinfo import ZoneInfo
>>> from datetime import datetime, timedelta

>>> # Daylight saving 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

Als Fallback-Quelle für Plattformen, die die IANA-Datenbank nicht mitliefern, wurde das Modul tzdata als First-Party-Paket veröffentlicht – verteilt über PyPI und gepflegt vom CPython-Kernteam.

Siehe auch

PEP 615 – Unterstützung für die IANA Zeitzonendatenbank in der Standardbibliothek

PEP geschrieben und implementiert von Paul Ganssle

graphlib

Ein neues Modul, graphlib, wurde hinzugefügt, das die Klasse graphlib.TopologicalSorter enthält, um Funktionalität für die topologische Sortierung von Graphen bereitzustellen. (Beigetragen von Pablo Galindo, Tim Peters und Larry Hastings in bpo-17005.)

Verbesserte Module

ast

Die Option indent wurde zu dump() hinzugefügt, die eine mehrzeilige Einrückung ermöglicht. (Beigetragen von Serhiy Storchaka in bpo-37995.)

Die Funktion ast.unparse() wurde als Funktion im Modul ast hinzugefügt, die verwendet werden kann, um ein ast.AST-Objekt zu unparsen und einen String mit Code zu erzeugen, der ein äquivalentes ast.AST-Objekt beim Parsen erzeugt. (Beigetragen von Pablo Galindo und Batuhan Taskaya in bpo-38870.)

Docstrings wurden zu AST-Knoten hinzugefügt, die die ASDL-Signatur enthalten, die zur Konstruktion dieses Knotens verwendet wurde. (Beigetragen von Batuhan Taskaya in bpo-39638.)

asyncio

Aufgrund erheblicher Sicherheitsbedenken wird der Parameter reuse_address von asyncio.loop.create_datagram_endpoint() nicht mehr unterstützt. Dies liegt am Verhalten der Socket-Option SO_REUSEADDR in UDP. Weitere Details finden Sie in der Dokumentation für loop.create_datagram_endpoint(). (Beigetragen von Kyle Stanley, Antoine Pitrou und Yury Selivanov in bpo-37228.)

Eine neue Coroutine shutdown_default_executor() wurde hinzugefügt, die ein Herunterfahren des Standard-Executors plant, der auf das Beenden des ThreadPoolExecutor wartet. Außerdem wurde asyncio.run() aktualisiert, um die neue Coroutine zu verwenden. (Beigetragen von Kyle Stanley in bpo-34037.)

Es wurde asyncio.PidfdChildWatcher hinzugefügt, eine Linux-spezifische Child-Watcher-Implementierung, die Prozess-Deskriptoren abfragt. (bpo-38692)

Eine neue Coroutine asyncio.to_thread() wurde hinzugefügt. Sie wird hauptsächlich zum Ausführen von E/A-gebundenen Funktionen in einem separaten Thread verwendet, um zu vermeiden, dass die Event-Schleife blockiert, und funktioniert im Wesentlichen als High-Level-Version von run_in_executor(), die direkt Schlüsselwortargumente entgegennehmen kann. (Beigetragen von Kyle Stanley und Yury Selivanov in bpo-32309.)

Beim Abbrechen der Aufgabe aufgrund eines Timeouts wartet asyncio.wait_for() nun auch dann, bis die Abbrechung abgeschlossen ist, wenn timeout <= 0 ist, wie es bei positiven Timeouts der Fall ist. (Beigetragen von Elvis Pranskevichus in bpo-32751.)

asyncio wirft nun TypeError, wenn inkompatible Methoden mit einem ssl.SSLSocket-Socket aufgerufen werden. (Beigetragen von Ido Michael in bpo-37404.)

compileall

Neue Möglichkeit zur Verwendung von Hardlinks für duplizierte .pyc-Dateien hinzugefügt: Parameter hardlink_dupes und Kommandozeilenoption –hardlink-dupes. (Beigetragen von Lumír ‘Frenzy’ Balhar in bpo-40495.)

Neue Optionen für die Pfadmanipulation in resultierenden .pyc-Dateien hinzugefügt: Parameter stripdir, prependdir, limit_sl_dest und Kommandozeilenoptionen -s, -p, -e. Die Möglichkeit hinzugefügt, die Option für einen Optimierungsgrad mehrmals anzugeben. (Beigetragen von Lumír ‘Frenzy’ Balhar in bpo-38112.)

concurrent.futures

Neuer Parameter cancel_futures zu concurrent.futures.Executor.shutdown() hinzugefügt, der alle ausstehenden Futures abbricht, die noch nicht ausgeführt wurden, anstatt auf deren Abschluss zu warten, bevor der Executor heruntergefahren wird. (Beigetragen von Kyle Stanley in bpo-39349.)

Daemon-Threads aus ThreadPoolExecutor und ProcessPoolExecutor entfernt. Dies verbessert die Kompatibilität mit Subinterpretern und die Vorhersagbarkeit bei deren Herunterfahrprozessen. (Beigetragen von Kyle Stanley in bpo-39812.)

Worker in ProcessPoolExecutor werden nun bei Bedarf gestartet, nur wenn keine verfügbaren Idle-Worker wiederverwendet werden können. Dies optimiert den Startaufwand und reduziert die Menge an verlorener CPU-Zeit durch Idle-Worker. (Beigetragen von Kyle Stanley in bpo-39207.)

curses

Hinzugefügt wurden die Funktionen curses.get_escdelay(), curses.set_escdelay(), curses.get_tabsize() und curses.set_tabsize(). (Beigetragen von Anthony Sottile in bpo-38312.)

datetime

Die Methoden isocalendar() von datetime.date und isocalendar() von datetime.datetime geben jetzt ein namedtuple() anstelle eines tuple zurück. (Beigetragen von Donghee Na in bpo-24416.)

distutils

Der Befehl upload erstellt jetzt SHA2-256- und Blake2b-256-Hash-Digests. MD5 wird auf Plattformen übersprungen, die MD5-Digests blockieren. (Beigetragen von Christian Heimes in bpo-40698.)

fcntl

Konstanten fcntl.F_OFD_GETLK, fcntl.F_OFD_SETLK und fcntl.F_OFD_SETLKW hinzugefügt. (Beigetragen von Donghee Na in bpo-38602.)

ftplib

FTP und FTP_TLS lösen jetzt einen ValueError aus, wenn der angegebene Timeout für ihren Konstruktor Null ist, um die Erstellung eines nicht-blockierenden Sockets zu verhindern. (Beigetragen von Donghee Na in bpo-39259.)

gc

Wenn der Garbage Collector eine Sammlung durchführt, bei der einige Objekte wiederbelebt werden (sie sind nach der Ausführung der Finalisierer von außerhalb der isolierten Zyklen erreichbar), wird die Sammlung aller noch unerreichbaren Objekte nicht blockiert. (Beigetragen von Pablo Galindo und Tim Peters in bpo-38379.)

Eine neue Funktion gc.is_finalized() wurde hinzugefügt, um zu überprüfen, ob ein Objekt vom Garbage Collector finalisiert wurde. (Beigetragen von Pablo Galindo in bpo-39322.)

hashlib

Das Modul hashlib kann jetzt SHA3-Hashes und SHAKE XOF von OpenSSL verwenden, wenn verfügbar. (Beigetragen von Christian Heimes in bpo-37630.)

Integrierte Hash-Module können jetzt mit ./configure --without-builtin-hashlib-hashes deaktiviert oder selektiv mit z. B. ./configure --with-builtin-hashlib-hashes=sha3,blake2 aktiviert werden, um die Verwendung der OpenSSL-basierten Implementierung zu erzwingen. (Beigetragen von Christian Heimes in bpo-40479)

http

HTTP-Statuscodes 103 EARLY_HINTS, 418 IM_A_TEAPOT und 425 TOO_EARLY werden zu http.HTTPStatus hinzugefügt. (Beigetragen von Donghee Na in bpo-39509 und Ross Rhodes in bpo-39507.)

IDLE und idlelib

Option zum Abschalten des Cursor-Blinkens hinzugefügt. (Beigetragen von Zackery Spytz in bpo-4603.)

Die Escape-Taste schließt jetzt die IDLE-Vervollständigungsfenster. (Beigetragen von Johnny Najera in bpo-38944.)

Schlüsselwörter zur Liste der Modulnamen-Vervollständigung hinzugefügt. (Beigetragen von Terry J. Reedy in bpo-37765.)

Neu in den 3.9 Wartungsversionen

IDLE ruft jetzt sys.excepthook() auf (wenn ohne '-n' gestartet). Benutzerdefinierte Hooks wurden zuvor ignoriert. (Beigetragen von Ken Hilton in bpo-43008.)

Die obigen Änderungen wurden in die 3.8 Wartungsversionen zurückportiert.

Das Einstellungsdialogfeld neu angeordnet. Die Registerkarte "Allgemein" wurde in die Registerkarten "Fenster" und "Shell/Editor" aufgeteilt. Hilfequellen, die das Hilfemenü erweitern, wurden auf die Registerkarte "Erweiterungen" verschoben. Platz für neue Optionen geschaffen und den Dialog verkürzt. Letzteres sorgt dafür, dass der Dialog besser auf kleine Bildschirme passt. (Beigetragen von Terry Jan Reedy in bpo-40468.) Die Einstellung für Einrückungsabstände wurde von der Registerkarte "Schriftart" auf die neue Registerkarte "Fenster" verschoben. (Beigetragen von Mark Roseman und Terry Jan Reedy in bpo-33962.)

Syntaxhervorhebung für .pyi-Dateien angewendet. (Beigetragen von Alex Waygood und Terry Jan Reedy in bpo-45447.)

imaplib

IMAP4 und IMAP4_SSL verfügen jetzt über einen optionalen Parameter timeout für ihre Konstruktoren. Außerdem verfügt die Methode open() mit dieser Änderung ebenfalls über einen optionalen Parameter timeout. Die überschriebenen Methoden von IMAP4_SSL und IMAP4_stream wurden auf diese Änderung angewendet. (Beigetragen von Donghee Na in bpo-38615.)

imaplib.IMAP4.unselect() wird hinzugefügt. imaplib.IMAP4.unselect() gibt die vom Server zugewiesenen Ressourcen für die ausgewählte Mailbox frei und versetzt den Server in den authentifizierten Zustand zurück. Dieser Befehl führt die gleichen Aktionen wie imaplib.IMAP4.close() aus, mit der Ausnahme, dass keine Nachrichten dauerhaft aus der aktuell ausgewählten Mailbox entfernt werden. (Beigetragen von Donghee Na in bpo-40375.)

importlib

Zur Verbesserung der Konsistenz mit Importanweisungen löst importlib.util.resolve_name() jetzt ImportError anstelle von ValueError für ungültige relative Importversuche aus. (Beigetragen von Ngalim Siregar in bpo-37444.)

Import-Loader, die unveränderliche Modulobjekte veröffentlichen, können jetzt zusätzlich zu einzelnen Modulen auch unveränderliche Pakete veröffentlichen. (Beigetragen von Dino Viehland in bpo-39336.)

Die Funktion importlib.resources.files() mit Unterstützung für Unterverzeichnisse in Paketdaten wurde hinzugefügt, passend zum Backport in importlib_resources Version 1.5. (Beigetragen von Jason R. Coombs in bpo-39791.)

importlib.metadata wurde von importlib_metadata Version 1.6.1 aktualisiert.

inspect

inspect.BoundArguments.arguments wurde von OrderedDict zu einem regulären dict geändert. (Beigetragen von Inada Naoki in bpo-36350 und bpo-39775.)

ipaddress

ipaddress unterstützt jetzt IPv6 Scoped Addresses (IPv6-Adressen mit Suffix %<scope_id>).

Mit ipaddress.IPv6Address können mit Scope versehene IPv6-Adressen geparst werden. Wenn vorhanden, ist die Scope-Zonen-ID über das Attribut scope_id verfügbar. (Beigetragen von Oleksandr Pavliuk in bpo-34788.)

Ab Python 3.9.5 akzeptiert das Modul ipaddress keine führenden Nullen mehr in IPv4-Adressstrings. (Beigetragen von Christian Heimes in bpo-36384).

math

Die Funktion math.gcd() wurde erweitert, um mehrere Argumente zu verarbeiten. Zuvor wurden nur zwei Argumente unterstützt. (Beigetragen von Serhiy Storchaka in bpo-39648.)

Hinzugefügt wurde math.lcm(): gibt das kleinste gemeinsame Vielfache der angegebenen Argumente zurück. (Beigetragen von Mark Dickinson, Ananthakrishnan und Serhiy Storchaka in bpo-39479 und bpo-39648.)

Hinzugefügt wurde math.nextafter(): gibt den nächsten Gleitkommawert nach x in Richtung y zurück. (Beigetragen von Victor Stinner in bpo-39288.)

Hinzugefügt wurde math.ulp(): gibt den Wert des am wenigsten signifikanten Bits einer Gleitkommazahl zurück. (Beigetragen von Victor Stinner in bpo-39310.)

multiprocessing

Die Klasse multiprocessing.SimpleQueue hat eine neue Methode close() zum expliziten Schließen der Warteschlange. (Beigetragen von Victor Stinner in bpo-30966.)

nntplib

NNTP und NNTP_SSL lösen jetzt einen ValueError aus, wenn der angegebene Timeout für ihren Konstruktor Null ist, um die Erstellung eines nicht-blockierenden Sockets zu verhindern. (Beigetragen von Donghee Na in bpo-39259.)

os

Konstanten CLD_KILLED und CLD_STOPPED für si_code hinzugefügt. (Beigetragen von Donghee Na in bpo-38493.)

Die Linux-spezifischen Funktionen os.pidfd_open() (bpo-38692) und os.P_PIDFD (bpo-38713) für die Prozessverwaltung mit File-Deskriptoren wurden verfügbar gemacht.

Die Funktion os.unsetenv() ist jetzt auch unter Windows verfügbar. (Beigetragen von Victor Stinner in bpo-39413.)

Die Funktionen os.putenv() und os.unsetenv() sind jetzt immer verfügbar. (Beigetragen von Victor Stinner in bpo-39395.)

Hinzugefügt wurde die Funktion os.waitstatus_to_exitcode(): Konvertiert einen Warte-Status in einen Exit-Code. (Beigetragen von Victor Stinner in bpo-40094.)

pathlib

Hinzugefügt wurde pathlib.Path.readlink(), das ähnlich wie os.readlink() funktioniert. (Beigetragen von Girts Folkmanis in bpo-30618)

pdb

Unter Windows unterstützt pdb.Pdb jetzt ~/.pdbrc. (Beigetragen von Tim Hopper und Dan Lidral-Porter in bpo-20523.)

poplib

POP3 und POP3_SSL lösen jetzt einen ValueError aus, wenn der angegebene Timeout für ihren Konstruktor Null ist, um die Erstellung eines nicht-blockierenden Sockets zu verhindern. (Beigetragen von Donghee Na in bpo-39259.)

pprint

Das Modul pprint kann jetzt types.SimpleNamespace schön drucken. (Beigetragen von Carl Bordum Hansen in bpo-37376.)

pydoc

Der Dokumentationsstring wird jetzt nicht nur für Klassen, Funktionen, Methoden usw. angezeigt, sondern für jedes Objekt, das ein eigenes __doc__-Attribut hat. (Beigetragen von Serhiy Storchaka in bpo-40257.)

random

Eine neue Methode random.Random.randbytes() wurde hinzugefügt: generiert zufällige Bytes. (Beigetragen von Victor Stinner in bpo-40286.)

signal

Die Linux-spezifische Funktion signal.pidfd_send_signal() wurde verfügbar gemacht, um Signale an einen Prozess über einen File-Deskriptor anstelle einer PID zu senden. (bpo-38712)

smtplib

SMTP und SMTP_SSL lösen jetzt einen ValueError aus, wenn der angegebene Timeout für ihren Konstruktor Null ist, um die Erstellung eines nicht-blockierenden Sockets zu verhindern. (Beigetragen von Donghee Na in bpo-39259.)

Der Konstruktor von LMTP hat jetzt einen optionalen Parameter timeout. (Beigetragen von Donghee Na in bpo-39329.)

socket

Das Modul socket exportiert jetzt die Konstante CAN_RAW_JOIN_FILTERS unter Linux 4.1 und neuer. (Beigetragen von Stefan Tatschner und Zackery Spytz in bpo-25780.)

Das Socket-Modul unterstützt jetzt das Protokoll CAN_J1939 auf Plattformen, die es unterstützen. (Beigetragen von Karl Ding in bpo-40291.)

Das Socket-Modul verfügt jetzt über die Funktionen socket.send_fds() und socket.recv_fds(). (Beigetragen von Joannah Nanjekye, Shinya Okano und Victor Stinner in bpo-28724.)

time

Unter AIX wird thread_time() jetzt mit thread_cputime() mit Nanosekundenauflösung implementiert, anstelle von clock_gettime(CLOCK_THREAD_CPUTIME_ID), das eine Auflösung von 10 Millisekunden hat. (Beigetragen von Batuhan Taskaya in bpo-40192)

sys

Ein neues Attribut sys.platlibdir wurde hinzugefügt: Name des plattformspezifischen Bibliotheksverzeichnisses. Es wird zum Erstellen des Pfads der Standardbibliothek und der Pfade installierter Erweiterungsmodule verwendet. Auf den meisten Plattformen ist es gleich "lib". Auf Fedora und SuSE ist es auf 64-Bit-Plattformen gleich "lib64". (Beigetragen von Jan Matějek, Matěj Cepl, Charalampos Stratakis und Victor Stinner in bpo-1294959.)

Zuvor war sys.stderr im nicht-interaktiven Modus Block-gepuffert. Jetzt ist stderr standardmäßig immer Zeilen-gepuffert. (Beigetragen von Jendrik Seipp in bpo-13601.)

tracemalloc

Hinzugefügt wurde tracemalloc.reset_peak(), um die Spitzen-Speichergröße von nachverfolgten Speicherblöcken auf die aktuelle Größe zu setzen, um die Spitzenlast bestimmter Codeabschnitte zu messen. (Beigetragen von Huon Wilson in bpo-40630.)

typing

PEP 593 führte einen typing.Annotated-Typ ein, um bestehende Typen mit kontextspezifischen Metadaten zu dekorieren, und einen neuen Parameter include_extras für typing.get_type_hints(), um zur Laufzeit auf die Metadaten zuzugreifen. (Beigetragen von Till Varoquaux und Konstantin Kashin.)

unicodedata

Die Unicode-Datenbank wurde auf Version 13.0.0 aktualisiert. (bpo-39926).

venv

Die von venv bereitgestellten Aktivierungsskripte geben ihre Prompt-Anpassung jetzt konsistent an, indem sie immer den von __VENV_PROMPT__ angegebenen Wert verwenden. Zuvor verwendeten einige Skripte bedingungslos __VENV_PROMPT__, andere nur, wenn es zufällig gesetzt war (was der Standardfall war), und eines verwendete stattdessen __VENV_NAME__. (Beigetragen von Brett Cannon in bpo-37663.)

xml

Leerzeichen in Attributen werden jetzt beim Serialisieren von xml.etree.ElementTree nach XML beibehalten. Zeilenumbrüche werden nicht mehr zu “n” normalisiert. Dies ist das Ergebnis einer Diskussion darüber, wie Abschnitt 2.11 der XML-Spezifikation zu interpretieren ist. (Beigetragen von Mefistotelis in bpo-39011.)

Optimierungen

  • Optimiertes Idiom für die Zuweisung einer temporären Variablen in Comprehensions. Jetzt ist for y in [expr] in Comprehensions so schnell wie eine einfache Zuweisung y = expr. Zum Beispiel

    sums = [s for s in [0] for x in data for s in [s + x]]

    Im Gegensatz zum Operator := leckt dieses Idiom keine Variable in den äußeren Geltungsbereich.

    (Beigetragen von Serhiy Storchaka in bpo-32856.)

  • Optimierte Signalbehandlung in multithreaded Anwendungen. Wenn ein Thread, der nicht der Haupt-Thread ist, ein Signal erhält, wird die Bytecode-Evaluierungsschleife nicht mehr bei jeder Bytecode-Instruktion unterbrochen, um auf ausstehende Signale zu prüfen, die nicht behandelt werden können. Nur der Haupt-Thread des Hauptinterpreters kann Signale behandeln.

    Zuvor wurde die Bytecode-Evaluierungsschleife bei jeder Instruktion unterbrochen, bis der Haupt-Thread Signale behandelt. (Beigetragen von Victor Stinner in bpo-40010.)

  • Optimiertes Modul subprocess unter FreeBSD mit closefrom(). (Beigetragen von Ed Maste, Conrad Meyer, Kyle Evans, Kubilay Kocak und Victor Stinner in bpo-38061.)

  • PyLong_FromDouble() ist jetzt bis zu 1,87x schneller für Werte, die in einen long passen. (Beigetragen von Sergey Fedoseev in bpo-37986.)

  • Eine Reihe von Python-Builtins (range, tuple, set, frozenset, list, dict) wurden nun durch die Verwendung des PEP 590 Vectorcall-Protokolls beschleunigt. (Beigetragen von Donghee Na, Mark Shannon, Jeroen Demeyer und Petr Viktorin in bpo-37207.)

  • Optimiertes set.difference_update() für den Fall, dass das andere Set viel größer ist als das Basis-Set. (Vorgeschlagen von Evgeny Kapun mit Code von Michele Orrù in bpo-8425.)

  • Der Small Object Allocator von Python (obmalloc.c) lässt nun zu (nicht mehr als) eine leere Arena für die sofortige Wiederverwendung verfügbar zu halten, ohne sie an das Betriebssystem zurückzugeben. Dies verhindert Thrashing in einfachen Schleifen, bei denen eine Arena bei jeder Iteration neu erstellt und zerstört werden konnte. (Beigetragen von Tim Peters in bpo-37257.)

  • Die Ganzzahldivision (floor division) von Fließkommaoperationen ist nun performanter. Auch die Meldung von ZeroDivisionError für diese Operation wurde aktualisiert. (Beigetragen von Donghee Na in bpo-39434.)

  • Das Dekodieren kurzer ASCII-Strings mit UTF-8 und ASCII-Codecs ist nun etwa 15 % schneller. (Beigetragen von Inada Naoki in bpo-37348.)

Hier ist eine Zusammenfassung der Leistungsverbesserungen von Python 3.4 bis 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    3.9
    read_nonlocal                    7.1     8.1     5.8     5.4     4.4    4.5
    read_global                     15.5    19.0    14.3    13.6     7.6    7.8
    read_builtin                    21.1    21.6    18.5    19.0     7.5    7.8
    read_classvar_from_class        25.6    26.5    20.7    19.5    18.4   17.9
    read_classvar_from_instance     22.8    23.5    18.8    17.1    16.4   16.9
    read_instancevar                32.4    33.1    28.0    26.3    25.4   25.3
    read_instancevar_slots          27.8    31.3    20.8    20.8    20.2   20.5
    read_namedtuple                 73.8    57.5    45.0    46.8    18.4   18.7
    read_boundmethod                37.6    37.9    29.6    26.9    27.7   41.1

Variable and attribute write access:
    write_local                      8.7     9.3     5.5     5.3     4.3    4.3
    write_nonlocal                  10.5    11.1     5.6     5.5     4.7    4.8
    write_global                    19.7    21.2    18.0    18.0    15.8   16.7
    write_classvar                  92.9    96.0   104.6   102.1    39.2   39.8
    write_instancevar               44.6    45.8    40.0    38.9    35.5   37.4
    write_instancevar_slots         35.6    36.1    27.3    26.6    25.7   25.8

Data structure read access:
    read_list                       24.2    24.5    20.8    20.8    19.0   19.5
    read_deque                      24.7    25.5    20.2    20.6    19.8   20.2
    read_dict                       24.3    25.7    22.3    23.0    21.0   22.4
    read_strdict                    22.6    24.3    19.5    21.2    18.9   21.5

Data structure write access:
    write_list                      27.1    28.5    22.5    21.6    20.0   20.0
    write_deque                     28.7    30.1    22.7    21.8    23.5   21.7
    write_dict                      31.4    33.3    29.3    29.2    24.7   25.4
    write_strdict                   28.4    29.9    27.5    25.2    23.1   24.5

Stack (or queue) operations:
    list_append_pop                 93.4   112.7    75.4    74.2    50.8   50.6
    deque_append_pop                43.5    57.0    49.4    49.2    42.5   44.2
    deque_append_popleft            43.7    57.3    49.7    49.7    42.8   46.4

Timing loop:
    loop_overhead                    0.5     0.6     0.4     0.3     0.3    0.3

Diese Ergebnisse wurden mit dem Benchmark-Skript für Variablenzugriffe unter: Tools/scripts/var_access_benchmark.py generiert. Das Benchmark-Skript zeigt Zeitmessungen in Nanosekunden an. Die Benchmarks wurden auf einem Intel® Core™ i7-4960HQ Prozessor unter Verwendung von macOS 64-Bit-Builds von python.org gemessen.

Veraltet

  • Der `distutils` Befehl `bdist_msi` ist nun veraltet; verwenden Sie stattdessen `bdist_wheel` (Wheel-Pakete). (Beigetragen von Hugo van Kemenade in bpo-39586.)

  • Derzeit akzeptiert math.factorial() `float`-Instanzen mit nicht-negativen ganzzahligen Werten (wie 5.0). Es löst eine ValueError für nicht-ganzzahlige und negative Fließkommazahlen aus. Dies ist nun veraltet. In zukünftigen Python-Versionen wird es eine TypeError für alle Fließkommazahlen auslösen. (Beigetragen von Serhiy Storchaka in bpo-37315.)

  • Die Module parser und symbol sind veraltet und werden in zukünftigen Python-Versionen entfernt. Für die Mehrheit der Anwendungsfälle können Benutzer die Generierung und Kompilierung von Abstract Syntax Trees (AST) mithilfe des Moduls ast nutzen.

  • Die öffentlichen C-API-Funktionen PyParser_SimpleParseStringFlags(), PyParser_SimpleParseStringFlagsFilename(), PyParser_SimpleParseFileFlags() und PyNode_Compile() sind veraltet und werden in Python 3.10 zusammen mit dem alten Parser entfernt.

  • Die Verwendung von NotImplemented in einem booleschen Kontext ist veraltet, da dies fast ausschließlich das Ergebnis falscher Implementierungen von Rich Comparatoren ist. Es wird in einer zukünftigen Python-Version zu einer TypeError werden. (Beigetragen von Josh Rosenberg in bpo-35712.)

  • Das Modul random akzeptiert derzeit jeden hashbaren Typ als möglichen Seed-Wert. Leider ist für einige dieser Typen kein deterministischer Hash-Wert garantiert. Nach Python 3.9 wird das Modul seine Seeds auf None, int, float, str, bytes und bytearray beschränken.

  • Das Öffnen der Datei GzipFile zum Schreiben, ohne das Argument `mode` anzugeben, ist veraltet. In zukünftigen Python-Versionen wird sie standardmäßig zum Lesen geöffnet. Geben Sie das Argument `mode` an, um sie zum Schreiben zu öffnen und eine Warnung zu unterdrücken. (Beigetragen von Serhiy Storchaka in bpo-28286.)

  • Die Methode `split()` von `_tkinter.TkappType` ist veraltet zugunsten der Methode `splitlist()`, die ein konsistenteres und vorhersagbareres Verhalten aufweist. (Beigetragen von Serhiy Storchaka in bpo-38371.)

  • Das explizite Übergeben von Coroutine-Objekten an asyncio.wait() ist veraltet und wird in Version 3.11 entfernt. (Beigetragen von Yury Selivanov und Kyle Stanley in bpo-34790.)

  • Die Standards binhex4 und hexbin4 sind nun veraltet. Das Modul binhex und die folgenden Funktionen des Moduls binascii sind nun veraltet:

    • b2a_hqx(), a2b_hqx()

    • rlecode_hqx(), rledecode_hqx()

    (Beigetragen von Victor Stinner in bpo-39353.)

  • Die `ast`-Klassen slice, Index und ExtSlice gelten als veraltet und werden in zukünftigen Python-Versionen entfernt. value sollte selbst anstelle von Index(value) verwendet werden. Tuple(slices, Load()) sollte anstelle von ExtSlice(slices) verwendet werden. (Beigetragen von Serhiy Storchaka in bpo-34822.)

  • Die `ast`-Klassen Suite, Param, AugLoad und AugStore gelten als veraltet und werden in zukünftigen Python-Versionen entfernt. Sie wurden im Parser nicht generiert und vom Code-Generator in Python 3 nicht akzeptiert. (Beigetragen von Batuhan Taskaya in bpo-39639 und bpo-39969 und Serhiy Storchaka in bpo-39988.)

  • Die C-Funktionen PyEval_InitThreads() und PyEval_ThreadsInitialized() sind nun veraltet und werden in Python 3.11 entfernt. Der Aufruf von PyEval_InitThreads() bewirkt nun nichts mehr. Der GIL wird seit Python 3.7 von Py_Initialize() initialisiert. (Beigetragen von Victor Stinner in bpo-39877.)

  • Das Übergeben von None als erstes Argument an die Funktion shlex.split() ist veraltet. (Beigetragen von Zackery Spytz in bpo-33262.)

  • smtpd.MailmanProxy() ist nun veraltet, da es ohne ein externes Modul, mailman, unbrauchbar ist. (Beigetragen von Samuel Colvin in bpo-35800.)

  • Das Modul lib2to3 gibt nun eine PendingDeprecationWarning aus. Python 3.9 wechselte zu einem PEG-Parser (siehe PEP 617) und Python 3.10 kann neuen Syntax enthalten, der mit dem LL(1)-Parser von lib2to3 nicht verarbeitbar ist. Das Modul lib2to3 kann in zukünftigen Python-Versionen aus der Standardbibliothek entfernt werden. Erwägen Sie Alternativen von Drittanbietern wie LibCST oder parso. (Beigetragen von Carl Meyer in bpo-40360.)

  • Der Parameter `random` von random.shuffle() ist veraltet. (Beigetragen von Raymond Hettinger in bpo-40465)

Entfernt

  • Die fehlerhafte Version unter unittest.mock.__version__ wurde entfernt.

  • nntplib.NNTP: Die Methoden xpath() und xgtitle() wurden entfernt. Diese Methoden sind seit Python 3.3 veraltet. Im Allgemeinen werden diese Erweiterungen von NNTP-Serveradministratoren nicht unterstützt oder nicht aktiviert. Für xgtitle() verwenden Sie stattdessen bitte nntplib.NNTP.descriptions() oder nntplib.NNTP.description(). (Beigetragen von Donghee Na in bpo-39366.)

  • array.array: Die Methoden tostring() und fromstring() wurden entfernt. Sie waren Aliase für tobytes() und frombytes(), die seit Python 3.2 veraltet sind. (Beigetragen von Victor Stinner in bpo-38916.)

  • Die undokumentierte Funktion sys.callstats() wurde entfernt. Seit Python 3.7 war sie veraltet und gab immer None zurück. Sie erforderte eine spezielle Build-Option CALL_PROFILE, die bereits in Python 3.7 entfernt wurde. (Beigetragen von Victor Stinner in bpo-37414.)

  • Die Funktionen sys.getcheckinterval() und sys.setcheckinterval() wurden entfernt. Sie waren seit Python 3.2 veraltet. Verwenden Sie stattdessen sys.getswitchinterval() und sys.setswitchinterval(). (Beigetragen von Victor Stinner in bpo-37392.)

  • Die C-Funktion PyImport_Cleanup() wurde entfernt. Sie war dokumentiert als: „Leeren Sie die Modultabelle. Nur für interne Verwendung.“ (Beigetragen von Victor Stinner in bpo-36710.)

  • Die Module _dummy_thread und dummy_threading wurden entfernt. Diese Module waren seit Python 3.7 veraltet, da sie eine Threading-Unterstützung erfordern. (Beigetragen von Victor Stinner in bpo-37312.)

  • Die Aliase aifc.openfp() zu aifc.open(), sunau.openfp() zu sunau.open() und wave.openfp() zu wave.open() wurden entfernt. Sie waren seit Python 3.7 veraltet. (Beigetragen von Victor Stinner in bpo-37320.)

  • Die Methode isAlive() von threading.Thread wurde entfernt. Sie war seit Python 3.8 veraltet. Verwenden Sie stattdessen is_alive(). (Beigetragen von Donghee Na in bpo-37804.)

  • Die Methoden getchildren() und getiterator() der Klassen ElementTree und Element im Modul ElementTree wurden entfernt. Sie waren seit Python 3.2 veraltet. Verwenden Sie iter(x) oder list(x) anstelle von x.getchildren() und x.iter() oder list(x.iter()) anstelle von x.getiterator(). (Beigetragen von Serhiy Storchaka in bpo-36543.)

  • Die alte API von plistlib wurde entfernt; sie war seit Python 3.4 veraltet. Verwenden Sie stattdessen die Funktionen load(), loads(), dump() und dumps(). Zusätzlich wurde der Parameter `use_builtin_types` entfernt; stattdessen werden immer Standard-Objekte bytes verwendet. (Beigetragen von Jon Janzen in bpo-36409.)

  • Die C-Funktion PyGen_NeedsFinalizing wurde entfernt. Sie war nicht dokumentiert, getestet oder irgendwo in CPython nach der Implementierung von PEP 442 verwendet worden. Patch von Joannah Nanjekye. (Beigetragen von Joannah Nanjekye in bpo-15088)

  • base64.encodestring() und base64.decodestring(), Aliase, die seit Python 3.1 veraltet sind, wurden entfernt: verwenden Sie stattdessen base64.encodebytes() und base64.decodebytes(). (Beigetragen von Victor Stinner in bpo-39351.)

  • Die Funktion fractions.gcd() wurde entfernt; sie war seit Python 3.5 veraltet (bpo-22486): verwenden Sie stattdessen math.gcd(). (Beigetragen von Victor Stinner in bpo-39350.)

  • Der Parameter `buffering` von bz2.BZ2File wurde entfernt. Seit Python 3.0 wurde er ignoriert und seine Verwendung löste eine DeprecationWarning aus. Übergeben Sie ein geöffnetes Dateiobjekt, um zu steuern, wie die Datei geöffnet wird. (Beigetragen von Victor Stinner in bpo-39357.)

  • Der Parameter `encoding` von json.loads() wurde entfernt. Ab Python 3.1 war er veraltet und wurde ignoriert; seine Verwendung löste seit Python 3.8 eine DeprecationWarning aus. (Beigetragen von Inada Naoki in bpo-39377)

  • Die Anweisungen with (await asyncio.lock): und with (yield from asyncio.lock): werden nicht mehr unterstützt, verwenden Sie stattdessen async with lock. Dasselbe gilt für asyncio.Condition und asyncio.Semaphore. (Beigetragen von Andrew Svetlov in bpo-34793.)

  • Die Funktion sys.getcounts(), die Kommandozeilenoption -X showalloccount und das Feld show_alloc_count der C-Struktur PyConfig wurden entfernt. Sie erforderten einen speziellen Python-Build durch Definition des Makros COUNT_ALLOCS. (Beigetragen von Victor Stinner in bpo-39489.)

  • Das Attribut `_field_types` der Klasse typing.NamedTuple wurde entfernt. Es war seit Python 3.8 veraltet. Verwenden Sie stattdessen das Attribut `__annotations__`. (Beigetragen von Serhiy Storchaka in bpo-40182.)

  • Die Methode symtable.SymbolTable.has_exec() wurde entfernt. Sie war seit 2006 veraltet und gab nur False zurück, wenn sie aufgerufen wurde. (Beigetragen von Batuhan Taskaya in bpo-40208)

  • Die Methoden asyncio.Task.current_task() und asyncio.Task.all_tasks() wurden entfernt. Sie waren seit Python 3.7 veraltet und Sie können stattdessen asyncio.current_task() und asyncio.all_tasks() verwenden. (Beigetragen von Rémi Lapeyre in bpo-40967)

  • Die Methode `unescape()` in der Klasse html.parser.HTMLParser wurde entfernt (sie war seit Python 3.4 veraltet). html.unescape() sollte zur Umwandlung von Zeichenreferenzen in die entsprechenden Unicode-Zeichen verwendet werden.

Portierung nach Python 3.9

Dieser Abschnitt listet zuvor beschriebene Änderungen und weitere Fehlerbehebungen auf, die möglicherweise Änderungen an Ihrem Code erfordern.

Änderungen in der Python-API

  • __import__() und importlib.util.resolve_name() lösen nun ImportError aus, wo zuvor ValueError ausgelöst wurde. Aufrufer, die den spezifischen Ausnahmetyp abfangen und sowohl Python 3.9 als auch frühere Versionen unterstützen, müssen beide mit except (ImportError, ValueError): abfangen.

  • Die Aktivierungsskripte von venv behandeln nun nicht mehr speziell, wenn __VENV_PROMPT__ auf "" gesetzt ist.

  • Die Methode select.epoll.unregister() ignoriert nun nicht mehr den Fehler EBADF. (Beigetragen von Victor Stinner in bpo-39239.)

  • Der Parameter `compresslevel` von bz2.BZ2File wurde zu einem nur-Schlüsselwort-Parameter, da der Parameter `buffering` entfernt wurde. (Beigetragen von Victor Stinner in bpo-39357.)

  • Vereinfachtes AST für Subskriptionen. Einfache Indizes werden durch ihren Wert repräsentiert, erweiterte Slices werden als Tupel dargestellt. Index(value) gibt den value selbst zurück, ExtSlice(slices) gibt Tuple(slices, Load()) zurück. (Beigetragen von Serhiy Storchaka in bpo-34822.)

  • Das Modul importlib ignoriert nun die Umgebungsvariable PYTHONCASEOK, wenn die Kommandozeilenoptionen -E oder -I verwendet werden.

  • Der Parameter `encoding` wurde zu den Klassen ftplib.FTP und ftplib.FTP_TLS als nur-Schlüsselwort-Parameter hinzugefügt, und die Standardkodierung wurde von Latin-1 auf UTF-8 geändert, um RFC 2640 zu folgen.

  • asyncio.loop.shutdown_default_executor() wurde zu AbstractEventLoop hinzugefügt. Das bedeutet, dass alternative Event-Loops, die von ihm erben, diese Methode definieren sollten. (Beigetragen von Kyle Stanley in bpo-34037.)

  • Die konstanten Werte der zukünftigen Flags im Modul __future__ wurden aktualisiert, um Kollisionen mit Compiler-Flags zu vermeiden. Zuvor kollidierte PyCF_ALLOW_TOP_LEVEL_AWAIT mit CO_FUTURE_DIVISION. (Beigetragen von Batuhan Taskaya in bpo-39562)

  • array('u') verwendet nun wchar_t als C-Typ anstelle von Py_UNICODE. Diese Änderung wirkt sich nicht auf das Verhalten aus, da Py_UNICODE seit Python 3.3 ein Alias für wchar_t ist. (Beigetragen von Inada Naoki in bpo-34538.)

  • Die API logging.getLogger() gibt nun den Root-Logger zurück, wenn der Name 'root' übergeben wird. Zuvor gab sie einen Nicht-Root-Logger namens 'root' zurück. Dies könnte Fälle beeinträchtigen, in denen Benutzercode explizit einen Nicht-Root-Logger namens 'root' wünscht oder einen Logger mit logging.getLogger(__name__) in einem Top-Level-Modul namens 'root.py' instanziiert. (Beigetragen von Vinay Sajip in bpo-37742.)

  • Die Divisionsbehandlung von PurePath gibt nun NotImplemented zurück, anstatt eine TypeError auszulösen, wenn etwas anderes als eine Instanz von str oder PurePath übergeben wird. Dies ermöglicht die Erstellung kompatibler Klassen, die nicht von den genannten Typen erben. (Beigetragen von Roger Aiudi in bpo-34775).

  • Ab Python 3.9.5 akzeptiert das ipaddress-Modul keine führenden Nullen mehr in IPv4-Adressstrings. Führende Nullen sind mehrdeutig und werden von einigen Bibliotheken als Oktalnotation interpretiert. Beispielsweise behandelt die Legacy-Funktion socket.inet_aton() führende Nullen als Oktalnotation. Die glibc-Implementierung von modernem inet_pton() akzeptiert keine führenden Nullen. (Beigetragen von Christian Heimes in bpo-36384).

  • codecs.lookup() normalisiert den Kodierungsnamen nun auf die gleiche Weise wie encodings.normalize_encoding(), mit der Ausnahme, dass codecs.lookup() den Namen auch in Kleinbuchstaben umwandelt. Zum Beispiel wird der kodierungsname "latex+latin1" jetzt zu "latex_latin1" normalisiert. (Beigetragen von Jordon Xu in bpo-37751.)

Änderungen in der C-API

  • Instanzen von Heap-allozierte Typen (wie solche, die mit PyType_FromSpec() und ähnlichen APIs erstellt wurden) halten seit Python 3.8 eine Referenz auf ihr Typobjekt. Wie in den "Änderungen in der C-API" von Python 3.8 angegeben, sollte dies in den allermeisten Fällen keine Nebenwirkungen haben, aber für Typen mit einer benutzerdefinierten tp_traverse-Funktion ist sicherzustellen, dass alle benutzerdefinierten tp_traverse-Funktionen von Heap-alloziierten Typen den Typ des Objekts besuchen.

    Beispiel

    int
    foo_traverse(PyObject *self, visitproc visit, void *arg)
    {
    // Rest of the traverse function
    #if PY_VERSION_HEX >= 0x03090000
        // This was not needed before Python 3.9 (Python issue 35810 and 40217)
        Py_VISIT(Py_TYPE(self));
    #endif
    }
    

    Wenn Ihre Traverse-Funktion an die tp_traverse ihrer Basisklasse (oder eines anderen Typs) delegiert, stellen Sie sicher, dass Py_TYPE(self) nur einmal besucht wird. Beachten Sie, dass nur Heap-Typen vom Besuch des Typs in tp_traverse erwartet werden.

    Wenn Ihre tp_traverse-Funktion beispielsweise Folgendes enthält:

    base->tp_traverse(self, visit, arg)
    

    fügen Sie hinzu:

    #if PY_VERSION_HEX >= 0x03090000
        // This was not needed before Python 3.9 (bpo-35810 and bpo-40217)
        if (base->tp_flags & Py_TPFLAGS_HEAPTYPE) {
            // a heap type's tp_traverse already visited Py_TYPE(self)
        } else {
            Py_VISIT(Py_TYPE(self));
        }
    #else
    

    (Siehe bpo-35810 und bpo-40217 für weitere Informationen.)

  • Die Funktionen PyEval_CallObject, PyEval_CallFunction, PyEval_CallMethod und PyEval_CallObjectWithKeywords sind veraltet. Verwenden Sie stattdessen PyObject_Call() und seine Varianten. (Weitere Details finden Sie in bpo-29548.)

CPython Bytecode-Änderungen

  • Der Opcode LOAD_ASSERTION_ERROR wurde zur Behandlung der assert-Anweisung hinzugefügt. Zuvor funktionierte die assert-Anweisung nicht korrekt, wenn die Ausnahme AssertionError überschattet wurde. (Beigetragen von Zackery Spytz in bpo-34880.)

  • Der Opcode COMPARE_OP wurde in vier separate Anweisungen aufgeteilt:

    • COMPARE_OP für Rich-Vergleiche

    • IS_OP für 'is'- und 'is not'-Tests

    • CONTAINS_OP für 'in'- und 'not in'-Tests

    • JUMP_IF_NOT_EXC_MATCH zur Überprüfung von Ausnahmen in 'try-except'-Anweisungen.

    (Beigetragen von Mark Shannon in bpo-39156.)

Build-Änderungen

  • Die Option --with-platlibdir wurde zum configure-Skript hinzugefügt: Name des plattformspezifischen Bibliotheksverzeichnisses, gespeichert im neuen Attribut sys.platlibdir. Weitere Informationen finden Sie im Attribut sys.platlibdir. (Beigetragen von Jan Matějek, Matěj Cepl, Charalampos Stratakis und Victor Stinner in bpo-1294959.)

  • Das spezielle Build-Makro COUNT_ALLOCS wurde entfernt. (Beigetragen von Victor Stinner in bpo-39489.)

  • Auf Nicht-Windows-Plattformen sind die Funktionen setenv() und unsetenv() nun für den Python-Build erforderlich. (Beigetragen von Victor Stinner in bpo-39395.)

  • Auf Nicht-Windows-Plattformen wird die Erstellung von bdist_wininst-Installern nun offiziell nicht mehr unterstützt. (Weitere Details finden Sie in bpo-10945.)

  • Beim Erstellen von Python auf macOS aus Quellcode verknüpft _tkinter nun mit Nicht-System-Tcl- und Tk-Frameworks, wenn diese in /Library/Frameworks installiert sind, wie es bei älteren macOS-Versionen der Fall war. Wenn ein macOS SDK explizit konfiguriert wird, entweder durch --enable-universalsdk oder -isysroot, wird nur das SDK selbst durchsucht. Das Standardverhalten kann immer noch mit --with-tcltk-includes und --with-tcltk-libs überschrieben werden. (Beigetragen von Ned Deily in bpo-34956.)

  • Python kann nun für Windows 10 ARM64 erstellt werden. (Beigetragen von Steve Dower in bpo-33125.)

  • Einige einzelne Tests werden nun übersprungen, wenn --pgo verwendet wird. Die fraglichen Tests erhöhten die PGO-Task-Zeit erheblich und trugen wahrscheinlich nicht zur Verbesserung der Optimierung der endgültigen ausführbaren Datei bei. Dies beschleunigt den Task um etwa das 15-fache. Das Ausführen der vollständigen Unit-Testsuite ist langsam. Diese Änderung kann zu einem geringfügig weniger optimierten Build führen, da nicht so viele Codezweige ausgeführt werden. Wenn Sie bereit sind, auf den wesentlich langsameren Build zu warten, kann das alte Verhalten mit ./configure [..] PROFILE_TASK="-m test --pgo-extended" wiederhergestellt werden. Wir geben keine Garantie, welche PGO-Task-Satz einen schnelleren Build erzeugt. Benutzer, die dies interessiert, sollten ihre eigenen relevanten Benchmarks ausführen, da die Ergebnisse von der Umgebung, der Arbeitslast und der Compiler-Toolchain abhängen können. (Siehe bpo-36044 und bpo-37707 für weitere Details.)

C-API-Änderungen

Neue Funktionen

  • PEP 573: PyType_FromModuleAndSpec() wurde hinzugefügt, um ein Modul einer Klasse zuzuordnen. PyType_GetModule() und PyType_GetModuleState(), um das Modul und seinen Zustand abzurufen. Und PyCMethod und METH_METHOD, um einer Methode den Zugriff auf die Klasse zu ermöglichen, in der sie definiert wurde. (Beigetragen von Marcel Plch und Petr Viktorin in bpo-38787.)

  • Die Funktion PyFrame_GetCode() wurde hinzugefügt: Abrufen eines Frame-Codes. Die Funktion PyFrame_GetBack() wurde hinzugefügt: Abrufen des nächst äußeren Frames. (Beigetragen von Victor Stinner in bpo-40421.)

  • Die Funktion PyFrame_GetLineNumber() wurde zur begrenzten C-API hinzugefügt. (Beigetragen von Victor Stinner in bpo-40421.)

  • Die Funktionen PyThreadState_GetInterpreter() und PyInterpreterState_Get() wurden hinzugefügt, um den Interpreter abzurufen. Die Funktion PyThreadState_GetFrame() wurde hinzugefügt, um den aktuellen Frame eines Python-Thread-Zustands abzurufen. Die Funktion PyThreadState_GetID() wurde hinzugefügt: Abrufen der eindeutigen ID eines Python-Thread-Zustands. (Beigetragen von Victor Stinner in bpo-39947.)

  • Eine neue öffentliche Funktion PyObject_CallNoArgs() wurde zur C-API hinzugefügt, die ein aufrufbares Python-Objekt ohne Argumente aufruft. Dies ist der effizienteste Weg, ein aufrufbares Python-Objekt ohne Argumente aufzurufen. (Beigetragen von Victor Stinner in bpo-37194.)

  • Änderungen in der begrenzten C-API (wenn das Makro Py_LIMITED_API definiert ist)

    • Py_EnterRecursiveCall() und Py_LeaveRecursiveCall() werden nun als reguläre Funktionen für die begrenzte API bereitgestellt. Zuvor waren sie als Makros definiert, aber diese Makros kompilierten nicht mit der begrenzten C-API, die keinen Zugriff auf das Feld PyThreadState.recursion_depth hat (die Struktur ist in der begrenzten C-API undurchsichtig).

    • PyObject_INIT() und PyObject_INIT_VAR() werden zu regulären "undurchsichtigen" Funktionen, um Implementierungsdetails zu verbergen.

    (Beigetragen von Victor Stinner in bpo-38644 und bpo-39542.)

  • Die Funktion PyModule_AddType() wurde hinzugefügt, um das Hinzufügen eines Typs zu einem Modul zu erleichtern. (Beigetragen von Donghee Na in bpo-40024.)

  • Die Funktionen PyObject_GC_IsTracked() und PyObject_GC_IsFinalized() wurden zur öffentlichen API hinzugefügt, um abzufragen, ob Python-Objekte derzeit vom Garbage Collector verfolgt oder bereits finalisiert wurden. (Beigetragen von Pablo Galindo Salgado in bpo-40241.)

  • _PyObject_FunctionStr() wurde hinzugefügt, um eine benutzerfreundliche String-Darstellung eines funktionsähnlichen Objekts zu erhalten. (Patch von Jeroen Demeyer in bpo-37645.)

  • PyObject_CallOneArg() wurde hinzugefügt, um ein Objekt mit einem positionsbezogenen Argument aufzurufen (Patch von Jeroen Demeyer in bpo-37483.)

Portierung auf Python 3.9

  • PyInterpreterState.eval_frame (PEP 523) erfordert nun einen neuen obligatorischen Parameter tstate (PyThreadState*). (Beigetragen von Victor Stinner in bpo-38500.)

  • Erweiterungsmodule: m_traverse, m_clear und m_free-Funktionen von PyModuleDef werden nicht mehr aufgerufen, wenn der Modulzustand angefordert, aber noch nicht zugewiesen wurde. Dies ist unmittelbar nach der Erstellung des Moduls und vor der Ausführung des Moduls (Py_mod_exec-Funktion) der Fall. Genauer gesagt, diese Funktionen werden nicht aufgerufen, wenn m_size größer als 0 ist und der Modulzustand (wie von PyModule_GetState() zurückgegeben) NULL ist.

    Erweiterungsmodule ohne Modulzustand (m_size <= 0) sind nicht betroffen.

  • Wenn Py_AddPendingCall() in einem Sub-Interpreter aufgerufen wird, wird die Funktion nun so geplant, dass sie vom Sub-Interpreter aufgerufen wird, anstatt vom Haupt-Interpreter aufgerufen zu werden. Jeder Sub-Interpreter hat nun seine eigene Liste geplanter Aufrufe. (Beigetragen von Victor Stinner in bpo-39984.)

  • Die Windows-Registrierung wird nicht mehr verwendet, um sys.path zu initialisieren, wenn die Option -E verwendet wird (wenn PyConfig.use_environment auf 0 gesetzt ist). Dies ist beim Einbetten von Python unter Windows von Bedeutung. (Beigetragen von Zackery Spytz in bpo-8901.)

  • Die globale Variable PyStructSequence_UnnamedField ist nun eine Konstante und verweist auf einen konstanten String. (Beigetragen von Serhiy Storchaka in bpo-38650.)

  • Die PyGC_Head-Struktur ist nun undurchsichtig. Sie ist nur in der internen C-API (pycore_gc.h) definiert. (Beigetragen von Victor Stinner in bpo-40241.)

  • Die Funktionen Py_UNICODE_COPY, Py_UNICODE_FILL, PyUnicode_WSTR_LENGTH, PyUnicode_FromUnicode(), PyUnicode_AsUnicode(), _PyUnicode_AsUnicode und PyUnicode_AsUnicodeAndSize() sind in C als veraltet markiert. Sie sind seit Python 3.3 durch PEP 393 veraltet. (Beigetragen von Inada Naoki in bpo-36346.)

  • Die Funktion Py_FatalError() wird durch ein Makro ersetzt, das automatisch den Namen der aktuellen Funktion protokolliert, es sei denn, das Makro Py_LIMITED_API ist definiert. (Beigetragen von Victor Stinner in bpo-39882.)

  • Das Vectorcall-Protokoll erfordert nun, dass der Aufrufer nur Strings als Schlüsselwortnamen übergibt. (Weitere Informationen finden Sie in bpo-37540.)

  • Implementierungsdetails einer Reihe von Makros und Funktionen sind nun verborgen

    (Siehe bpo-40170 für weitere Details.)

Entfernt

  • Die Makros PyFPE_START_PROTECT() und PyFPE_END_PROTECT() aus pyfpe.h wurden aus der begrenzten C-API ausgeschlossen. (Beigetragen von Victor Stinner in bpo-38835.)

  • Der tp_print-Slot von PyTypeObject wurde entfernt. Er wurde zum Drucken von Objekten in Dateien in Python 2.7 und früher verwendet. Seit Python 3.0 wurde er ignoriert und nicht verwendet. (Beigetragen von Jeroen Demeyer in bpo-36974.)

  • Änderungen in der begrenzten C-API (wenn das Makro Py_LIMITED_API definiert ist)

    • Folgende Funktionen wurden aus der begrenzten C-API ausgeschlossen:

      • PyThreadState_DeleteCurrent() (Beigetragen von Joannah Nanjekye in bpo-37878.)

      • _Py_CheckRecursionLimit

      • _Py_NewReference()

      • _Py_ForgetReference()

      • _PyTraceMalloc_NewReference()

      • _Py_GetRefTotal()

      • Der "Mülleimer"-Mechanismus, der in der begrenzten C-API nie funktionierte.

      • PyTrash_UNWIND_LEVEL

      • Py_TRASHCAN_BEGIN_CONDITION

      • Py_TRASHCAN_BEGIN

      • Py_TRASHCAN_END

      • Py_TRASHCAN_SAFE_BEGIN

      • Py_TRASHCAN_SAFE_END

    • Folgende Funktionen und Definitionen wurden in die interne C-API verschoben:

      • _PyDebug_PrintTotalRefs()

      • _Py_PrintReferences()

      • _Py_PrintReferenceAddresses()

      • _Py_tracemalloc_config

      • _Py_AddToAllObjects() (spezifisch für Py_TRACE_REFS-Build)

    (Beigetragen von Victor Stinner in bpo-38644 und bpo-39542.)

  • Der _PyRuntime.getframe-Hook wurde entfernt und das Makro _PyThreadState_GetFrame, das ein Alias für _PyRuntime.getframe war, wurde ebenfalls entfernt. Sie wurden nur von der internen C-API verfügbar gemacht. Der Typ PyThreadFrameGetter wurde ebenfalls entfernt. (Beigetragen von Victor Stinner in bpo-39946.)

  • Folgende Funktionen wurden aus der C-API entfernt. Rufen Sie PyGC_Collect() explizit auf, um alle Freilisten zu leeren. (Beigetragen von Inada Naoki und Victor Stinner in bpo-37340, bpo-38896 und bpo-40428.)

    • PyAsyncGen_ClearFreeLists()

    • PyContext_ClearFreeList()

    • PyDict_ClearFreeList()

    • PyFloat_ClearFreeList()

    • PyFrame_ClearFreeList()

    • PyList_ClearFreeList()

    • PyMethod_ClearFreeList() und PyCFunction_ClearFreeList(): Die Freilisten von gebundenen Methodenobjekten wurden entfernt.

    • PySet_ClearFreeList(): Die Set-Freiliste wurde in Python 3.4 entfernt.

    • PyTuple_ClearFreeList()

    • PyUnicode_ClearFreeList(): Die Unicode-Freiliste wurde in Python 3.3 entfernt.

  • Die Funktion _PyUnicode_ClearStaticStrings() wurde entfernt. (Beigetragen von Victor Stinner in bpo-39465.)

  • Entfernt Py_UNICODE_MATCH. Es wurde durch PEP 393 veraltet und ist seit Python 3.3 defekt. Die Funktion PyUnicode_Tailmatch() kann stattdessen verwendet werden. (Beigetragen von Inada Naoki in bpo-36346.)

  • Header-Dateien wurden von definierten, aber nicht implementierten Schnittstellen bereinigt. Die entfernten öffentlichen API-Symbole sind: _PyBytes_InsertThousandsGroupingLocale, _PyBytes_InsertThousandsGrouping, _Py_InitializeFromArgs, _Py_InitializeFromWideArgs, _PyFloat_Repr, _PyFloat_Digits, _PyFloat_DigitsInit, PyFrame_ExtendStack, _PyAIterWrapper_Type, PyNullImporter_Type, PyCmpWrapper_Type, PySortWrapper_Type, PyNoArgsFunction. (Beigetragen von Pablo Galindo Salgado in bpo-39372.)

Bemerkenswerte Änderungen in Python 3.9.1

typing

Das Verhalten von typing.Literal wurde geändert, um PEP 586 zu entsprechen und das Verhalten statischer Typenprüfer wie in der PEP angegeben zu entsprechen.

  1. Literal dedupliziert nun Parameter.

  2. Gleichheitsvergleiche zwischen Literal-Objekten sind nun ordnungsunabhängig.

  3. Literal-Vergleiche berücksichtigen nun Typen. Zum Beispiel ergab Literal[0] == Literal[False] zuvor True. Jetzt ist es False. Um diese Änderung zu unterstützen, unterstützt der intern verwendete Typ-Cache nun die Unterscheidung von Typen.

  4. Literal-Objekte lösen nun eine TypeError-Ausnahme bei Gleichheitsvergleichen aus, wenn einer ihrer Parameter nicht hashbar ist. Beachten Sie, dass die Deklaration von Literal mit veränderbaren Parametern keinen Fehler auslöst.

    >>> from typing import Literal
    >>> Literal[{0}]
    >>> Literal[{0}] == Literal[{False}]
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    TypeError: unhashable type: 'set'
    

(Beigetragen von Yurii Karabas in bpo-42345.)

Unterstützung für macOS 11.0 (Big Sur) und Apple Silicon Macs

Ab 3.9.1 unterstützt Python nun vollständig das Erstellen und Ausführen auf macOS 11.0 (Big Sur) und auf Apple Silicon Macs (basierend auf der ARM64-Architektur). Eine neue universelle Build-Variante, universal2, ist nun verfügbar, um sowohl ARM64 als auch Intel 64 nativ in einem Satz ausführbarer Dateien zu unterstützen. Binärdateien können nun auch auf aktuellen macOS-Versionen erstellt werden, um auf einer Reihe älterer macOS-Versionen (getestet bis 10.9) eingesetzt zu werden, wobei einige neuere OS-Funktionen und Optionen zur Laufzeit basierend auf der verwendeten Betriebssystemversion bedingt verfügbar gemacht werden ("weaklinking").

(Beigetragen von Ronald Oussoren und Lawrence D’Anna in bpo-41100.)

Bemerkenswerte Änderungen in Python 3.9.2

collections.abc

collections.abc.Callable ist jetzt generisch und verflacht Typ-Parameter, ähnlich wie typing.Callable derzeit tut. Das bedeutet, dass collections.abc.Callable[[int, str], str] __args__ von (int, str, str) hat; zuvor war dies ([int, str], str). Um diese Änderung zu ermöglichen, kann types.GenericAlias jetzt unterklassen werden, und eine Unterklasse wird zurückgegeben, wenn der Typ collections.abc.Callable mit eckigen Klammern adressiert wird. Code, der über typing.get_args() oder __args__ auf die Argumente zugreift, muss diese Änderung berücksichtigen. Eine DeprecationWarning kann für ungültige Formen der Parametrisierung von collections.abc.Callable ausgegeben werden, die in Python 3.9.1 möglicherweise stillschweigend bestanden haben. Diese DeprecationWarning wird in Python 3.10 zu einer TypeError. (Beigetragen von Ken Jin in bpo-42195.)

urllib.parse

Frühere Python-Versionen erlaubten die Verwendung von sowohl ; als auch & als Trennzeichen für Abfrageparameter in urllib.parse.parse_qs() und urllib.parse.parse_qsl(). Aus Sicherheitsgründen und zur Einhaltung neuerer W3C-Empfehlungen wurde dies geändert, um nur ein einzelnes Trennzeichen zuzulassen, wobei & der Standard ist. Diese Änderung wirkt sich auch auf cgi.parse() und cgi.parse_multipart() aus, da diese intern die betroffenen Funktionen verwenden. Weitere Details finden Sie in der jeweiligen Dokumentation. (Beigetragen von Adam Goldschmidt, Senthil Kumaran und Ken Jin in bpo-42967.)

Bemerkenswerte Änderungen in Python 3.9.3

Ein Sicherheitspatch ändert das Verhalten von ftplib.FTP, sodass die vom entfernten Server gesendete IPv4-Adresse beim Einrichten eines passiven Datenkanals nicht mehr vertraut wird. Stattdessen wird die FTP-Server-IP-Adresse wiederverwendet. Für ungewöhnlichen Code, der das alte Verhalten erfordert, setzen Sie ein Attribut trust_server_pasv_ipv4_address auf Ihrer FTP-Instanz auf True. (Siehe gh-87451)

Bemerkenswerte Änderungen in Python 3.9.5

urllib.parse

Das Vorhandensein von Zeilenumbruch- oder Tabulatorzeichen in Teilen einer URL ermöglicht einige Formen von Angriffen. Gemäß der WHATWG-Spezifikation, die RFC 3986 aktualisiert, werden ASCII-Zeilenumbruch \n, \r und Tabulator \t Zeichen vom Parser in urllib.parse entfernt, um solche Angriffe zu verhindern. Die zu entfernenden Zeichen werden durch eine neue Modulvariable urllib.parse._UNSAFE_URL_BYTES_TO_REMOVE gesteuert. (Siehe gh-88048)

Bemerkenswerte Sicherheitsfunktion in 3.9.14

Die Konvertierung zwischen int und str in anderen Basen als 2 (binär), 4, 8 (oktal), 16 (hexadezimal) oder 32 wie Basis 10 (dezimal) löst nun einen ValueError aus, wenn die Anzahl der Ziffern in Zeichenform einen Grenzwert überschreitet, um mögliche Denial-of-Service-Angriffe aufgrund der algorithmischen Komplexität zu vermeiden. Dies ist eine Abhilfemaßnahme für CVE 2020-10735. Dieses Limit kann über Umgebungsvariablen, Kommandozeilenoptionen oder sys-APIs konfiguriert oder deaktiviert werden. Siehe die Dokumentation zur Beschränkung der Zeichenkettenlänge bei Ganzzahlkonvertierungen. Das Standardlimit beträgt 4300 Ziffern in Zeichenform.

Bemerkenswerte Änderungen in 3.9.17

tarfile

  • Die Extraktionsmethoden in tarfile und shutil.unpack_archive() haben ein neues Argument filter, das die Beschränkung von Tar-Funktionen ermöglicht, die überraschend oder gefährlich sein können, wie z. B. das Erstellen von Dateien außerhalb des Zielverzeichnisses. Einzelheiten finden Sie unter Extraktionsfilter. In Python 3.12 wird die Verwendung ohne das Argument filter eine DeprecationWarning anzeigen. In Python 3.14 wird der Standard auf 'data' umgestellt. (Beigetragen von Petr Viktorin in PEP 706.)