Was gibt es Neues in Python 3.8

Editor:

Raymond Hettinger

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

Zusammenfassung – Release-Highlights

Neue Funktionen

Zuweisungsausdrücke

Es gibt eine neue Syntax :=, die Werte Variablen als Teil eines größeren Ausdrucks zuweist. Sie ist liebevoll als "Walross-Operator" bekannt, da sie an die Augen und Stoßzähne eines Walrosses erinnert.

In diesem Beispiel hilft der Zuweisungsausdruck, len() nicht zweimal aufrufen zu müssen

if (n := len(a)) > 10:
    print(f"List is too long ({n} elements, expected <= 10)")

Ein ähnlicher Vorteil ergibt sich bei regulären Ausdrucksabgleichen, bei denen Match-Objekte zweimal benötigt werden, einmal um zu testen, ob eine Übereinstimmung stattgefunden hat, und einmal, um eine Untergruppe zu extrahieren

discount = 0.0
if (mo := re.search(r'(\d+)% discount', advertisement)):
    discount = float(mo.group(1)) / 100.0

Der Operator ist auch nützlich bei while-Schleifen, die einen Wert berechnen, um die Schleifenbeendigung zu testen, und diesen Wert dann im Schleifenkörper erneut benötigen

# Loop over fixed length blocks
while (block := f.read(256)) != '':
    process(block)

Ein weiterer motivierender Anwendungsfall ergibt sich bei List Comprehensions, wo ein in einer Filterbedingung berechneter Wert auch im Ausdruckskörper benötigt wird

[clean_name.title() for name in names
 if (clean_name := normalize('NFC', name)) in allowed_names]

Versuchen Sie, die Verwendung des Walross-Operators auf klare Fälle zu beschränken, die die Komplexität reduzieren und die Lesbarkeit verbessern.

Siehe PEP 572 für eine vollständige Beschreibung.

(Beigetragen von Emily Morehouse in bpo-35224.)

Positionsgebundene Parameter

Es gibt eine neue Syntax für Funktionsparameter /, um anzuzeigen, dass einige Funktionsparameter positionsgebunden angegeben werden müssen und nicht als Schlüsselwortargumente verwendet werden können. Dies ist die gleiche Notation, die von help() für C-Funktionen angezeigt wird, die mit Larry Hastings' Argument Clinic-Tool annotiert sind.

Im folgenden Beispiel sind die Parameter *a* und *b* positionsgebunden, während *c* oder *d* positionsgebunden oder als Schlüsselwortargumente verwendet werden können, und *e* oder *f* müssen als Schlüsselwortargumente angegeben werden

def f(a, b, /, c, d, *, e, f):
    print(a, b, c, d, e, f)

Der folgende Aufruf ist gültig

f(10, 20, 30, d=40, e=50, f=60)

Folgende Aufrufe sind jedoch ungültig

f(10, b=20, c=30, d=40, e=50, f=60)   # b cannot be a keyword argument
f(10, 20, 30, 40, 50, f=60)           # e must be a keyword argument

Ein Anwendungsfall für diese Notation ist, dass sie es rein-Python-Funktionen ermöglicht, das Verhalten vorhandener C-codierter Funktionen vollständig nachzuahmen. Zum Beispiel akzeptiert die eingebaute Funktion divmod() keine Schlüsselwortargumente

