Seria o zmianach w Pythonie od 3.8 do 3.15, przy każdej wersji z wybranymi nowościami. Pierwsza część obejmuje wersje 3.8 i 3.9: operator :=, parametry tylko pozycyjne, operator | dla słowników i moduł zoneinfo.

Operator przypisania w wyrażeniu :=

Wersja3.8
KategoriaSkładnia
PEPPEP 572
OpisOperator „walrus” pozwala przypisać wartość wewnątrz warunku if, pętli while czy comprehension, bez osobnej linii.
data = [3, 8, 1, 9]
if (n := len(data)) > 3:
    print(f"Za dużo elementów: {n}")      # Za dużo elementów: 4

while (line := input("> ")) != "koniec":
    print(line.upper())

squares = [y for x in data if (y := x * x) > 10]   # [64, 81]

Parametry tylko pozycyjne

Wersja3.8
KategoriaSkładnia
PEPPEP 570
OpisParametry przed / nie mogą być przekazane po nazwie, więc autor biblioteki może je później przemianować bez łamania API.
def clamp(value, /, low=0, high=100):
    return max(low, min(value, high))

clamp(150)              # 100
clamp(150, high=120)    # 120
clamp(value=150)        # TypeError: clamp() got some positional-only arguments passed as keyword arguments: 'value'

Specyfikator = w f-stringach

Wersja3.8
KategoriaSkładnia
PEP—
Opisf"{x=}" wypisuje nazwę wyrażenia i jego wartość, co przydaje się przy szybkim debugowaniu.
x, y = 3, 4
print(f"{x=}, {y=}")         # x=3, y=4
print(f"{x * y = }")         # x * y = 12
print(f"{3.14159=:.2f}")     # 3.14159=3.14

importlib.metadata

Wersja3.8
KategoriaBiblioteka
PEP—
OpisOdczyt wersji i metadanych zainstalowanych pakietów.
from importlib.metadata import version, requires

version("requests")     # '2.32.3'
requires("requests")    # ['charset_normalizer<4,>=2', 'idna<4,>=2.5', ...]

typing.Literal

Wersja3.8
KategoriaTypowanie
PEPPEP 586
OpisTyp dopuszczający tylko wymienione wartości, np. konkretne napisy lub liczby.
from typing import Literal

def set_mode(mode: Literal["r", "w"]) -> None: ...

set_mode("r")       # OK
set_mode("x")       # type checker: "x" nie należy do Literal["r", "w"]

typing.Final

Wersja3.8
KategoriaTypowanie
PEPPEP 591
OpisOznaczenie stałej, której nie wolno ponownie przypisać. Dekorator @final blokuje dziedziczenie po klasie lub nadpisanie metody.
from typing import Final, final

MAX_RETRIES: Final = 3
MAX_RETRIES = 5         # type checker: nie można przypisać do stałej Final

@final
class Config: ...

class MyConfig(Config): ...   # type checker: Config jest final

typing.Protocol

Wersja3.8
KategoriaTypowanie
PEPPEP 544
OpisTypowanie strukturalne („duck typing”): klasa pasuje do protokołu, jeśli ma wymagane metody, bez dziedziczenia po nim.
from typing import Protocol

class Closable(Protocol):
    def close(self) -> None: ...

class Connection:                   # nie dziedziczy po Closable
    def close(self) -> None:
        print("zamknięte")

def shutdown(resource: Closable) -> None:
    resource.close()

shutdown(Connection())              # OK: Connection ma metodę close()
shutdown("tekst")                   # type checker: str nie ma close()

typing.TypedDict

Wersja3.8
KategoriaTypowanie
PEPPEP 589
OpisSłownik o ustalonych kluczach, każdy z własnym typem. Przydaje się przy danych z JSON-a.
from typing import TypedDict

class User(TypedDict):
    name: str
    age: int

user: User = {"name": "Ala", "age": 30}     # OK
bad: User = {"name": "Ala", "age": "30"}    # type checker: age musi być int

functools.cached_property

Wersja3.8
KategoriaBiblioteka
PEP—
OpisWłaściwość liczona raz i zapamiętywana w instancji.
from functools import cached_property

class Report:
    def __init__(self, rows):
        self.rows = rows

    @cached_property
    def total(self) -> int:
        print("liczę...")
        return sum(self.rows)

r = Report([1, 2, 3])
r.total     # liczę... 6
r.total     # 6 (bez ponownego liczenia)

math.prod(), math.isqrt(), math.dist()

Wersja3.8
KategoriaBiblioteka
PEP—
OpisIloczyn elementów, całkowity pierwiastek kwadratowy i odległość euklidesowa między punktami.
import math

math.prod([2, 3, 4])           # 24
math.isqrt(17)                 # 4
math.dist((0, 0), (3, 4))      # 5.0

multiprocessing.shared_memory

Wersja3.8
KategoriaBiblioteka
PEP—
OpisPamięć współdzielona między procesami bez kopiowania danych.
from multiprocessing import shared_memory

