Po roku prac zaprezentowano znaczące wydanie języka programowania Python 3.10. Nowa gałąź będzie wspierana przez półtora roku, po czym przez kolejne trzy i pół roku będą tworzone poprawki eliminujące luki bezpieczeństwa.
Jednocześnie rozpoczęło się testowanie alfa gałęzi Python 3.11 (zgodnie z nowym harmonogramem rozwoju prace nad nową gałęzią zaczynają się pięć miesięcy przed wydaniem poprzedniej gałęzi, a do momentu kolejnego wydania osiąga ona etap testów alfa). Gałąź Python 3.11 będzie na etapie wydań alfa przez siedem miesięcy, w trakcie których będą dodawane nowe funkcjonalności i naprawiane błędy. Następnie przez trzy miesiące prowadzone będą testy wersji beta, w trakcie których dodawanie nowych funkcji będzie zabronione, a cała uwaga skupi się na naprawie błędów. Ostatnie dwa miesiące przed wydaniem gałąź będzie na etapie kandydata do wydania, podczas którego nastąpi finalizacja stabilizacji.
Wśród nowości dodanych do Python 3.10 znajdują się:
- Wprowadzono operatorzy „match” i „case” do porównywania wzorców, które pozwalają poprawić czytelność kodu, uprościć dopasowanie dowolnych obiektów Python oraz zwiększyć niezawodność kodu dzięki możliwości zaawansowanej statycznej weryfikacji typów. Realizacja w dużej mierze przypomina operator „match” dostępny w językach Scala, Rust i F#, który porównuje wynik wykonania określonego wyrażenia z listą wzorców wymienionych w blokach opartych na operatorze „case”.
def http_error(status): match status: case 400: return "Bad request" case 401|403|404: return "Not allowed" case 418: return "I’m a teapot" case _: return "Something else"
Możliwe jest rozpakowywanie obiektów, krotek, list i dowolnych sekwencji do przypisania zmiennych na podstawie istniejących wartości. Dopuszcza się definiowanie zagnieżdżonych wzorców, użycie dodatkowych warunków "if" w wzorcu, stosowanie masek ("[x, y, *rest]"), mapowanie par klucz/wartość (na przykład, {"bandwidth": b, "latency": l} do wyodrębnienia wartości "bandwidth" i "latency" z słownika), wyciąganie podwzorców (operator ":="), użycie nazwanych stałych w wzorcu. W klasach możliwa jest konfiguracja zachowania przy dopasowaniu za pomocą metody "__match__()".
from dataclasses import dataclass @dataclass class Point: x: int y: int def whereis(point): match point: case Point(0, 0): print("Początek") case Point(0, y): print(f"Y={y}") case Point(x, 0): print(f"X={x}") case Point(): print("Gdzie indziej") case _: print("Nie jest punktem") match point: case Point(x, y) if x == y: print(f"Y=X w {x}") case Point(x, y): print(f"Nie na przekątnej") RED, GREEN, BLUE = 0, 1, 2 match color: case RED: print("Widzę czerwony!") case GREEN: print("Trawa jest zielona") case BLUE: print("Czuję smutek :( ")
- Umożliwiono użycie nawiasów okrągłych w operatorze with do rozdzielenia na kilka linii definicji zbioru menedżerów kontekstu. W tym także dozwolone jest pozostawienie przecinka po ostatnim menedżerze kontekstu w grupie: with ( CtxManager1() as example1, CtxManager2() as example2, CtxManager3() as example3, ): …
- Udoskonalone informowanie o lokalizacji w kodzie błędów związanych z niezamkniętymi klamrami i cudzysłowami w literałach stringowych. Na przykład, zamiast informować o błędzie składni w następującej konstrukcji przy niezamkniętej klamrze, wskaźnik teraz podświetla otwierającą klamrę i informuje o braku zamykającego bloku. File "example.py", line 1 expected = {9: 1, 18: 2, 19: 2, 27: 3, 28: 3, 29: 3, 36: 4, 37: 4, ^ SyntaxError: '{' was never closed
Dodano dodatkowe, specjalistyczne komunikaty o błędach składni: brak znaku „:” przed blokiem oraz w słownikach, niedostateczne wydzielenie krotki nawiasami, brak przecinka w listach, określenie bloku „try” bez „except” i „finally”, użycie „=” zamiast „==” w porównaniach, wskazania wyrażeń * w f-stringach. Ponadto zapewniono wydzielenie całego problematycznego wyrażenia, a nie tylko jego początku oraz bardziej wyraźne informowanie o kontekście błędów związanych z niewłaściwym wcięciem. >>> def foo(): … if lel: … x = 2 Plik „”, linia 3 x = 2 ^ IndentationError: oczekiwano wciętego bloku po instrukcji „if” w linii 2
W błędach spowodowanych literówkami w nazwach atrybutów i nazwach zmiennych w funkcji dodano zalecenie z poprawną nazwą. >>> collections.namedtoplo Traceback (najświeższe wywołanie ostatnie): Plik „”, linia 1, w AttributeError: moduł ‘collections’ nie ma atrybutu ‘namedtoplo’. Czy miałeś na myśli: namedtuple?
- Dla narzędzi debugujących i profilerów zapewniono wskazanie w zdarzeniach śledzenia dokładnych numerów linii wykonanego kodu.
- Dodano ustawienie sys.flags.warn_default_encoding do wyświetlania ostrzeżenia o potencjalnych błędach związanych z przetwarzaniem w TextIOWrapper i open() plików w kodowaniu UTF-8 bez jawnego określenia opcji ‘encoding=„utf-8”‘ (domyślnie używane jest kodowanie ASCII). W nowym wydaniu dodano także możliwość określenia wartości ‘encoding=„locale”‘, aby ustawić kodowanie na podstawie aktualnej lokalizacji.
- Do modułu typing, który zapewnia narzędzia do ustalania adnotacji typów, dodano nowy operator umożliwiający użycie składni „X | Y” do wyboru jednego z typów (typ X lub typ Y). def square(number: int | float) -> int | float: return number ** 2 jest równoważne wcześniej wspieranej konstrukcji: def square(number: Union[int, float]) -> Union[int, float]: return number ** 2
- Do modułu typing dodano operator Concatenate oraz zmienną ParamSpec, które pozwalają przekazywać dodatkowe informacje do statycznej weryfikacji typów przy użyciu Callable. Do modułu typing dodano również specjalne wartości TypeGuard do adnotacji funkcji ochrony typów oraz TypeAlias do wyraźnego określenia aliasu typu. StrCache: TypeAlias = ‘Cache[str]’ # alias typu
- W funkcji zip() wprowadzono opcjonalny flag „strict”, której ustawienie umożliwia sprawdzenie, czy przetwarzane argumenty mają tę samą długość. >>> list(zip((‘a’, ‘b’, ‘c’), (1, 2, 3), strict=True)) [(‘a’, 1), (‘b’, 2), (‘c’, 3)] >>> list(zip(range(3), [‘fee’, ‘fi’, ‘fo’, ‘fum’], strict=True)) Traceback (most recent call last): … ValueError: zip() argument 2 jest dłuższy niż argument 1
- Wprowadzone nowe funkcje wbudowane aiter() i anext() z implementacją asynchronicznych odpowiedników funkcji iter() i next().
- Przyspieszono działanie konstruktorów str(), bytes() i bytearray() o 30-40% podczas pracy z małymi obiektami.
- Skrócono liczbę operacji importu w module runpy. Komenda „python3 -m nazwa_modułu” jest teraz uruchamiana średnio 1,4 razy szybciej dzięki zmniejszeniu importowanych modułów z 69 do 51.
- W instrukcji LOAD_ATTR wprowadzono mechanizm pamięci podręcznej dla poszczególnych opkodów, co pozwoliło przyspieszyć pracę z typowymi atrybutami o 36%, a ze slotami o 44%.
- Podczas kompilacji Pythona z opcją „—enable-optimizations” teraz włączany jest tryb „-fno-semantic-interposition”, co pozwala w porównaniu z kompilacją z opcją „—enable-shared” przyspieszyć działanie interpretera o 30%.
- W modułach hashlib i ssl dodano wsparcie dla OpenSSL 3.0.0 i zakończono wsparcie dla wersji OpenSSL starszych niż 1.1.1.
- Usunięto stary parser, który został zastąpiony przez parser PEG (Parsing Expression Grammar). Usunięto moduł formatter. Z API asyncio usunięto parametr loop. Usunięto metody, które wcześniej zostały oznaczone jako przestarzałe. Usunięto funkcje Py_UNICODE_str*, manipulujące łańcuchami Py_UNICODE*.
- Ogłoszono przestarzałym moduł distutils, który ma być usunięty w Pythonie 3.12. Zamiast distutils zaleca się użycie modułów setuptools, packaging, platform, shutil, subprocess i sysconfig. Wśród przestarzałych i planowanych do usunięcia znalazła się struktura wstr w PyUnicodeObject.
Źródło: opennet.ru