def divmod(a, b, /):
    "Emulate the built in divmod() function"
    return (a // b, a % b)

Ein weiterer Anwendungsfall ist die Verhinderung von Schlüsselwortargumenten, wenn der Parametername nicht hilfreich ist. Zum Beispiel hat die eingebaute Funktion len() die Signatur len(obj, /). Dies verhindert umständliche Aufrufe wie

len(obj='hello')  # The "obj" keyword argument impairs readability

Ein weiterer Vorteil der Kennzeichnung eines Parameters als positionsgebunden ist, dass der Parametername in Zukunft geändert werden kann, ohne dass der Client-Code beeinträchtigt wird. Zum Beispiel kann im Modul statistics der Parametername *dist* in Zukunft geändert werden. Dies wurde mit der folgenden Funktionsspezifikation ermöglicht

def quantiles(dist, /, *, n=4, method='exclusive')
    ...

Da die Parameter links von / nicht als mögliche Schlüsselwörter verfügbar sind, bleiben die Parameternamen für die Verwendung in **kwargs verfügbar

>>> def f(a, b, /, **kwargs):
...     print(a, b, kwargs)
...
>>> f(10, 20, a=1, b=2, c=3)         # a and b are used in two ways
10 20 {'a': 1, 'b': 2, 'c': 3}

Dies vereinfacht die Implementierung von Funktionen und Methoden, die beliebige Schlüsselwortargumente akzeptieren müssen, erheblich. Hier ist zum Beispiel ein Auszug aus Code im Modul collections

class Counter(dict):

    def __init__(self, iterable=None, /, **kwds):
        # Note "iterable" is a possible keyword argument

Siehe PEP 570 für eine vollständige Beschreibung.

(Beigetragen von Pablo Galindo in bpo-36540.)

Paralleler Dateisystem-Cache für kompilierte Bytecode-Dateien

Die neue Einstellung PYTHONPYCACHEPREFIX (auch verfügbar als -X pycache_prefix) konfiguriert den impliziten Bytecode-Cache so, dass ein separater paralleler Dateisystembaum verwendet wird, anstatt der standardmäßigen `__pycache__`-Unterverzeichnisse in jedem Quellverzeichnis.

Der Speicherort des Caches wird in sys.pycache_prefix berichtet (None zeigt den Standardspeicherort in `__pycache__`-Unterverzeichnissen an).

(Beigetragen von Carl Meyer in bpo-33499.)

Debug-Build verwendet dasselbe ABI wie Release-Build

Python verwendet nun dasselbe ABI, unabhängig davon, ob es im Release- oder Debug-Modus kompiliert wurde. Unter Unix ist es nun möglich, C-Erweiterungen, die im Release-Modus kompiliert wurden, sowie C-Erweiterungen, die mit dem stabilen ABI kompiliert wurden, zu laden, wenn Python im Debug-Modus kompiliert wird.

Release-Builds und Debug-Builds sind nun ABI-kompatibel: Die Definition des Makros Py_DEBUG impliziert nicht mehr das Makro Py_TRACE_REFS, das die einzige ABI-Inkompatibilität darstellt. Das Makro Py_TRACE_REFS, das die Funktion sys.getobjects() und die Umgebungsvariable PYTHONDUMPREFS hinzufügt, kann über die neue Build-Option ./configure --with-trace-refs gesetzt werden. (Beigetragen von Victor Stinner in bpo-36465.)

Unter Unix werden C-Erweiterungen nicht mehr mit libpython verknüpft, außer auf Android und Cygwin. Es ist nun möglich, dass ein statisch verknüpftes Python eine C-Erweiterung lädt, die mit einer gemeinsam genutzten Python-Bibliothek kompiliert wurde. (Beigetragen von Victor Stinner in bpo-21536.)

Unter Unix sucht Import nun auch nach C-Erweiterungen, die im Release-Modus kompiliert wurden, und nach C-Erweiterungen, die mit dem stabilen ABI kompiliert wurden, wenn Python im Debug-Modus kompiliert wird. (Beigetragen von Victor Stinner in bpo-36722.)

Um Python in eine Anwendung einzubetten, muss die neue Option --embed an python3-config --libs --embed übergeben werden, um -lpython3.8 zu erhalten (Anwendung mit libpython verknüpfen). Um sowohl 3.8 als auch ältere Versionen zu unterstützen, versuchen Sie zuerst python3-config --libs --embed und greifen Sie auf python3-config --libs (ohne --embed) zurück, wenn der vorherige Befehl fehlschlägt.

Fügen Sie ein pkg-config-Modul python-3.8-embed hinzu, um Python in eine Anwendung einzubetten: pkg-config python-3.8-embed --libs enthält -lpython3.8. Um sowohl 3.8 als auch ältere Versionen zu unterstützen, versuchen Sie zuerst pkg-config python-X.Y-embed --libs und greifen Sie auf pkg-config python-X.Y --libs (ohne --embed) zurück, wenn der vorherige Befehl fehlschlägt (ersetzen Sie X.Y durch die Python-Version).

Andererseits enthält pkg-config python3.8 --libs nicht mehr -lpython3.8. C-Erweiterungen dürfen nicht mit libpython verknüpft werden (außer auf Android und Cygwin, deren Fälle vom Skript behandelt werden); diese Änderung ist absichtlich abwärts inkompatibel. (Beigetragen von Victor Stinner in bpo-36721.)

f-Strings unterstützen = für selbstdokumentierende Ausdrücke und Debugging

Ein `=` Spezifikator wurde zu f-Strings hinzugefügt. Ein f-String wie f'{expr=}' wird in den Text des Ausdrucks, ein Gleichheitszeichen und dann die Darstellung des ausgewerteten Ausdrucks erweitert. Zum Beispiel

>>> user = 'eric_idle'
>>> member_since = date(1975, 7, 31)
>>> f'{user=} {member_since=}'
"user='eric_idle' member_since=datetime.date(1975, 7, 31)"

Die üblichen f-String-Formatierungsspezifizierer ermöglichen mehr Kontrolle darüber, wie das Ergebnis des Ausdrucks angezeigt wird

>>> delta = date.today() - member_since
>>> f'{user=!s}  {delta.days=:,d}'
'user=eric_idle  delta.days=16,075'

Der `=` Spezifikator zeigt den gesamten Ausdruck an, sodass Berechnungen angezeigt werden können

>>> print(f'{theta=}  {cos(radians(theta))=:.3f}')
theta=30  cos(radians(theta))=0.866

(Beigetragen von Eric V. Smith und Larry Hastings in bpo-36817.)

PEP 578: Python Runtime Audit Hooks

Die PEP fügt einen Audit Hook und einen Verified Open Hook hinzu. Beide sind aus Python- und nativen Code verfügbar und ermöglichen es Anwendungen und Frameworks, die in reinem Python-Code geschrieben sind, von zusätzlichen Benachrichtigungen zu profitieren, während sie es auch Einbettungen oder Systemadministratoren ermöglichen, Builds von Python bereitzustellen, bei denen die Prüfung immer aktiviert ist.

Siehe PEP 578 für vollständige Details.

PEP 587: Python Initialization Configuration

Die PEP 587 fügt eine neue C-API hinzu, um die Python-Initialisierung zu konfigurieren und eine feinere Kontrolle über die gesamte Konfiguration sowie eine bessere Fehlerberichterstattung zu ermöglichen.

Neue Strukturen

Neue Funktionen

Diese PEP fügt auch die Felder _PyRuntimeState.preconfig (Typ PyPreConfig) und PyInterpreterState.config (Typ PyConfig) zu diesen internen Strukturen hinzu. PyInterpreterState.config wird zur neuen Referenzkonfiguration und ersetzt globale Konfigurationsvariablen und andere private Variablen.

Siehe Python Initialization Configuration für die Dokumentation.

Siehe PEP 587 für eine vollständige Beschreibung.

(Beigetragen von Victor Stinner in bpo-36763.)

PEP 590: Vectorcall: ein schnelles Aufrufprotokoll für CPython

Das Vectorcall-Protokoll wird der Python/C-API hinzugefügt. Es soll bestehende Optimierungen formalisieren, die bereits für verschiedene Klassen durchgeführt wurden. Jeder statische Typ, der ein Aufrufobjekt implementiert, kann dieses Protokoll verwenden.

Dies ist derzeit vorläufig. Ziel ist es, es in Python 3.9 vollständig öffentlich zu machen.

Siehe PEP 590 für eine vollständige Beschreibung.

(Beigetragen von Jeroen Demeyer, Mark Shannon und Petr Viktorin in bpo-36974.)

Pickle-Protokoll 5 mit Out-of-Band-Datenpuffern

Wenn pickle verwendet wird, um große Daten zwischen Python-Prozessen zu übertragen, um die Vorteile von Multi-Core- oder Multi-Machine-Verarbeitung zu nutzen, ist es wichtig, die Übertragung zu optimieren, indem Speicher Kopien reduziert und möglicherweise benutzerdefinierte Techniken wie datenabhängige Komprimierung angewendet werden.

Das pickle Protokoll 5 führt Unterstützung für Out-of-Band-Puffer ein, bei denen PEP 3118-kompatible Daten getrennt vom Haupt-Pickle-Stream übertragen werden können, nach Ermessen der Kommunikationsschicht.

Siehe PEP 574 für eine vollständige Beschreibung.

(Beigetragen von Antoine Pitrou in bpo-36785.)

Andere Sprachänderungen

  • Eine `continue`-Anweisung war in der `finally`-Klausel aufgrund eines Implementierungsproblems illegal. In Python 3.8 wurde diese Einschränkung aufgehoben. (Beigetragen von Serhiy Storchaka in bpo-32489.)

  • Die Typen `bool`, `int` und `fractions.Fraction` haben jetzt eine Methode `as_integer_ratio()`, ähnlich der von `float` und `decimal.Decimal`. Diese geringfügige API-Erweiterung ermöglicht es, `numerator, denominator = x.as_integer_ratio()` zu schreiben und dass es über mehrere numerische Typen hinweg funktioniert. (Beigetragen von Lisa Roach in bpo-33073 und Raymond Hettinger in bpo-37819.)

  • Konstruktoren von `int`, `float` und `complex` verwenden nun die spezielle Methode `__index__()`, falls verfügbar und die entsprechende Methode `__int__()`, `__float__()` oder `__complex__()` nicht verfügbar ist. (Beigetragen von Serhiy Storchaka in bpo-20092.)

  • Unterstützung für `\N{name}`-Escapes in regulären Ausdrücken hinzugefügt

    >>> notice = 'Copyright © 2019'
    >>> copyright_year_pattern = re.compile(r'\N{copyright sign}\s*(\d{4})')
    >>> int(copyright_year_pattern.search(notice).group(1))
    2019
    

    (Beigetragen von Jonathan Eunice und Serhiy Storchaka in bpo-30688.)

  • Dicts und dictviews sind nun in umgekehrter Einfügungsreihenfolge über `reversed()` iterierbar. (Beigetragen von Rémi Lapeyre in bpo-33462.)

  • Die für Schlüsselnamen in Funktionsaufrufen zulässige Syntax wurde weiter eingeschränkt. Insbesondere ist `f((keyword)=arg)` nicht mehr erlaubt. Es war nie beabsichtigt, mehr als einen einzelnen Namen auf der linken Seite eines Schlüsselwortargument-Zuweisungsterms zuzulassen. (Beigetragen von Benjamin Peterson in bpo-34641.)

  • Generalisierte Iterable-Unpacking in `yield`- und `return`-Anweisungen erfordert keine umschließenden Klammern mehr. Dies bringt die Syntax für `yield` und `return` in bessere Übereinstimmung mit der normalen Zuweisungssyntax

    >>> def parse(family):
    ...     lastname, *members = family.split()
    ...     return lastname.upper(), *members
    ...
    >>> parse('simpsons homer marge bart lisa maggie')
    ('SIMPSONS', 'homer', 'marge', 'bart', 'lisa', 'maggie')
    

    (Beigetragen von David Cuthbert und Jordan Chapman in bpo-32117.)

  • Wenn ein Komma in Code wie `[(10, 20) (30, 40)]` fehlt, zeigt der Compiler eine `SyntaxWarning` mit einem hilfreichen Vorschlag an. Dies verbessert das alleinige Anzeigen einer `TypeError`, die darauf hinweist, dass das erste Tupel nicht aufrufbar war. (Beigetragen von Serhiy Storchaka in bpo-15248.)

  • Arithmetische Operationen zwischen Unterklassen von `datetime.date` oder `datetime.datetime` und `datetime.timedelta`-Objekten geben nun eine Instanz der Unterklasse zurück, anstatt der Basisklasse. Dies wirkt sich auch auf den Rückgabetyp von Operationen aus, deren Implementierung (direkt oder indirekt) die Arithmetik mit `datetime.timedelta` verwendet, wie z. B. `astimezone()`. (Beigetragen von Paul Ganssle in bpo-32417.)

  • Wenn der Python-Interpreter durch Strg+C (SIGINT) unterbrochen wird und die resultierende `KeyboardInterrupt`-Ausnahme nicht abgefangen wird, beendet sich der Python-Prozess nun über ein SIGINT-Signal oder mit dem richtigen Exit-Code, sodass der aufrufende Prozess erkennen kann, dass er aufgrund eines Strg+C beendet wurde. Shells unter POSIX und Windows verwenden dies, um Skripte in interaktiven Sitzungen ordnungsgemäß zu beenden. (Beigetragen von Google über Gregory P. Smith in bpo-1054041.)

  • Einige fortgeschrittene Programmierstile erfordern die Aktualisierung des `types.CodeType`-Objekts für eine bestehende Funktion. Da Code-Objekte unveränderlich sind, muss ein neues Code-Objekt erstellt werden, das auf dem bestehenden Code-Objekt basiert. Mit 19 Parametern war dies etwas mühsam. Nun ermöglicht die neue `replace()`-Methode die Erstellung einer Kopie mit wenigen geänderten Parametern.

    Hier ist ein Beispiel, das die Funktion `statistics.mean()` modifiziert, um zu verhindern, dass der Parameter *data* als Schlüsselwortargument verwendet wird

    >>> from statistics import mean
    >>> mean(data=[10, 20, 90])
    40
    >>> mean.__code__ = mean.__code__.replace(co_posonlyargcount=1)
    >>> mean(data=[10, 20, 90])
    Traceback (most recent call last):
      ...
    TypeError: mean() got some positional-only arguments passed as keyword arguments: 'data'
    

    (Beigetragen von Victor Stinner in bpo-37032.)

  • Für ganze Zahlen erlaubt die dreistellige Form der `pow()`-Funktion nun, dass der Exponent negativ ist, wenn die Basis relativ prim zur Modul ist. Sie berechnet dann eine modulare Inverse zur Basis, wenn der Exponent `-1` ist, und eine geeignete Potenz dieser Inversen für andere negative Exponenten. Um beispielsweise die modulare multiplikative Inverse von 38 modulo 137 zu berechnen, schreiben Sie

    >>> pow(38, -1, 137)
    119
    >>> 119 * 38 % 137
    1
    

    Modulare Inverse treten bei der Lösung von linearen diophantischen Gleichungen auf. Um beispielsweise ganzzahlige Lösungen für `4258𝑥 + 147𝑦 = 369` zu finden, schreiben Sie sie zunächst als `4258𝑥 ≡ 369 (mod 147)` um und lösen Sie dann

    >>> x = 369 * pow(4258, -1, 147) % 147
    >>> y = (4258 * x - 369) // -147
    >>> 4258 * x + 147 * y
    369
    

    (Beigetragen von Mark Dickinson in bpo-36027.)

  • Dict-Comprehensions wurden mit Dict-Literalen synchronisiert, sodass zuerst der Schlüssel und dann der Wert berechnet wird

    >>> # Dict comprehension
    >>> cast = {input('role? '): input('actor? ') for i in range(2)}
    role? King Arthur
    actor? Chapman
    role? Black Knight
    actor? Cleese
    
    >>> # Dict literal
    >>> cast = {input('role? '): input('actor? ')}
    role? Sir Robin
    actor? Eric Idle
    

    Die garantierte Ausführungsreihenfolge ist bei Zuweisungsausdrücken hilfreich, da Variablen, die im Schlüssel-Ausdruck zugewiesen werden, im Wert-Ausdruck verfügbar sind

    >>> names = ['Martin von Löwis', 'Łukasz Langa', 'Walter Dörwald']
    >>> {(n := normalize('NFC', name)).casefold() : n for name in names}
    {'martin von löwis': 'Martin von Löwis',
     'łukasz langa': 'Łukasz Langa',
     'walter dörwald': 'Walter Dörwald'}
    

    (Beigetragen von Jörn Heissler in bpo-35224.)

  • Die Methode `object.__reduce__()` kann nun ein Tupel von zwei bis sechs Elementen zurückgeben. Zuvor war fünf die Grenze. Das neue, optionale sechste Element ist eine aufrufbare Funktion mit einer Signatur `(obj, state)`. Dies ermöglicht die direkte Steuerung des Zustandsaktualisierungsverhaltens eines bestimmten Objekts. Wenn diese Funktion nicht `None` ist, hat sie Vorrang vor der `__setstate__()`-Methode des Objekts. (Beigetragen von Pierre Glaser und Olivier Grisel in bpo-35900.)

Neue Module

  • Das neue Modul `importlib.metadata` bietet (vorläufige) Unterstützung für das Lesen von Metadaten aus Drittanbieterpaketen. Zum Beispiel kann es die Versionsnummer eines installierten Pakets, die Liste der Einstiegspunkte und mehr extrahieren

    >>> # Note following example requires that the popular "requests"
    >>> # package has been installed.
    >>>
    >>> from importlib.metadata import version, requires, files
    >>> version('requests')
    '2.22.0'
    >>> list(requires('requests'))
    ['chardet (<3.1.0,>=3.0.2)']
    >>> list(files('requests'))[:5]
    [PackagePath('requests-2.22.0.dist-info/INSTALLER'),
     PackagePath('requests-2.22.0.dist-info/LICENSE'),
     PackagePath('requests-2.22.0.dist-info/METADATA'),
     PackagePath('requests-2.22.0.dist-info/RECORD'),
     PackagePath('requests-2.22.0.dist-info/WHEEL')]
    

    (Beigetragen von Barry Warsaw und Jason R. Coombs in bpo-34632.)

Verbesserte Module

ast

AST-Knoten haben nun die Attribute `end_lineno` und `end_col_offset`, die den genauen Speicherort des Endes des Knotens angeben. (Dies gilt nur für Knoten, die die Attribute `lineno` und `col_offset` haben.)

Die neue Funktion `ast.get_source_segment()` gibt den Quellcode für einen bestimmten AST-Knoten zurück.

(Beigetragen von Ivan Levkivskyi in bpo-33416.)

Die Funktion `ast.parse()` hat einige neue Flags

  • `type_comments=True` bewirkt, dass sie den Text der PEP 484 und PEP 526 Typkommentare zurückgibt, die bestimmten AST-Knoten zugeordnet sind;

  • `mode='func_type'` kann verwendet werden, um PEP 484 "Signatur-Typkommentare" zu parsen (die für AST-Knoten von Funktionsdefinitionen zurückgegeben werden);

  • `feature_version=(3, N)` ermöglicht die Angabe einer früheren Python 3-Version. Zum Beispiel behandelt `feature_version=(3, 4)` `async` und `await` als nicht reservierte Wörter.

(Beigetragen von Guido van Rossum in bpo-35766.)

asyncio

`asyncio.run()` ist von der provisorischen zur stabilen API aufgestiegen. Diese Funktion kann verwendet werden, um eine Coroutine auszuführen und das Ergebnis zurückzugeben, während die Event-Schleife automatisch verwaltet wird. Zum Beispiel

import asyncio

async def main():
    await asyncio.sleep(0)
    return 42

asyncio.run(main())

Dies ist *ungefähr* äquivalent zu

import asyncio

async def main():
    await asyncio.sleep(0)
    return 42

loop = asyncio.new_event_loop()
asyncio.set_event_loop(loop)
try:
    loop.run_until_complete(main())
finally:
    asyncio.set_event_loop(None)
    loop.close()

Die tatsächliche Implementierung ist wesentlich komplexer. Daher sollte asyncio.run() die bevorzugte Methode zum Ausführen von asyncio-Programmen sein.

(Beigetragen von Yury Selivanov in bpo-32314.)

Das Ausführen von python -m asyncio startet eine nativerweise asynchrone REPL. Dies ermöglicht schnelles Experimentieren mit Code, der ein Top-Level await aufweist. Es ist nicht mehr notwendig, asyncio.run() direkt aufzurufen, was bei jedem Aufruf eine neue Event-Schleife spawnen würde.

$ python -m asyncio
asyncio REPL 3.8.0
Use "await" directly instead of "asyncio.run()".
Type "help", "copyright", "credits" or "license" for more information.
>>> import asyncio
>>> await asyncio.sleep(10, result='hello')
hello

(Beigetragen von Yury Selivanov in bpo-37028.)

Die Ausnahme asyncio.CancelledError erbt nun von BaseException anstatt von Exception und erbt nicht mehr von concurrent.futures.CancelledError. (Beigetragen von Yury Selivanov in bpo-32528.)

Unter Windows ist die Standard-Event-Schleife nun ProactorEventLoop. (Beigetragen von Victor Stinner in bpo-34687.)

ProactorEventLoop unterstützt nun auch UDP. (Beigetragen von Adam Meily und Andrew Svetlov in bpo-29883.)

ProactorEventLoop kann nun durch KeyboardInterrupt ("STRG+C") unterbrochen werden. (Beigetragen von Vladimir Matveev in bpo-23057.)

Hinzugefügt wurde asyncio.Task.get_coro() zum Abrufen der umschlossenen Koroutine innerhalb einer asyncio.Task. (Beigetragen von Alex Grönholm in bpo-36999.)

Asyncio-Aufgaben können nun benannt werden, entweder durch Übergabe des Schlüsselwortarguments name an asyncio.create_task() oder an die Event-Loop-Methode create_task(), oder durch Aufruf der Methode set_name() auf dem Aufgabenobjekt. Der Aufgabenname ist in der repr()-Ausgabe von asyncio.Task sichtbar und kann auch über die Methode get_name() abgerufen werden. (Beigetragen von Alex Grönholm in bpo-34270.)

Unterstützung für Happy Eyeballs wurde zu asyncio.loop.create_connection() hinzugefügt. Um das Verhalten festzulegen, wurden zwei neue Parameter hinzugefügt: happy_eyeballs_delay und interleave. Der Happy Eyeballs-Algorithmus verbessert die Reaktionsfähigkeit von Anwendungen, die IPv4 und IPv6 unterstützen, indem er versucht, gleichzeitig mit beiden zu verbinden. (Beigetragen von twisteroid ambassador in bpo-33530.)

builtins

Die integrierte Funktion compile() wurde verbessert, um das Flag ast.PyCF_ALLOW_TOP_LEVEL_AWAIT zu akzeptieren. Mit diesem neuen Flag erlaubt compile() Top-Level await, async for und async with Konstrukte, die normalerweise als ungültige Syntax gelten. Asynchrone Code-Objekte, die mit dem Flag CO_COROUTINE markiert sind, können dann zurückgegeben werden. (Beigetragen von Matthias Bussonnier in bpo-34616)

collections

Die Methode _asdict() für collections.namedtuple() gibt nun ein dict anstelle eines collections.OrderedDict zurück. Dies funktioniert, da reguläre Dictionaries seit Python 3.7 eine garantierte Reihenfolge haben. Wenn die zusätzlichen Funktionen von OrderedDict benötigt werden, ist die empfohlene Abhilfe, das Ergebnis in den gewünschten Typ zu konvertieren: OrderedDict(nt._asdict()). (Beigetragen von Raymond Hettinger in bpo-35864.)

cProfile

Die Klasse cProfile.Profile kann nun als Kontextmanager verwendet werden. Profilieren Sie einen Codeblock, indem Sie ausführen

import cProfile

with cProfile.Profile() as profiler:
      # code to be profiled
      ...

(Beigetragen von Scott Sanderson in bpo-29235.)

csv

Der csv.DictReader gibt nun Instanzen von dict anstelle eines collections.OrderedDict zurück. Das Werkzeug ist nun schneller und verbraucht weniger Speicher, behält aber dennoch die Feldreihenfolge bei. (Beigetragen von Michael Selik in bpo-34003.)

curses

Eine neue Variable, die strukturierte Versionsinformationen für die zugrunde liegende ncurses-Bibliothek enthält, wurde hinzugefügt: ncurses_version. (Beigetragen von Serhiy Storchaka in bpo-31680.)

ctypes

Unter Windows akzeptieren ctypes.CDLL und dessen Unterklassen nun einen Parameter winmode, um Flags für den zugrunde liegenden Aufruf von LoadLibraryEx anzugeben. Die Standard-Flags sind so eingestellt, dass DLL-Abhängigkeiten nur aus vertrauenswürdigen Speicherorten geladen werden, einschließlich des Pfads, an dem die DLL gespeichert ist (wenn ein vollständiger oder teilweiser Pfad zum Laden der initialen DLL verwendet wird) und der von os.add_dll_directory() hinzugefügten Pfade. (Beigetragen von Steve Dower in bpo-36085.)

datetime

Neue alternative Konstruktoren wurden hinzugefügt: datetime.date.fromisocalendar() und datetime.datetime.fromisocalendar(), die date- und datetime-Objekte aus ISO-Jahr, Wochennummer und Wochentag konstruieren; dies sind die Umkehrungen der isocalendar-Methode jeder Klasse. (Beigetragen von Paul Ganssle in bpo-36004.)

functools

functools.lru_cache() kann nun als direkter Dekorator verwendet werden, anstatt als Funktion, die einen Dekorator zurückgibt. Beide Varianten werden nun unterstützt

@lru_cache
def f(x):
    ...

@lru_cache(maxsize=256)
def f(x):
    ...

(Beigetragen von Raymond Hettinger in bpo-36772.)

Ein neuer Dekorator functools.cached_property() wurde hinzugefügt, für berechnete Eigenschaften, die für die Lebensdauer der Instanz gecacht werden.

import functools
import statistics

class Dataset:
   def __init__(self, sequence_of_numbers):
      self.data = sequence_of_numbers

   @functools.cached_property
   def variance(self):
      return statistics.variance(self.data)

(Beigetragen von Carl Meyer in bpo-21145)

Ein neuer Dekorator functools.singledispatchmethod() wurde hinzugefügt, der Methoden in generische Funktionen mit Single Dispatch umwandelt

from functools import singledispatchmethod
from contextlib import suppress

class TaskManager:

    def __init__(self, tasks):
        self.tasks = list(tasks)

    @singledispatchmethod
    def discard(self, value):
        with suppress(ValueError):
            self.tasks.remove(value)

    @discard.register(list)
    def _(self, tasks):
        targets = set(tasks)
        self.tasks = [x for x in self.tasks if x not in targets]

(Beigetragen von Ethan Smith in bpo-32380)

gc

get_objects() kann nun einen optionalen Parameter generation erhalten, der eine zu holende Generation angibt. (Beigetragen von Pablo Galindo in bpo-36016.)

gettext

pgettext() und seine Varianten wurden hinzugefügt. (Beigetragen von Franz Glasner, Éric Araujo und Cheryl Sabella in bpo-2504.)

gzip

Der Parameter mtime wurde zu gzip.compress() für reproduzierbare Ausgaben hinzugefügt. (Beigetragen von Guo Ci Teo in bpo-34898.)

Eine Ausnahme BadGzipFile wird nun anstelle von OSError für bestimmte Arten von ungültigen oder beschädigten Gzip-Dateien ausgelöst. (Beigetragen von Filip Gruszczyński, Michele Orrù und Zackery Spytz in bpo-6584.)

IDLE und idlelib

Ausgaben über N Zeilen (standardmäßig 50) werden zu einem Button zusammengefasst. N kann im Abschnitt PyShell der Seite Allgemein im Einstellungsdialog geändert werden. Weniger, aber möglicherweise sehr lange Zeilen, können durch Rechtsklick auf die Ausgabe zusammengefasst werden. Zusammengefasste Ausgaben können durch Doppelklick auf den Button an Ort und Stelle oder in die Zwischenablage oder ein separates Fenster durch Rechtsklick auf den Button erweitert werden. (Beigetragen von Tal Einat in bpo-1529353.)

Fügt "Run Customized" zum Menü "Run" hinzu, um ein Modul mit benutzerdefinierten Einstellungen auszuführen. Alle eingegebenen Kommandozeilenargumente werden zu sys.argv hinzugefügt. Sie erscheinen auch wieder in der Box für den nächsten benutzerdefinierten Lauf. Man kann auch den normalen Neustart des Shell-Hauptmoduls unterdrücken. (Beigetragen von Cheryl Sabella, Terry Jan Reedy und anderen in bpo-5680 und bpo-37627.)

Optionale Zeilennummern für IDLE-Editorfenster hinzugefügt. Fenster werden ohne Zeilennummern geöffnet, es sei denn, dies ist im Reiter Allgemein des Konfigurationsdialogs anders eingestellt. Zeilennummern für ein bestehendes Fenster werden im Menü Optionen ein- und ausgeblendet. (Beigetragen von Tal Einat und Saimadhav Heblikar in bpo-17535.)

Die OS-native Kodierung wird nun für die Konvertierung zwischen Python-Strings und Tcl-Objekten verwendet. Dies ermöglicht IDLE die Arbeit mit Emojis und anderen Nicht-BMP-Zeichen. Diese Zeichen können angezeigt oder kopiert und in die Zwischenablage eingefügt werden. Die Konvertierung von Strings von Tcl nach Python und zurück schlägt nun nie fehl. (Viele Leute haben acht Jahre lang daran gearbeitet, aber das Problem wurde schließlich von Serhiy Storchaka in bpo-13153 gelöst.)

Neu in 3.8.1

Option zum Deaktivieren des Cursorblinkens hinzugefügt. (Beigetragen von Zackery Spytz in bpo-4603.)

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

Die oben genannten Änderungen wurden in Wartungsversionen von 3.7 zurückportiert.

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

inspect

Die Funktion inspect.getdoc() kann nun Docstrings für __slots__ finden, wenn dieses Attribut ein dict ist, dessen Werte Docstrings sind. Dies bietet Dokumentationsmöglichkeiten, die den bereits vorhandenen für property(), classmethod() und staticmethod() ähneln.

class AudioClip:
    __slots__ = {'bit_rate': 'expressed in kilohertz to one decimal place',
                 'duration': 'in seconds, rounded up to an integer'}
    def __init__(self, bit_rate, duration):
        self.bit_rate = round(bit_rate / 1000.0, 1)
        self.duration = ceil(duration)

(Beigetragen von Raymond Hettinger in bpo-36326.)

io

Im Entwicklungsmodus (-X env) und in Debug-Builds protokolliert der Finalisierer von io.IOBase die Ausnahme, wenn die Methode close() fehlschlägt. Die Ausnahme wird standardmäßig im Release-Build stillschweigend ignoriert. (Beigetragen von Victor Stinner in bpo-18748.)

itertools

Die Funktion itertools.accumulate() hat ein optionales Schlüsselwortargument initial hinzugefügt, um einen Startwert anzugeben.

>>> from itertools import accumulate
>>> list(accumulate([10, 5, 30, 15], initial=1000))
[1000, 1010, 1015, 1045, 1060]

(Beigetragen von Lisa Roach in bpo-34659.)

json.tool

Option --json-lines hinzugefügt, um jede Eingabezeile als separates JSON-Objekt zu parsen. (Beigetragen von Weipeng Hong in bpo-31553.)

logging

Ein neues Schlüsselwortargument force wurde zu logging.basicConfig() hinzugefügt. Wenn es auf true gesetzt ist, werden alle vorhandenen Handler, die an den Root-Logger angehängt sind, entfernt und geschlossen, bevor die durch die anderen Argumente angegebene Konfiguration durchgeführt wird.

Dies löst ein seit langem bestehendes Problem. Sobald ein Logger oder basicConfig() aufgerufen worden war, wurden nachfolgende Aufrufe von basicConfig() stillschweigend ignoriert. Dies erschwerte die Aktualisierung, das Experimentieren oder das Lehren der verschiedenen Logging-Konfigurationsoptionen über die interaktive Eingabeaufforderung oder ein Jupyter-Notebook.

(Vorgeschlagen von Raymond Hettinger, implementiert von Donghee Na und überprüft von Vinay Sajip in bpo-33897.)

math

Eine neue Funktion math.dist() zur Berechnung der euklidischen Distanz zwischen zwei Punkten wurde hinzugefügt. (Beigetragen von Raymond Hettinger in bpo-33089.)

Die Funktion math.hypot() wurde erweitert, um mehrere Dimensionen zu handhaben. Zuvor unterstützte sie nur den 2D-Fall. (Beigetragen von Raymond Hettinger in bpo-33089.)

Eine neue Funktion, math.prod(), wurde hinzugefügt, als analoge Funktion zu sum(), die das Produkt eines Startwertes (standardmäßig: 1) mal einem Iterable von Zahlen zurückgibt.

>>> prior = 0.8
>>> likelihoods = [0.625, 0.84, 0.30]
>>> math.prod(likelihoods, start=prior)
0.126

(Beigetragen von Pablo Galindo in bpo-35606.)

Zwei neue kombinatorische Funktionen wurden hinzugefügt: math.perm() und math.comb().

>>> math.perm(10, 3)    # Permutations of 10 things taken 3 at a time
720
>>> math.comb(10, 3)    # Combinations of 10 things taken 3 at a time
120

(Beigetragen von Yash Aggarwal, Keller Fuchs, Serhiy Storchaka und Raymond Hettinger in bpo-37128, bpo-37178 und bpo-35431.)

Eine neue Funktion math.isqrt() wurde hinzugefügt, um genaue ganzzahlige Quadratwurzeln ohne Konvertierung in Gleitkommazahlen zu berechnen. Die neue Funktion unterstützt beliebig große ganze Zahlen. Sie ist schneller als floor(sqrt(n)), aber langsamer als math.sqrt().

>>> r = 650320427
>>> s = r ** 2
>>> isqrt(s - 1)         # correct
650320426
>>> floor(sqrt(s - 1))   # incorrect
650320427

(Beigetragen von Mark Dickinson in bpo-36887.)

Die Funktion math.factorial() akzeptiert keine Argumente mehr, die keine int-ähnlichen sind. (Beigetragen von Pablo Galindo in bpo-33083.)

mmap

Die Klasse mmap.mmap hat nun eine Methode madvise(), um auf den Systemaufruf madvise() zuzugreifen. (Beigetragen von Zackery Spytz in bpo-32941.)

multiprocessing

Das neue Modul multiprocessing.shared_memory wurde hinzugefügt. (Beigetragen von Davin Potts in bpo-35813.)

Unter macOS wird nun standardmäßig die Startmethode spawn verwendet. (Beigetragen von Victor Stinner in bpo-33725.)

os

Die neue Funktion os.add_dll_directory() wurde unter Windows hinzugefügt, um zusätzliche Suchpfade für native Abhängigkeiten bereitzustellen, wenn Erweiterungsmodule importiert oder DLLs über ctypes geladen werden. (Beigetragen von Steve Dower in bpo-36085.)

Eine neue Funktion os.memfd_create() wurde hinzugefügt, um den Systemaufruf memfd_create() zu wrappen. (Beigetragen von Zackery Spytz und Christian Heimes in bpo-26836.)

Unter Windows wurde ein Großteil der manuellen Logik für die Behandlung von Reparse-Punkten (einschließlich Symlinks und Verzeichnissymbolverknüpfungen) an das Betriebssystem delegiert. Insbesondere durchläuft os.stat() nun alles, was vom Betriebssystem unterstützt wird, während os.lstat() nur Reparse-Punkte öffnet, die als "Namenssurrogate" identifiziert werden, während andere wie bei os.stat() geöffnet werden. In allen Fällen hat os.stat_result.st_mode nur S_IFLNK für symbolische Links gesetzt und nicht für andere Arten von Reparse-Punkten. Um andere Arten von Reparse-Punkten zu identifizieren, überprüfen Sie das neue Attribut os.stat_result.st_reparse_tag.

Unter Windows kann os.readlink() nun Verzeichnissymbolverknüpfungen lesen. Beachten Sie, dass islink() für Verzeichnissymbolverknüpfungen False zurückgibt, sodass Code, der zuerst islink prüft, Verknüpfungen weiterhin als Verzeichnisse behandelt, während Code, der Fehler von os.readlink() behandelt, Verknüpfungen nun als Links behandeln kann.

(Beigetragen von Steve Dower in bpo-37834.)

os.path

os.path-Funktionen, die ein boolesches Ergebnis zurückgeben, wie z.B. exists(), lexists(), isdir(), isfile(), islink() und ismount() geben nun False anstelle von ValueError oder seinen Unterklassen UnicodeEncodeError und UnicodeDecodeError für Pfade mit Zeichen oder Bytes zurück, die auf OS-Ebene nicht darstellbar sind. (Beigetragen von Serhiy Storchaka in bpo-33721.)

expanduser() unter Windows bevorzugt nun die Umgebungsvariable USERPROFILE und verwendet nicht HOME, die normalerweise nicht für normale Benutzerkonten gesetzt ist. (Beigetragen von Anthony Sottile in bpo-36264.)

isdir() unter Windows gibt nun für einen Link zu einem nicht vorhandenen Verzeichnis nicht mehr True zurück.

realpath() unter Windows löst nun Reparse-Punkte auf, einschließlich Symlinks und Verzeichnissymbolverknüpfungen.

(Beigetragen von Steve Dower in bpo-37834.)

pathlib

pathlib.Path-Methoden, die ein boolesches Ergebnis zurückgeben, wie z.B. exists(), is_dir(), is_file(), is_mount(), is_symlink(), is_block_device(), is_char_device(), is_fifo(), is_socket() geben nun stattdessen False zurück, anstatt ValueError oder dessen Unterklasse UnicodeEncodeError für Pfade mit Zeichen auszulösen, die auf OS-Ebene nicht darstellbar sind. (Beigetragen von Serhiy Storchaka in bpo-33721.)

Fügt die Methode pathlib.Path.link_to() hinzu, die einen Hardlink erstellt, der auf einen Pfad verweist. (Beigetragen von Joannah Nanjekye in bpo-26978) Beachten Sie, dass link_to in 3.10 als veraltet und in 3.12 entfernt wurde, zugunsten einer Methode hardlink_to, die in 3.10 hinzugefügt wurde und die Semantik der bestehenden Methode symlink_to widerspiegelt.

pickle

pickle-Erweiterungen, die von der C-optimierten Klasse Pickler ableiten, können nun die Pickling-Logik von Funktionen und Klassen überschreiben, indem sie die spezielle Methode reducer_override() definieren. (Beigetragen von Pierre Glaser und Olivier Grisel in bpo-35900.)

plistlib

Fügt plistlib.UID hinzu und ermöglicht die Unterstützung für das Lesen und Schreiben von NSKeyedArchiver-kodierten Binär-Plists. (Beigetragen von Jon Janzen in bpo-26707.)

pprint

Das Modul pprint hat einen Parameter sort_dicts zu mehreren Funktionen hinzugefügt. Standardmäßig sortieren diese Funktionen weiterhin Wörterbücher vor dem Rendern oder Drucken. Wenn jedoch sort_dicts auf false gesetzt ist, behalten die Wörterbücher die Reihenfolge bei, in der die Schlüssel eingefügt wurden. Dies kann beim Debuggen nützlich sein, um mit JSON-Eingaben zu vergleichen.

Darüber hinaus gibt es eine neue Komfortfunktion, pprint.pp(), die ähnlich wie pprint.pprint() ist, aber sort_dicts auf False setzt.

>>> from pprint import pprint, pp
>>> d = dict(source='input.txt', operation='filter', destination='output.txt')
>>> pp(d, width=40)                  # Original order
{'source': 'input.txt',
 'operation': 'filter',
 'destination': 'output.txt'}
>>> pprint(d, width=40)              # Keys sorted alphabetically
{'destination': 'output.txt',
 'operation': 'filter',
 'source': 'input.txt'}

(Beigetragen von Rémi Lapeyre in bpo-30670.)

py_compile

py_compile.compile() unterstützt nun den Stillmodus. (Beigetragen von Joannah Nanjekye in bpo-22640.)

shlex

Die neue Funktion shlex.join() wirkt als Umkehrung von shlex.split(). (Beigetragen von Bo Bayles in bpo-32102.)

shutil

shutil.copytree() akzeptiert nun ein neues Schlüsselwortargument dirs_exist_ok. (Beigetragen von Josh Bronson in bpo-20849.)

shutil.make_archive() verwendet nun standardmäßig das moderne pax-Format (POSIX.1-2001) für neue Archive, um die Portabilität und Konformität mit Standards zu verbessern. Dies wird von der entsprechenden Änderung im Modul tarfile übernommen. (Beigetragen von C.A.M. Gerlach in bpo-30661.)

shutil.rmtree() unter Windows entfernt nun Verzeichnissprünge, ohne zuerst rekursiv deren Inhalt zu entfernen. (Beigetragen von Steve Dower in bpo-37834.)

socket

Fügt die Komfortfunktionen create_server() und has_dualstack_ipv6() hinzu, um die notwendigen Aufgaben bei der Erstellung eines Server-Sockets zu automatisieren, einschließlich der Annahme von IPv4- und IPv6-Verbindungen auf demselben Socket. (Beigetragen von Giampaolo Rodolà in bpo-17561.)

Die Funktionen socket.if_nameindex(), socket.if_nametoindex() und socket.if_indextoname() wurden unter Windows implementiert. (Beigetragen von Zackery Spytz in bpo-37007.)

ssl

Fügt post_handshake_auth zum Aktivieren und verify_client_post_handshake() zum Initiieren der TLS 1.3 Post-Handshake-Authentifizierung hinzu. (Beigetragen von Christian Heimes in bpo-34670.)

statistics

Fügt statistics.fmean() als schnellere Fließkomma-Variante von statistics.mean() hinzu. (Beigetragen von Raymond Hettinger und Steven D’Aprano in bpo-35904.)

Fügt statistics.geometric_mean() hinzu. (Beigetragen von Raymond Hettinger in bpo-27181.)

Fügt statistics.multimode() hinzu, das eine Liste der häufigsten Werte zurückgibt. (Beigetragen von Raymond Hettinger in bpo-35892.)

Fügt statistics.quantiles() hinzu, das Daten oder eine Verteilung in gleichwahrscheinliche Intervalle (z.B. Quartile, Dezile oder Perzentile) unterteilt. (Beigetragen von Raymond Hettinger in bpo-36546.)

Fügt statistics.NormalDist hinzu, ein Werkzeug zur Erstellung und Manipulation von Normalverteilungen einer Zufallsvariablen. (Beigetragen von Raymond Hettinger in bpo-36018.)

>>> temperature_feb = NormalDist.from_samples([4, 12, -3, 2, 7, 14])
>>> temperature_feb.mean
6.0
>>> temperature_feb.stdev
6.356099432828281

>>> temperature_feb.cdf(3)            # Chance of being under 3 degrees
0.3184678262814532
>>> # Relative chance of being 7 degrees versus 10 degrees
>>> temperature_feb.pdf(7) / temperature_feb.pdf(10)
1.2039930378537762

>>> el_niño = NormalDist(4, 2.5)
>>> temperature_feb += el_niño        # Add in a climate effect
>>> temperature_feb
NormalDist(mu=10.0, sigma=6.830080526611674)

>>> temperature_feb * (9/5) + 32      # Convert to Fahrenheit
NormalDist(mu=50.0, sigma=12.294144947901014)
>>> temperature_feb.samples(3)        # Generate random samples
[7.672102882379219, 12.000027119750287, 4.647488369766392]

sys

Fügt die neue Funktion sys.unraisablehook() hinzu, die überschrieben werden kann, um die Behandlung von "nicht abfangbaren Ausnahmen" zu steuern. Sie wird aufgerufen, wenn eine Ausnahme aufgetreten ist, Python sie aber nicht behandeln kann. Zum Beispiel, wenn ein Destruktor eine Ausnahme auslöst oder während der Garbage Collection (gc.collect()). (Beigetragen von Victor Stinner in bpo-36829.)

tarfile

Das Modul tarfile verwendet nun standardmäßig das moderne pax-Format (POSIX.1-2001) für neue Archive anstelle des früheren GNU-spezifischen. Dies verbessert die plattformübergreifende Portabilität mit einer konsistenten Kodierung (UTF-8) in einem standardisierten und erweiterbaren Format und bietet mehrere weitere Vorteile. (Beigetragen von C.A.M. Gerlach in bpo-36268.)

threading

Fügt die neue Funktion threading.excepthook() hinzu, die unbehandelte Ausnahmen von threading.Thread.run() behandelt. Sie kann überschrieben werden, um zu steuern, wie unbehandelte Ausnahmen von threading.Thread.run() behandelt werden. (Beigetragen von Victor Stinner in bpo-1230540.)

Fügt die neue Funktion threading.get_native_id() und ein Attribut native_id zur Klasse threading.Thread hinzu. Diese geben die native integrale Thread-ID des aktuellen Threads zurück, die vom Kernel zugewiesen wurde. Diese Funktion ist nur auf bestimmten Plattformen verfügbar, siehe get_native_id für weitere Informationen. (Beigetragen von Jake Tesler in bpo-36084.)

tokenize

Das Modul tokenize gibt nun implizit ein NEWLINE-Token aus, wenn eine Eingabe ohne abschließenden Zeilenumbruch bereitgestellt wird. Dieses Verhalten entspricht nun dem, was der C-Tokenizer intern tut. (Beigetragen von Ammar Askar in bpo-33899.)

tkinter

Fügt die Methoden selection_from(), selection_present(), selection_range() und selection_to() in der Klasse tkinter.Spinbox hinzu. (Beigetragen von Juliette Monsel in bpo-34829.)

Fügt die Methode moveto() in der Klasse tkinter.Canvas hinzu. (Beigetragen von Juliette Monsel in bpo-23831.)

Die Klasse tkinter.PhotoImage hat nun die Methoden transparency_get() und transparency_set(). (Beigetragen von Zackery Spytz in bpo-25451.)

time

Fügt die neue Uhr CLOCK_UPTIME_RAW für macOS 10.12 hinzu. (Beigetragen von Joannah Nanjekye in bpo-35702.)

typing

Das Modul typing enthält mehrere neue Funktionen

  • Ein Wörterbuchtyp mit pro Schlüssel definierten Typen. Siehe PEP 589 und typing.TypedDict. TypedDict verwendet nur Zeichenketten als Schlüssel. Standardmäßig muss jeder Schlüssel vorhanden sein. Geben Sie „total=False“ an, um optionale Schlüssel zuzulassen.

    class Location(TypedDict, total=False):
        lat_long: tuple
        grid_square: str
        xy_coordinate: tuple
    
  • Literaltypen. Siehe PEP 586 und typing.Literal. Literaltypen geben an, dass ein Parameter oder Rückgabewert auf einen oder mehrere bestimmte Literale Werte beschränkt ist.

    def get_status(port: int) -> Literal['connected', 'disconnected']:
        ...
    
  • „Final“-Variablen, Funktionen, Methoden und Klassen. Siehe PEP 591, typing.Final und typing.final(). Der Final-Qualifier weist einen statischen Typ-Checker an, die Unterklassifizierung, das Überschreiben oder die Neuzuweisung einzuschränken.

    pi: Final[float] = 3.1415926536
    
  • Protokoll-Definitionen. Siehe PEP 544, typing.Protocol und typing.runtime_checkable(). Einfache ABCs wie typing.SupportsInt sind nun Protocol-Unterklassen.

  • Neue Protokollklasse typing.SupportsIndex.

  • Neue Funktionen typing.get_origin() und typing.get_args().

unicodedata

Das Modul unicodedata wurde aktualisiert, um die Veröffentlichung Unicode 12.1.0 zu verwenden.

Die neue Funktion is_normalized() kann verwendet werden, um zu überprüfen, ob eine Zeichenkette in einer bestimmten Normalform vorliegt, oft viel schneller als durch tatsächliche Normalisierung der Zeichenkette. (Beigetragen von Max Belanger, David Euresti und Greg Price in bpo-32285 und bpo-37966).

unittest

Fügt AsyncMock hinzu, um eine asynchrone Version von Mock zu unterstützen. Entsprechende neue Assert-Funktionen zum Testen wurden ebenfalls hinzugefügt. (Beigetragen von Lisa Roach in bpo-26467.)

Fügt addModuleCleanup() und addClassCleanup() zu unittest hinzu, um Bereinigungen für setUpModule() und setUpClass() zu unterstützen. (Beigetragen von Lisa Roach in bpo-24412.)

Mehrere Mock-Assert-Funktionen geben nun auch eine Liste der tatsächlichen Aufrufe bei einem Fehler aus. (Beigetragen von Petter Strandmark in bpo-35047.)

Das Modul unittest hat Unterstützung für Coroutinen als Testfälle mit unittest.IsolatedAsyncioTestCase erhalten. (Beigetragen von Andrew Svetlov in bpo-32972.)

Beispiel

import unittest


class TestRequest(unittest.IsolatedAsyncioTestCase):

    async def asyncSetUp(self):
        self.connection = await AsyncConnection()

    async def test_get(self):
        response = await self.connection.get("https://example.com")
        self.assertEqual(response.status_code, 200)

    async def asyncTearDown(self):
        await self.connection.close()


if __name__ == "__main__":
    unittest.main()

venv

venv enthält nun ein Skript Activate.ps1 auf allen Plattformen zum Aktivieren von virtuellen Umgebungen unter PowerShell Core 6.1. (Beigetragen von Brett Cannon in bpo-32718.)

weakref

Die von weakref.proxy() zurückgegebenen Proxy-Objekte unterstützen nun zusätzlich zu den anderen numerischen Operatoren die Matrixmultiplikationsoperatoren @ und @=. (Beigetragen von Mark Dickinson in bpo-36669.)

xml

Als Abhilfemaßnahme gegen das Abrufen von DTDs und externen Entitäten verarbeiten die Module xml.dom.minidom und xml.sax externe Entitäten standardmäßig nicht mehr. (Beigetragen von Christian Heimes in bpo-17239.)

Die Methoden .find*() im Modul xml.etree.ElementTree unterstützen Wildcard-Suchen wie {*}tag, die den Namespace ignorieren, und {namespace}*, die alle Tags im angegebenen Namespace zurückgeben. (Beigetragen von Stefan Behnel in bpo-28238.)

Das Modul xml.etree.ElementTree bietet die neue Funktion canonicalize(), die C14N 2.0 implementiert. (Beigetragen von Stefan Behnel in bpo-13611.)

Das Zielobjekt von xml.etree.ElementTree.XMLParser kann Namespace-Deklarationsereignisse über die neuen Callback-Methoden start_ns() und end_ns() empfangen. Zusätzlich kann der xml.etree.ElementTree.TreeBuilder Ziel konfiguriert werden, um Ereignisse zu Kommentaren und Verarbeitungsanweisungen zu verarbeiten, um sie in den generierten Baum aufzunehmen. (Beigetragen von Stefan Behnel in bpo-36676 und bpo-36673.)

xmlrpc

xmlrpc.client.ServerProxy unterstützt nun ein optionales Schlüsselwortargument headers für eine Sequenz von HTTP-Headern, die mit jeder Anfrage gesendet werden sollen. Dies ermöglicht unter anderem das Upgrade von der Standard-Basic-Authentifizierung auf eine schnellere Sitzungsauthentifizierung. (Beigetragen von Cédric Krier in bpo-35153.)

Optimierungen

  • Das Modul subprocess kann nun in einigen Fällen die Funktion os.posix_spawn() für eine bessere Leistung nutzen. Derzeit wird dies nur unter macOS und Linux (mit glibc 2.24 oder neuer) verwendet, wenn alle diese Bedingungen erfüllt sind

    • close_fds ist false;

    • die Parameter preexec_fn, pass_fds, cwd und start_new_session sind nicht gesetzt;

    • der Pfad executable enthält ein Verzeichnis.

    (Beigetragen von Joannah Nanjekye und Victor Stinner in bpo-35537.)

  • shutil.copyfile(), shutil.copy(), shutil.copy2(), shutil.copytree() und shutil.move() verwenden plattformspezifische „Fast-Copy“-Systemaufrufe unter Linux und macOS, um die Datei effizienter zu kopieren. „Fast-Copy“ bedeutet, dass der Kopiervorgang im Kernel stattfindet und die Verwendung von Benutzermodell-Puffern in Python vermieden wird, wie bei „outfd.write(infd.read())“. Unter Windows verwendet shutil.copyfile() eine größere Standardpuffergröße (1 MiB statt 16 KiB) und eine memoryview()-basierte Variante von shutil.copyfileobj() wird verwendet. Die Geschwindigkeitssteigerung beim Kopieren einer 512-MiB-Datei innerhalb derselben Partition beträgt etwa +26% unter Linux, +50% unter macOS und +40% unter Windows. Außerdem werden deutlich weniger CPU-Zyklen verbraucht. Siehe Abschnitt Plattformabhängige effiziente Kopiervorgänge. (Beigetragen von Giampaolo Rodolà in bpo-33671.)

  • shutil.copytree() verwendet die Funktion os.scandir() und alle davon abhängigen Kopierfunktionen verwenden gecachte os.stat()-Werte. Die Geschwindigkeitssteigerung beim Kopieren eines Verzeichnisses mit 8000 Dateien beträgt etwa +9% unter Linux, +20% unter Windows und +30% auf einer Windows SMB-Freigabe. Außerdem wird die Anzahl der os.stat()-Systemaufrufe um 38% reduziert, wodurch shutil.copytree() insbesondere auf Netzwerksystemen schneller wird. (Beigetragen von Giampaolo Rodolà in bpo-33695.)

  • Das Standardprotokoll im Modul pickle ist nun Protokoll 4, das erstmals in Python 3.4 eingeführt wurde. Es bietet eine bessere Leistung und eine geringere Größe im Vergleich zu Protokoll 3, das seit Python 3.0 verfügbar ist.

  • Ein Py_ssize_t-Mitglied aus PyGC_Head wurde entfernt. Die Größe aller GC-getrackten Objekte (z.B. Tupel, Listen, Wörterbücher) ist um 4 oder 8 Bytes reduziert. (Beigetragen von Inada Naoki in bpo-33597.)

  • uuid.UUID verwendet nun __slots__, um seinen Speicherbedarf zu reduzieren. (Beigetragen von Wouter Bolsterlee und Tal Einat in bpo-30977)

  • Verbesserte Leistung von operator.itemgetter() um 33%. Optimierte Argumentbehandlung und Hinzufügung eines Schnellwegs für den häufigen Fall eines einzelnen nicht-negativen Integer-Indexes in ein Tupel (was der typische Anwendungsfall in der Standardbibliothek ist). (Beigetragen von Raymond Hettinger in bpo-35664.)

  • Beschleunigte Feldabrufe in collections.namedtuple(). Sie sind jetzt mehr als doppelt so schnell und damit die schnellste Form des Instanzvariablenabrufs in Python. (Beigetragen von Raymond Hettinger, Pablo Galindo und Joe Jevnik, Serhiy Storchaka in bpo-32492.)

  • Der Konstruktor der list überweist den internen Elementpuffer nicht, wenn das Eingabe-Iterable eine bekannte Länge hat (die Eingabe implementiert __len__). Dies macht die erstellte Liste im Durchschnitt 12% kleiner. (Beigetragen von Raymond Hettinger und Pablo Galindo in bpo-33234.)

  • Verdoppelte Geschwindigkeit von Klassenvariablen-Schreibvorgängen. Wenn ein Nicht-Dunder-Attribut aktualisiert wurde, gab es einen unnötigen Aufruf zur Aktualisierung von Slots. (Beigetragen von Stefan Behnel, Pablo Galindo Salgado, Raymond Hettinger, Neil Schemenauer und Serhiy Storchaka in bpo-36012.)

  • Reduzierte Overhead bei der Konvertierung von Argumenten, die an viele eingebaute Funktionen und Methoden übergeben werden. Dies beschleunigte den Aufruf einiger einfacher eingebauter Funktionen und Methoden um bis zu 20–50%. (Beigetragen von Serhiy Storchaka in bpo-23867, bpo-35582 und bpo-36127.)

  • LOAD_GLOBAL-Instruktion verwendet jetzt einen neuen Mechanismus für „pro Opcode-Cache“. Dies ist etwa 40% schneller. (Beigetragen von Yury Selivanov und Inada Naoki in bpo-26219.)

Build- und C-API-Änderungen

  • Standardmäßig wurde sys.abiflags zu einem leeren String: das Flag m für pymalloc wurde nutzlos (Builds mit und ohne pymalloc sind ABI-kompatibel) und wurde daher entfernt. (Beigetragen von Victor Stinner in bpo-36707.)

    Beispiel für Änderungen

    • Nur das Programm python3.8 wird installiert, das Programm python3.8m ist verschwunden.

    • Nur das Skript python3.8-config wird installiert, das Skript python3.8m-config ist verschwunden.

    • Das Flag m wurde aus dem Suffix von dynamischen Bibliotheksdateinamen entfernt: Erweiterungsmodule in der Standardbibliothek sowie solche, die von Drittanbieterpaketen erstellt und installiert werden, z. B. von PyPI heruntergeladene. Unter Linux wurde beispielsweise das Suffix von Python 3.7 .cpython-37m-x86_64-linux-gnu.so in Python 3.8 zu .cpython-38-x86_64-linux-gnu.so.

  • Die Header-Dateien wurden neu organisiert, um die verschiedenen Arten von APIs besser zu trennen

    • Include/*.h sollte die portable öffentliche stabile C-API sein.

    • Include/cpython/*.h sollte die instabile C-API sein, die spezifisch für CPython ist; öffentliche API, mit einigen privaten APIs, die mit _Py oder _PY präfigiert sind.

    • Include/internal/*.h ist die private interne C-API, die sehr spezifisch für CPython ist. Diese API hat keine Garantie für Abwärtskompatibilität und sollte nicht außerhalb von CPython verwendet werden. Sie wird nur für sehr spezifische Bedürfnisse wie Debugger und Profiler bereitgestellt, die ohne Aufrufe von Funktionen auf CPython-Interna zugreifen müssen. Diese API wird jetzt mit make install installiert.

    (Beigetragen von Victor Stinner in bpo-35134 und bpo-35081, Arbeit initiiert von Eric Snow in Python 3.7.)

  • Einige Makros wurden in statische Inline-Funktionen konvertiert: Parametertypen und Rückgabetyp sind gut definiert, sie haben keine Makrospezifischen Probleme, Variablen haben einen lokalen Gültigkeitsbereich. Beispiele

    (Beigetragen von Victor Stinner in bpo-35059.)

  • Die Funktionen PyByteArray_Init() und PyByteArray_Fini() wurden entfernt. Sie taten nichts seit Python 2.7.4 und Python 3.2.0, wurden aus der begrenzten API (stabile ABI) ausgeschlossen und waren nicht dokumentiert. (Beigetragen von Victor Stinner in bpo-35713.)

  • Das Ergebnis von PyExceptionClass_Name() ist nun vom Typ const char * anstelle von char *. (Beigetragen von Serhiy Storchaka in bpo-33818.)

  • Die Dualität von Modules/Setup.dist und Modules/Setup wurde entfernt. Zuvor musste man beim Aktualisieren des CPython-Quellbaums manuell Modules/Setup.dist (innerhalb des Quellbaums) nach Modules/Setup (innerhalb des Build-Baums) kopieren, um Änderungen im Upstream widerzuspiegeln. Dies war ein kleiner Vorteil für Packager auf Kosten einer häufigen Belästigung von Entwicklern, die der CPython-Entwicklung folgen, da das Vergessen des Kopierens der Datei zu Build-Fehlern führen konnte.

    Jetzt liest das Build-System immer aus Modules/Setup im Quellbaum. Personen, die diese Datei anpassen möchten, werden ermutigt, ihre Änderungen in einem Git-Fork von CPython oder als Patchdateien zu pflegen, wie sie es für jede andere Änderung am Quellbaum tun würden.

    (Beigetragen von Antoine Pitrou in bpo-32430.)

  • Funktionen, die Python-Zahlen in C-Integer umwandeln, wie PyLong_AsLong() und Argument-Parsing-Funktionen wie PyArg_ParseTuple() mit Integer-konvertierenden Formateinheiten wie 'i', verwenden nun die spezielle Methode __index__() anstelle von __int__(), falls verfügbar. Eine Deprecation-Warnung wird für Objekte mit der Methode __int__(), aber ohne die Methode __index__() (wie Decimal und Fraction) ausgegeben. PyNumber_Check() gibt nun 1 für Objekte zurück, die __index__() implementieren. PyNumber_Long(), PyNumber_Float() und PyFloat_AsDouble() verwenden nun ebenfalls die Methode __index__(), falls verfügbar. (Beigetragen von Serhiy Storchaka in bpo-36048 und bpo-20092.)

  • Heap-allozierte Typobjekte erhöhen nun ihre Referenzanzahl in PyObject_Init() (und seiner parallelen Makro PyObject_INIT) anstatt in PyType_GenericAlloc(). Typen, die die Instanzallokation oder -deallokation ändern, müssen möglicherweise angepasst werden. (Beigetragen von Eddie Elizondo in bpo-35810.)

  • Die neue Funktion PyCode_NewWithPosOnlyArgs() ermöglicht die Erstellung von Code-Objekten wie PyCode_New(), jedoch mit einem zusätzlichen Parameter posonlyargcount zur Angabe der Anzahl der positionsabhängigen Argumente. (Beigetragen von Pablo Galindo in bpo-37221.)

  • Py_SetPath() setzt nun sys.executable auf den vollständigen Pfad des Programms (Py_GetProgramFullPath()) anstatt auf den Programmnamen (Py_GetProgramName()). (Beigetragen von Victor Stinner in bpo-38234.)

Veraltet

Entfernung von APIs und Features

Folgende Features und APIs wurden aus Python 3.8 entfernt

  • Seit Python 3.3 war der Import von ABCs aus collections veraltet, und der Import sollte aus collections.abc erfolgen. Der Import aus collections wurde für die Entfernung in 3.8 markiert, aber auf 3.9 verschoben. (Siehe gh-81134.)

  • Das Modul macpath, das in Python 3.7 veraltet war, wurde entfernt. (Beigetragen von Victor Stinner in bpo-35471.)

  • Die Funktion platform.popen() wurde entfernt, nachdem sie seit Python 3.3 veraltet war: verwenden Sie stattdessen os.popen(). (Beigetragen von Victor Stinner in bpo-35345.)

  • Die Funktion time.clock() wurde entfernt, nachdem sie seit Python 3.3 veraltet war: verwenden Sie stattdessen time.perf_counter() oder time.process_time(), je nach Ihren Anforderungen, um ein wohldefiniertes Verhalten zu haben. (Beigetragen von Matthias Bussonnier in bpo-36895.)

  • Das Skript pyvenv wurde zugunsten von python3.8 -m venv entfernt, um Verwirrung darüber zu vermeiden, an welchen Python-Interpreter das Skript pyvenv gebunden ist. (Beigetragen von Brett Cannon in bpo-25427.)

  • parse_qs, parse_qsl und escape werden aus dem Modul cgi entfernt. Sie sind in Python 3.2 oder älter veraltet. Sie sollten stattdessen aus den Modulen urllib.parse und html importiert werden.

  • filemode Funktion wurde aus dem tarfile-Modul entfernt. Sie war nicht dokumentiert und seit Python 3.3 veraltet.

  • Der Konstruktor von XMLParser akzeptiert das Argument html nicht mehr. Es hatte nie eine Auswirkung und war seit Python 3.4 veraltet. Alle anderen Parameter sind jetzt keyword-only. (Beigetragen von Serhiy Storchaka in bpo-29209.)

  • Entfernte die doctype()-Methode von XMLParser. (Beigetragen von Serhiy Storchaka in bpo-29209.)

  • Der "unicode_internal" Codec wurde entfernt. (Beigetragen von Inada Naoki in bpo-36297.)

  • Cache- und Statement-Objekte des sqlite3-Moduls werden dem Benutzer nicht mehr zugänglich gemacht. (Beigetragen von Aviv Palivoda in bpo-30262.)

  • Das Schlüsselwortargument bufsize von fileinput.input() und fileinput.FileInput(), das ignoriert und seit Python 3.6 veraltet war, wurde entfernt. bpo-36952 (Beigetragen von Matthias Bussonnier.)

  • Die Funktionen sys.set_coroutine_wrapper() und sys.get_coroutine_wrapper(), die in Python 3.7 als veraltet markiert wurden, wurden entfernt; bpo-36933 (Beigetragen von Matthias Bussonnier.)

Portierung auf Python 3.8

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

Verhaltensänderungen in Python

  • Yield-Ausdrücke (sowohl yield als auch yield from Klauseln) sind nun in Comprehensions und Generatorausdrücken (außer dem linken for-Ausdruck des Iterables) nicht mehr zulässig. (Beigetragen von Serhiy Storchaka in bpo-10544.)

  • Der Compiler gibt nun eine SyntaxWarning aus, wenn Identitätsprüfungen (is und is not) mit bestimmten Literalarten (z.B. Zeichenketten, Zahlen) verwendet werden. Diese können in CPython manchmal versehentlich funktionieren, sind aber nicht durch die Sprachspezifikation garantiert. Die Warnung rät Benutzern, stattdessen Gleichheitstests (== und !=) zu verwenden. (Beigetragen von Serhiy Storchaka in bpo-34850.)

  • Der CPython-Interpreter kann unter bestimmten Umständen Ausnahmen "verschlucken". In Python 3.8 passiert dies in weniger Fällen. Insbesondere werden Ausnahmen, die beim Abrufen eines Attributs aus dem Typwörterbuch ausgelöst werden, nicht mehr ignoriert. (Beigetragen von Serhiy Storchaka in bpo-35459.)

  • Entfernte __str__ Implementierungen aus eingebauten Typen bool, int, float, complex und einigen Klassen aus der Standardbibliothek. Sie erben nun __str__() von object. Infolgedessen wirkt sich die Definition der Methode __repr__() in Unterklassen dieser Klassen auf ihre String-Repräsentation aus. (Beigetragen von Serhiy Storchaka in bpo-36793.)

  • Auf AIX enthält sys.platform nicht mehr die Hauptversion. Es ist immer 'aix' statt 'aix3' .. 'aix7'. Da ältere Python-Versionen die Versionsnummer enthalten, wird empfohlen, immer sys.platform.startswith('aix') zu verwenden. (Beigetragen von M. Felt in bpo-36588.)

  • PyEval_AcquireLock() und PyEval_AcquireThread() beenden nun den aktuellen Thread, wenn sie aufgerufen werden, während der Interpreter finalisiert, was sie mit PyEval_RestoreThread(), Py_END_ALLOW_THREADS() und PyGILState_Ensure() konsistent macht. Wenn dieses Verhalten nicht gewünscht ist, sollte der Aufruf durch Überprüfung von _Py_IsFinalizing() oder sys.is_finalizing() geschützt werden. (Beigetragen von Joannah Nanjekye in bpo-36475.)

Änderungen in der Python-API

  • Die Funktion os.getcwdb() verwendet unter Windows nun die UTF-8-Kodierung anstelle der ANSI-Codepage: siehe PEP 529 für die Begründung. Die Funktion ist unter Windows nicht mehr veraltet. (Beigetragen von Victor Stinner in bpo-37412.)

  • subprocess.Popen kann nun in einigen Fällen os.posix_spawn() zur Leistungssteigerung verwenden. Unter Windows Subsystem für Linux und QEMU User Emulation löst der Popen-Konstruktor mit os.posix_spawn() bei Fehlern wie "missing program" keine Ausnahme mehr aus. Stattdessen schlägt der Kindprozess mit einem nicht-null returncode fehl. (Beigetragen von Joannah Nanjekye und Victor Stinner in bpo-35537.)

  • Das Argument preexec_fn von * subprocess.Popen ist nicht mehr mit Subinterpretern kompatibel. Die Verwendung des Parameters in einem Subinterpreter löst nun eine RuntimeError aus. (Beigetragen von Eric Snow in bpo-34651, geändert von Christian Heimes in bpo-37951.)

  • Die Methode imaplib.IMAP4.logout() ignoriert willkürliche Ausnahmen nicht mehr stillschweigend. (Beigetragen von Victor Stinner in bpo-36348.)

  • Die Funktion platform.popen() wurde entfernt, nachdem sie seit Python 3.3 veraltet war: verwenden Sie stattdessen os.popen(). (Beigetragen von Victor Stinner in bpo-35345.)

  • Die Funktion statistics.mode() löst bei multimodalen Daten keine Ausnahme mehr aus. Stattdessen gibt sie den ersten im Eingabedatum gefundenen Modus zurück. (Beigetragen von Raymond Hettinger in bpo-35892.)

  • Die Methode selection() der Klasse tkinter.ttk.Treeview akzeptiert keine Argumente mehr. Die Verwendung mit Argumenten zur Änderung der Auswahl war in Python 3.6 veraltet. Verwenden Sie spezialisierte Methoden wie selection_set(), um die Auswahl zu ändern. (Beigetragen von Serhiy Storchaka in bpo-31508.)

  • Die Methoden writexml(), toxml() und toprettyxml() von xml.dom.minidom und die Methode write() von xml.etree.ElementTree behalten nun die vom Benutzer angegebene Attributreihenfolge bei. (Beigetragen von Diego Rojas und Raymond Hettinger in bpo-34160.)

  • Eine mit Flags 'r' geöffnete dbm.dumb-Datenbank ist nun schreibgeschützt. dbm.dumb.open() mit Flags 'r' und 'w' erstellt keine Datenbank mehr, wenn sie nicht existiert. (Beigetragen von Serhiy Storchaka in bpo-32749.)

  • Die in einer Unterklasse von XMLParser definierte Methode doctype() wird nicht mehr aufgerufen und gibt stattdessen eine RuntimeWarning anstelle einer DeprecationWarning aus. Definieren Sie die Methode doctype() auf einem Ziel, um eine XML-Dokumenttypdeklaration zu behandeln. (Beigetragen von Serhiy Storchaka in bpo-29209.)

  • Es wird nun eine RuntimeError ausgelöst, wenn die benutzerdefinierte Metaklasse den Eintrag __classcell__ im an type.__new__ übergebenen Namespace nicht bereitstellt. In Python 3.6–3.7 wurde dafür eine DeprecationWarning ausgegeben. (Beigetragen von Serhiy Storchaka in bpo-23722.)

  • Die Klasse cProfile.Profile kann nun als Kontextmanager verwendet werden. (Beigetragen von Scott Sanderson in bpo-29235.)

  • shutil.copyfile(), shutil.copy(), shutil.copy2(), shutil.copytree() und shutil.move() verwenden plattformspezifische "fast-copy"-Systemaufrufe (siehe Abschnitt Plattformabhängige effiziente Kopiervorgänge).

  • Die Standardpuffergröße von shutil.copyfile() unter Windows wurde von 16 KiB auf 1 MiB geändert.

  • Die PyGC_Head-Struktur wurde komplett geändert. Jeglicher Code, der auf die Strukturmember zugegriffen hat, muss überarbeitet werden. (Siehe bpo-33597.)

  • Die PyInterpreterState-Struktur wurde in die "internen" Header-Dateien verschoben (speziell Include/internal/pycore_pystate.h). Ein opaker PyInterpreterState ist weiterhin als Teil der öffentlichen API (und der stabilen ABI) verfügbar. Die Dokumentation gibt an, dass keiner der Felder der Struktur öffentlich ist, daher hoffen wir, dass niemand sie verwendet hat. Wenn Sie jedoch von einem oder mehreren dieser privaten Felder abhängen und keine Alternative haben, eröffnen Sie bitte ein BPO-Issue. Wir werden Ihnen bei der Anpassung helfen (möglicherweise auch durch Hinzufügen von Zugriffsfunktionen zur öffentlichen API). (Siehe bpo-35886.)

  • Die Methode mmap.flush() gibt nun unter allen Plattformen bei Erfolg None zurück und löst bei einem Fehler eine Ausnahme aus. Zuvor war ihr Verhalten plattformabhängig: Unter Windows wurde bei Erfolg ein Wert ungleich Null zurückgegeben; unter Unix wurde bei Erfolg Null zurückgegeben und bei einem Fehler eine Ausnahme ausgelöst. (Beigetragen von Berker Peksag in bpo-2122.)

  • Die Module xml.dom.minidom und xml.sax verarbeiten externe Entitäten nicht mehr standardmäßig. (Beigetragen von Christian Heimes in bpo-17239.)

  • Das Löschen eines Schlüssels aus einer schreibgeschützten dbm-Datenbank (dbm.dumb, dbm.gnu oder dbm.ndbm) löst nun error (dbm.dumb.error, dbm.gnu.error oder dbm.ndbm.error) anstelle von KeyError aus. (Beigetragen von Xiang Zhang in bpo-33106.)

  • Vereinfachtes AST für Literale. Alle Konstanten werden als Instanzen von ast.Constant dargestellt. Das Instanziieren alter Klassen Num, Str, Bytes, NameConstant und Ellipsis gibt eine Instanz von Constant zurück. (Beigetragen von Serhiy Storchaka in bpo-32892.)

  • os.path.expanduser() unter Windows bevorzugt nun die Umgebungsvariable USERPROFILE und verwendet nicht HOME, die für normale Benutzerkonten normalerweise nicht gesetzt ist. (Beigetragen von Anthony Sottile in bpo-36264.)

  • Die Ausnahme asyncio.CancelledError erbt nun von BaseException anstatt von Exception und erbt nicht mehr von concurrent.futures.CancelledError. (Beigetragen von Yury Selivanov in bpo-32528.)

  • Die Funktion asyncio.wait_for() wartet nun korrekt auf die Aufhebung, wenn eine Instanz von asyncio.Task verwendet wird. Zuvor wurde sie nach Erreichen des timeoute abgebrochen und sofort zurückgegeben. (Beigetragen von Elvis Pranskevichus in bpo-32751.)

  • Die Funktion asyncio.BaseTransport.get_extra_info() gibt nun ein sicher zu verwendendes Socket-Objekt zurück, wenn 'socket' als Parameter name übergeben wird. (Beigetragen von Yury Selivanov in bpo-37027.)

  • asyncio.BufferedProtocol ist nun Teil der stabilen API.

  • DLL-Abhängigkeiten für Erweiterungsmodule und mit ctypes geladene DLLs werden unter Windows nun sicherer aufgelöst. Nur die Systempfade, das Verzeichnis, das die DLL- oder PYD-Datei enthält, und mit add_dll_directory() hinzugefügte Verzeichnisse werden nach Ladezeitabhängigkeiten durchsucht. Insbesondere werden PATH und das aktuelle Arbeitsverzeichnis nicht mehr verwendet, und Änderungen daran haben keine Auswirkungen mehr auf die normale DLL-Auflösung. Wenn Ihre Anwendung auf diese Mechanismen angewiesen ist, sollten Sie nach add_dll_directory() suchen und, falls vorhanden, es zum Hinzufügen Ihres DLL-Verzeichnisses beim Laden Ihrer Bibliothek verwenden. Beachten Sie, dass Windows 7-Benutzer sicherstellen müssen, dass Windows Update KB2533623 installiert ist (dies wird auch vom Installer überprüft). (Beigetragen von Steve Dower in bpo-36085.)

  • Die Header-Dateien und Funktionen im Zusammenhang mit pgen wurden nach seinem Ersatz durch eine reine Python-Implementierung entfernt. (Beigetragen von Pablo Galindo in bpo-36623.)

  • types.CodeType hat einen neuen Parameter an zweiter Position des Konstruktors (posonlyargcount), um positionsabhängige Argumente zu unterstützen, die in PEP 570 definiert sind. Das erste Argument (argcount) stellt nun die Gesamtzahl der positionsabhängigen Argumente (einschließlich positionsabhängiger Argumente) dar. Die neue Methode replace() von types.CodeType kann verwendet werden, um den Code zukunftssicher zu machen.

  • Der Parameter digestmod für hmac.new() verwendet standardmäßig nicht mehr die MD5-Digest.

Änderungen in der C-API

  • Die Struktur PyCompilerFlags hat ein neues Feld cf_feature_version erhalten. Es sollte mit PY_MINOR_VERSION initialisiert werden. Das Feld wird standardmäßig ignoriert und nur dann verwendet, wenn das Flag PyCF_ONLY_AST in cf_flags gesetzt ist. (Beigetragen von Guido van Rossum in bpo-35766.)

  • Die Funktion PyEval_ReInitThreads() wurde aus der C-API entfernt. Sie sollte nicht explizit aufgerufen werden: Verwenden Sie stattdessen PyOS_AfterFork_Child(). (Beigetragen von Victor Stinner in bpo-36728.)

  • Unter Unix werden C-Erweiterungen nicht mehr gegen libpython gelinkt, außer unter Android und Cygwin. Wenn Python eingebettet wird, darf libpython nicht mit RTLD_LOCAL geladen werden, sondern stattdessen mit RTLD_GLOBAL. Zuvor war es mit RTLD_LOCAL bereits nicht möglich, C-Erweiterungen zu laden, die nicht gegen libpython gelinkt waren, wie z.B. C-Erweiterungen der Standardbibliothek, die im Abschnitt *shared* von Modules/Setup erstellt wurden. (Beigetragen von Victor Stinner in bpo-21536.)

  • Die Verwendung von #-Varianten von Formaten beim Parsen oder Erstellen von Werten (z.B. PyArg_ParseTuple(), Py_BuildValue(), PyObject_CallFunction(), etc.) ohne PY_SSIZE_T_CLEAN gibt nun eine DeprecationWarning aus. Sie wird in 3.10 oder 4.0 entfernt. Lesen Sie Argumente parsen und Werte erstellen für Details. (Beigetragen von Inada Naoki in bpo-36381.)

  • Instanzen von heap-allokierten Typen (wie z.B. die mit PyType_FromSpec() erstellten) halten eine Referenz auf ihr Typobjekt. Die Erhöhung des Referenzzählers dieser Typobjekte wurde von PyType_GenericAlloc() auf die niedrigeren Funktionen PyObject_Init() und PyObject_INIT verlagert. Dies lässt Typen, die über PyType_FromSpec() erstellt werden, wie andere Klassen in verwaltetem Code agieren.

    Statisches Typsystem sind nicht betroffen.

    In den allermeisten Fällen sollte es keine Nebenwirkungen geben. Typen, die nach der Allokation einer Instanz manuell den Referenzzähler erhöhen (vielleicht zur Umgehung des Fehlers), können nun unsterblich werden. Um dies zu vermeiden, müssen diese Klassen Py_DECREF auf dem Typobjekt während der Instanzdeallokation aufrufen.

    Um diese Typen korrekt für 3.8 zu portieren, führen Sie bitte folgende Änderungen durch:

    • Entfernen Sie Py_INCREF auf dem Typobjekt nach der Allokation einer Instanz – falls vorhanden. Dies kann nach dem Aufruf von PyObject_New, PyObject_NewVar, PyObject_GC_New(), PyObject_GC_NewVar() oder einem anderen benutzerdefinierten Allokator, der PyObject_Init() oder PyObject_INIT verwendet.

      Beispiel

      static foo_struct *
      foo_new(PyObject *type) {
          foo_struct *foo = PyObject_GC_New(foo_struct, (PyTypeObject *) type);
          if (foo == NULL)
              return NULL;
      #if PY_VERSION_HEX < 0x03080000
          // Workaround for Python issue 35810; no longer necessary in Python 3.8
          PY_INCREF(type)
      #endif
          return foo;
      }
      
    • Stellen Sie sicher, dass alle benutzerdefinierten tp_dealloc-Funktionen von heap-allokierten Typen den Referenzzähler des Typs verringern.

      Beispiel

      static void
      foo_dealloc(foo_struct *instance) {
          PyObject *type = Py_TYPE(instance);
          PyObject_GC_Del(instance);
      #if PY_VERSION_HEX >= 0x03080000
          // This was not needed before Python 3.8 (Python issue 35810)
          Py_DECREF(type);
      #endif
      }
      

    (Beigetragen von Eddie Elizondo in bpo-35810.)

  • Das Makro Py_DEPRECATED() wurde für MSVC implementiert. Das Makro muss nun vor dem Symbolnamen platziert werden.

    Beispiel

    Py_DEPRECATED(3.8) PyAPI_FUNC(int) Py_OldFunction(void);
    

    (Beigetragen von Zackery Spytz in bpo-33407.)

  • Der Interpreter gibt nicht mehr vor, die Binärkompatibilität von Erweiterten Typen über Feature-Releases hinweg zu unterstützen. Ein von einem Drittanbieter-Erweiterungsmodul exportiertes PyTypeObject muss alle Slots aufweisen, die in der aktuellen Python-Version erwartet werden, einschließlich tp_finalize ( Py_TPFLAGS_HAVE_FINALIZE wird nicht mehr überprüft, bevor tp_finalize gelesen wird).

    (Beigetragen von Antoine Pitrou in bpo-32388.)

  • Die Funktionen PyNode_AddChild() und PyParser_AddToken() akzeptieren nun zwei zusätzliche int-Argumente end_lineno und end_col_offset.

  • Die Datei libpython38.a, die es MinGW-Tools ermöglicht, direkt gegen python38.dll zu linken, ist nicht mehr Teil der regulären Windows-Distribution. Wenn Sie diese Datei benötigen, kann sie mit den Werkzeugen gendef und dlltool generiert werden, die Teil des MinGW binutils-Pakets sind.

    gendef - python38.dll > tmp.def
    dlltool --dllname python38.dll --def tmp.def --output-lib libpython38.a
    

    Der Speicherort einer installierten pythonXY.dll hängt von den Installationsoptionen sowie der Version und Sprache von Windows ab. Weitere Informationen finden Sie unter Verwendung von Python unter Windows. Die resultierende Bibliothek sollte im selben Verzeichnis wie pythonXY.lib abgelegt werden, was im Allgemeinen das Verzeichnis libs unter Ihrer Python-Installation ist.

    (Beigetragen von Steve Dower in bpo-37351.)

CPython Bytecode-Änderungen

  • Die Interpreter-Schleife wurde vereinfacht, indem die Logik des Entrollens des Blockstapels in den Compiler verschoben wurde. Der Compiler gibt nun explizite Anweisungen zum Anpassen des Wertestapels und zum Aufrufen des Aufräumcodes für break, continue und return aus.

    Entfernte Opcodes BREAK_LOOP, CONTINUE_LOOP, SETUP_LOOP und SETUP_EXCEPT. Neue Opcodes ROT_FOUR, BEGIN_FINALLY, CALL_FINALLY und POP_FINALLY hinzugefügt. Das Verhalten von END_FINALLY und WITH_CLEANUP_START geändert.

    (Beigetragen von Mark Shannon, Antoine Pitrou und Serhiy Storchaka in bpo-17611.)

  • Neuer Opcode END_ASYNC_FOR zum Behandeln von Ausnahmen hinzugefügt, die beim Warten auf das nächste Element in einer async for-Schleife ausgelöst werden. (Beigetragen von Serhiy Storchaka in bpo-33041.)

  • MAP_ADD erwartet nun den Wert als erstes Element des Stacks und den Schlüssel als zweites Element. Diese Änderung wurde vorgenommen, damit der Schlüssel in Dictionary Comprehensions immer vor dem Wert ausgewertet wird, wie von PEP 572 vorgeschlagen. (Beigetragen von Jörn Heissler in bpo-35224.)

Demos und Tools

Ein Benchmark-Skript zum Messen verschiedener Methoden des Zugriffs auf Variablen wurde hinzugefügt: Tools/scripts/var_access_benchmark.py. (Beigetragen von Raymond Hettinger in bpo-35884.)

Hier ist eine Zusammenfassung der Leistungsverbesserungen seit Python 3.3

Python version                       3.3     3.4     3.5     3.6     3.7     3.8
--------------                       ---     ---     ---     ---     ---     ---

Variable and attribute read access:
    read_local                       4.0     7.1     7.1     5.4     5.1     3.9
    read_nonlocal                    5.3     7.1     8.1     5.8     5.4     4.4
    read_global                     13.3    15.5    19.0    14.3    13.6     7.6
    read_builtin                    20.0    21.1    21.6    18.5    19.0     7.5
    read_classvar_from_class        20.5    25.6    26.5    20.7    19.5    18.4
    read_classvar_from_instance     18.5    22.8    23.5    18.8    17.1    16.4
    read_instancevar                26.8    32.4    33.1    28.0    26.3    25.4
    read_instancevar_slots          23.7    27.8    31.3    20.8    20.8    20.2
    read_namedtuple                 68.5    73.8    57.5    45.0    46.8    18.4
    read_boundmethod                29.8    37.6    37.9    29.6    26.9    27.7

Variable and attribute write access:
    write_local                      4.6     8.7     9.3     5.5     5.3     4.3
    write_nonlocal                   7.3    10.5    11.1     5.6     5.5     4.7
    write_global                    15.9    19.7    21.2    18.0    18.0    15.8
    write_classvar                  81.9    92.9    96.0   104.6   102.1    39.2
    write_instancevar               36.4    44.6    45.8    40.0    38.9    35.5
    write_instancevar_slots         28.7    35.6    36.1    27.3    26.6    25.7

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

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

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

Timing loop:
    loop_overhead                    0.3     0.5     0.6     0.4     0.3     0.3

Die Benchmarks wurden auf einem Intel® Core™ i7-4960HQ Prozessor unter macOS 64-Bit-Builds von python.org gemessen. Das Benchmark-Skript zeigt die Zeiten in Nanosekunden an.

Bemerkenswerte Änderungen in Python 3.8.1

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 bei 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.)

Bemerkenswerte Änderungen in Python 3.8.2

Ein Regression mit dem ignore Callback von shutil.copytree() behoben. Die Argumenttypen sind wieder str und List[str]. (Beigetragen von Manuel Barkhau und Giampaolo Rodola in gh-83571.)

Bemerkenswerte Änderungen in Python 3.8.3

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

Bemerkenswerte Änderungen in Python 3.8.8

Frühere Python-Versionen erlaubten die Verwendung von ; und & als Trennzeichen für Query-Parameter 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 zu erlauben, wobei & der Standard ist. Diese Änderung betrifft auch cgi.parse() und cgi.parse_multipart(), da diese intern die betroffenen Funktionen verwenden. Weitere Einzelheiten finden Sie in der jeweiligen Dokumentation. (Beigetragen von Adam Goldschmidt, Senthil Kumaran und Ken Jin in bpo-42967.)

Bemerkenswerte Änderungen in Python 3.8.9

Ein Sicherheitsupdate ändert das Verhalten von ftplib.FTP, so dass die IPv4-Adresse, die vom Remote-Server beim Einrichten eines passiven Datenkanals gesendet wird, nicht mehr vertraut wird. Stattdessen wird die IP-Adresse des FTP-Servers 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.8.10

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

Ab Python 3.8.10 unterstützt Python das Erstellen und Ausführen auf macOS 11 (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 von ausführbaren Dateien zu unterstützen. Beachten Sie, dass die Unterstützung für "weaklinking", das Erstellen von Binärdateien, die für neuere macOS-Versionen bestimmt sind und auch auf älteren Versionen korrekt funktionieren, indem zur Laufzeit auf fehlende Funktionen geprüft wird, nicht in diesem Backport von Python 3.9 enthalten ist. Um eine Reihe von macOS-Versionen zu unterstützen, zielen Sie weiterhin auf die älteste Version in der Reihe ab und erstellen Sie darauf.

(Ursprünglich beigetragen von Ronald Oussoren und Lawrence D’Anna in gh-85272, mit Korrekturen von FX Coudert und Eli Rykoff, und zurückportiert auf 3.8 von Maxime Bélanger und Ned Deily)

Bemerkenswerte Änderungen in Python 3.8.10

urllib.parse

Das Vorhandensein von Zeilenumbruch- oder Tabulatorzeichen in Teilen einer URL ermöglicht bestimmte Angriffsformen. Gemäß der WHATWG-Spezifikation, die RFC 3986 aktualisiert, werden ASCII-Zeilenumbruchs- (\n, \r) und Tabulatorzeichen (\t) von dem 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 bpo-43882)

Bemerkenswerte Änderungen in Python 3.8.12

Änderungen in der Python-API

Ab Python 3.8.12 akzeptiert das Modul ipaddress keine führenden Nullen mehr in IPv4-Adressstrings. Führende Nullen sind mehrdeutig und werden von einigen Bibliotheken als Oktalnotation interpretiert. Die Legacy-Funktion socket.inet_aton() beispielsweise behandelt führende Nullen als Oktalnotation. Die glibc-Implementierung der modernen Funktion inet_pton() akzeptiert keine führenden Nullen.

(Ursprünglich beigetragen von Christian Heimes in bpo-36384 und zurückportiert auf 3.8 von Achraf Merzouki.)

Bemerkenswerte Sicherheitsfunktion in 3.8.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 eine Umgebungsvariable, ein Kommandozeilenflag oder sys-APIs konfiguriert oder deaktiviert werden. Siehe die Dokumentation zur Beschränkung der Längenbegrenzung für die Integer-String-Konvertierung. Das Standardlimit beträgt 4300 Ziffern in Zeichenform.

Bemerkenswerte Änderungen in 3.8.17

tarfile

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