shm = shared_memory.SharedMemory(create=True, size=4)
shm.buf[:4] = b"abcd"

# w innym procesie: dostęp po nazwie bloku
other = shared_memory.SharedMemory(name=shm.name)
bytes(other.buf[:4])    # b'abcd'

other.close()
shm.close()
shm.unlink()

REPL asyncio

Wersja3.8
KategoriaBiblioteka
PEP—
Opispython -m asyncio uruchamia REPL, w którym działa await na najwyższym poziomie.
$ python -m asyncio
>>> import asyncio
>>> await asyncio.sleep(1, result="gotowe")
'gotowe'

Operatory | i |= dla słowników

Wersja3.9
KategoriaSkładnia
PEPPEP 584
OpisŁączenie słowników bez {**a, **b} i bez dict.update().
defaults = {"host": "localhost", "port": 5432}
config = defaults | {"port": 6543}    # {'host': 'localhost', 'port': 6543}

defaults |= {"user": "admin"}         # modyfikacja w miejscu
defaults    # {'host': 'localhost', 'port': 5432, 'user': 'admin'}

Generyki wbudowanych kolekcji

Wersja3.9
KategoriaTypowanie
PEPPEP 585
Opislist[int], dict[str, float] działają bez importu List i Dict z typing.
def average(values: list[float]) -> dict[str, float]:
    return {"avg": sum(values) / len(values)}

point: tuple[int, int] = (3, 4)
tags: set[str] = {"python", "typing"}

Swobodniejsze dekoratory

Wersja3.9
KategoriaSkładnia
PEPPEP 614
OpisDekoratorem może być dowolne wyrażenie, np. @buttons[0].clicked.connect.
from functools import cache, lru_cache

caches = {"bez_limitu": cache, "maly": lru_cache(maxsize=16)}

@caches["maly"]          # przed 3.9: SyntaxError
def square(n: int) -> int:
    return n * n

str.removeprefix() i str.removesuffix()

Wersja3.9
KategoriaBiblioteka
PEPPEP 616
OpisW odróżnieniu od strip() usuwają cały ciąg, a nie zbiór znaków.
"test_settings.py".removeprefix("test_")    # 'settings.py'
"test_settings.py".lstrip("test_")          # 'ings.py' (usuwa znaki t, e, s, _)
"raport.csv".removesuffix(".csv")           # 'raport'

zoneinfo

Wersja3.9
KategoriaBiblioteka
PEPPEP 615
OpisStrefy czasowe IANA w bibliotece standardowej, bez pytz. Na Windowsie wymaga pakietu tzdata z PyPI.
from datetime import datetime
from zoneinfo import ZoneInfo

meeting = datetime(2026, 3, 30, 15, 0, tzinfo=ZoneInfo("Europe/Warsaw"))
print(meeting.astimezone(ZoneInfo("America/New_York")))
# 2026-03-30 09:00:00-04:00

graphlib.TopologicalSorter

Wersja3.9
KategoriaBiblioteka
PEP—
OpisSortowanie topologiczne grafu zależności.
from graphlib import TopologicalSorter

deps = {
    "app": ["db", "cache"],
    "db": ["config"],
    "cache": ["config"],
}
list(TopologicalSorter(deps).static_order())
# ['config', 'db', 'cache', 'app']

functools.cache

Wersja3.9
KategoriaBiblioteka
PEP—
OpisZapamiętywanie wyników funkcji. To lru_cache(maxsize=None) pod krótszą nazwą, bez limitu rozmiaru.
from functools import cache

@cache
def fib(n: int) -> int:
    return n if n < 2 else fib(n - 1) + fib(n - 2)

fib(80)                 # 23416728348467685, natychmiast
fib.cache_info()        # CacheInfo(hits=78, misses=81, maxsize=None, currsize=81)

math.lcm()

Wersja3.9
KategoriaBiblioteka
PEP—
OpisNajmniejsza wspólna wielokrotność. Przy okazji math.gcd() zaczął przyjmować dowolną liczbę argumentów.
import math

math.lcm(4, 6, 10)      # 60
math.gcd(12, 18, 24)    # 6 (od 3.9 przyjmuje dowolną liczbę argumentów)

typing.Annotated

Wersja3.9
KategoriaTypowanie
PEPPEP 593
OpisDołączanie metadanych do typu, np. Annotated[int, Gt(0)]. Korzystają z tego m.in. Pydantic i FastAPI.
from typing import Annotated, get_type_hints

Port = Annotated[int, "zakres 1–65535"]

def connect(port: Port) -> None: ...

get_type_hints(connect, include_extras=True)["port"]
# typing.Annotated[int, 'zakres 1–65535']

Parser PEG

Wersja3.9
KategoriaInterpreter
PEPPEP 617
OpisNowy parser stał się domyślny w miejsce parsera LL(1), który usunięto w 3.10. Sam w sobie nie zmienił języka, ale umożliwił składnię z kolejnych wersji, w tym match w 3.10.