След една година разработка, значителен выпуск на езика за програмиране Python 3.10 беше представен. Новата версия ще бъде поддържана в продължение на година и половина, след което ще бъдат предоставяни корекции за уязвимости в продължение на още три години и половина.
В същото време започна алфа-тестиране на версията Python 3.11 (според новия график за разработка, работата по новата версия започва пет месеца преди пускането на предишната версия и в момента на следващото пускане достига етапа на алфа-тестиране). Версията Python 3.11 ще бъде в етап алфа-релизи в продължение на седем месеца, през които ще бъдат добавяни нови функции и ще се поправят грешки. След това, за период от три месеца, ще се провеждат бета-тестове, по време на които добавянето на нови функции ще бъде забранено и цялото внимание ще бъде насочено към корекция на грешки. Последните два месеца преди пускането версията ще бъде в етап кандидат за пускане, в който ще се извърши финалната стабилизация.
Сред нововъведенията в Python 3.10 са:
- Реализирани са операторите „match“ и „case“ за съответствие с образец, които подобряват четимостта на кода, опростяват съвпадението на произволни Python обекти и увеличават надеждността на кода чрез възможността за разширена статична проверка на типовете. Реализацията много напомня на оператора „match“, предоставян в езици като Scala, Rust и F#, който извършва сравнение на резултата от изпълнението на посоченото изразяване с списък от образци, изброени в блоковете на базата на оператора „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"
Възможно е разопаковане на обекти, кортеджи, списъци и произволни последователности за привързване на променливи на основата на наличните стойности. Допуска се определяне на вложени шаблони, използване на допълнителни условия «if» в шаблона, приложение на маски («[x, y, *rest]»), маппинг на свързани ключ/стойност (например, {«bandwidth»: b, «latency»: l} за извличане на стойностите «bandwidth» и «latency» от речника), извличане на подплотове (оператор «:=»), използване на именувани константи в шаблона. В класове е възможна настройка на поведението при съвпадение чрез метода «__match__()».
from dataclasses import dataclass @dataclass class Point: x: int y: int def whereis(point): match point: case Point(0, 0): print(«Origin») case Point(0, y): print(f»Y={y}») case Point(x, 0): print(f»X={x}») case Point(): print(«Somewhere else») case _: print(«Not a point») match point: case Point(x, y) if x == y: print(f»Y=X at {x}») case Point(x, y): print(f»Not on the diagonal») RED, GREEN, BLUE = 0, 1, 2 match color: case RED: print(«I see red!») case GREEN: print(«Grass is green») case BLUE: print(«I’m feeling the blues :(«)
- Предоставена е възможност за използване на кръгли скоби в оператора with за разпределение на определения на колекция от контекстни мениджъри на няколко реда. Включително е разрешено да се остави запетая след последния контекстен мениджър в групата: with ( CtxManager1() as example1, CtxManager2() as example2, CtxManager3() as example3, ): …
- Подобренo е информираността относно местоположението на кодови грешки, свързани с незатворени фигурни скоби и кавички в стрингови литерали. Например, при незатворена фигурна скоба, вместо информираност за синтактична грешка в следващата конструкция, указателят сега подсветява отварящата фигурна скоба и информира за липсата на затварящ блок. 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
Добавени са допълнителни специализирани съобщения за грешки в синтаксиса: липсващ символ «:» преди блока и в речниците, неизолиране на кортежа в скоби, липса на запетая в списъците, указване на блока «try» без «except» и «finally», използване на «=» вместо «==» в сравненията, указване на *-изрази в f-стрингове. Освен това, осигурено е изолиране на цялото проблемно изразяване, а не само на неговото начало, и по-явно информирано за контекста на грешките, свързани с неправилно разположение на отстъпите. >>> def foo(): … if lel: … x = 2 File «», line 3 x = 2 ^ IndentationError: expected an indented block after ‘if’ statement in line 2
При грешки, причинени от печатни грешки в имената на атрибутите и променливите в функция, е осигурен изход на препоръка с правилното име. >>> collections.namedtoplo Traceback (most recent call last): File «», line 1, in AttributeError: module ‘collections’ has no attribute ‘namedtoplo’. Did you mean: namedtuple?
- За отладъчните инструменти и профилировчиците е осигурено указване в събитията на трасировка на точни номера на редовете на изпълнения код.
- Добавена е настройка sys.flags.warn_default_encoding за извеждане на предупреждение за потенциални грешки, свързани с обработката в TextIOWrapper и open() файлове в кодировка UTF-8 без явно указване на опцията ‘encoding="utf-8"‘ (по подразбиране се използва кодировка ASCII). Освен това в новото издание е предоставена възможност за указване на стойността ‘encoding="locale"‘ за задаване на кодировката на базата на текущата локализация.
- В модула typing, който предоставя средства за задаване на анотации на типове, е добавен нов оператор, позволяващ използването на синтаксиса «X | Y» за избор на един от типовете (тип X или тип Y). def square(number: int | float) -> int | float: return number ** 2 еквивалентно на преди поддържаната конструкция: def square(number: Union[int, float]) -> Union[int, float]: return number ** 2
- В модула typing е добавен оператор Concatenate и променлива ParamSpec, които позволяват предаване на допълнителна информация за статична проверка на типовете при използване на Callable. В модула typing също са добавени специални стойности TypeGuard за анотиране на функции за защита на типовете и TypeAlias за явно определяне на псевдоним на тип. StrCache: TypeAlias = ‘Cache[str]’ # a type alias
- Във функцията zip() е реализиран незадължителен флаг „strict“, при указването на който се извършва проверка за еднаква дължина на аргументите. >>> 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 is longer than argument 1
- Предложени са нови вградени функции aiter() и anext() с реализация на асинхронни аналози на функциите iter() и next().
- Ускорена е работата на конструкциите str(), bytes() и bytearray() с 30-40% при работа с малки обекти.
- Скъсен е броят операции за импорт в модула runpy. Команда „python3 -m име_на_модула“ сега се изпълнява средно с 1.4 пъти по-бързо благодарение на намаления брой на импортируемите модули от 69 на 51.
- В инструкцията LOAD_ATTR е активиран механизъм за кеширане на отделни опкоди, което е позволило да се ускори работата с обикновени атрибути до 36%, а със слот до 44%.
- При компилиране на Python с опцията „—enable-optimizations“ сега се активира режим „-fno-semantic-interposition“, позволяващ увеличаване на производителността на интерпретатора с до 30% в сравнение с компилация с опцията „—enable-shared“.
- В модулите hashlib и ssl е добавена поддръжка на OpenSSL 3.0.0 и е прекратена поддръжката на версии на OpenSSL по-стари от 1.1.1.
- Старият парсер е премахнат, на негово място в предишната версия е внедрен парсер PEG (Parsing Expression Grammar). Премахнат е модулът formatter. От API asyncio е премахнат параметърът loop. Премахнати са методи, преди това обявени за остарели. Премахнати са функциите Py_UNICODE_str*, манипулиращи строки Py_UNICODE*.
- Модулът distutils е обявен за остарял, като планирано за изтриване в Python 3.12. Вместо distutils се препоръчва използването на модулите setuptools, packaging, platform, shutil, subprocess и sysconfig. В списъка на остарелите и планирани за изтриване е включена структурата wstr в PyUnicodeObject.
Източник: opennet.ru
