Содержание страницы
Что нового в Python 3.8¶What’s New In Python 3.8
- Редактор:
Raymond Hettinger
В этой статье описаны новые возможности Python 3.8 по сравнению с 3.7. Python 3.8 был выпущен 14 октября 2019 года. Полные сведения см. в журнале изменений.
Краткий обзор – основные изменения выпуска¶Summary – Release highlights
Новые возможности¶New Features
Выражения присваивания¶Assignment expressions
Появился новый синтаксис :=, который присваивает значения переменным внутри более крупного выражения. Его ласково называют «оператором моржа» из-за сходства с глазами и клыками моржа.
В этом примере выражение присваивания помогает избежать двукратного вызова len():
if (n := len(a)) > 10:
print(f"List is too long ({n} elements, expected <= 10)")
Аналогичное преимущество возникает при сопоставлении с регулярным выражением, когда объект совпадения нужен дважды: один раз для проверки, было ли совпадение, и второй раз для извлечения подгруппы:
discount = 0.0
if (mo := re.search(r'(\d+)% discount', advertisement)):
discount = float(mo.group(1)) / 100.0
Оператор также полезен в циклах while, которые вычисляют значение для проверки условия завершения цикла, а затем снова используют это же значение в теле цикла:
# Цикл по блокам фиксированной длины
while (block := f.read(256)) != '':
process(block)
Ещё один мотивирующий пример – списковые включения, где значение, вычисленное в условии фильтрации, также требуется в теле выражения:
[clean_name.title() for name in names
if (clean_name := normalize('NFC', name)) in allowed_names]
Следует ограничивать использование оператора моржа только теми случаями, которые снижают сложность и повышают читаемость.
См. PEP 572 для полного описания.
(Предложено Emily Morehouse в bpo-35224.)
Только позиционные параметры¶Positional-only parameters
Появился новый синтаксис параметров функции /, который указывает, что некоторые параметры функции должны задаваться позиционно и не могут использоваться в качестве именованных аргументов. Это та же нотация, что показывается help() для C-функций, аннотированных с помощью инструмента Argument Clinic Ларри Хастингса.
В следующем примере параметры a и b являются только позиционными, c или d могут быть позиционными или именованными, а e или f должны быть именованными:
def f(a, b, /, c, d, *, e, f):
print(a, b, c, d, e, f)
Следующий вызов допустим:
f(10, 20, 30, d=40, e=50, f=60)
Однако следующие вызовы некорректны:
f(10, b=20, c=30, d=40, e=50, f=60) # b не может быть именованным аргументом
f(10, 20, 30, 40, 50, f=60) # e должен быть именованным аргументом
Один из вариантов использования этой нотации – она позволяет чистым функциям Python полностью эмулировать поведение существующих функций, написанных на C. Например, встроенная функция divmod() не принимает именованных аргументов:
def divmod(a, b, /):
"Emulate the built in divmod() function"
return (a // b, a % b)
Другой случай – запрет именованных аргументов, когда имя параметра не несет смысловой нагрузки. Например, встроенная функция len() имеет сигнатуру len(obj, /). Это предотвращает неудобные вызовы вроде:
len(obj='hello') # Именованный аргумент "obj" ухудшает читаемость
Ещё одно преимущество пометки параметра как только позиционного – возможность в будущем изменить имя параметра без риска сломать клиентский код. Например, в модуле statistics имя параметра dist может быть изменено в будущем. Это стало возможным благодаря следующему описанию функции:
def quantiles(dist, /, *, n=4, method='exclusive')
...
Поскольку параметры слева от / не раскрываются как возможные ключевые слова, их имена остаются доступными для использования в **kwargs:
>>> def f(a, b, /, **kwargs):
... print(a, b, kwargs)
...
>>> f(10, 20, a=1, b=2, c=3) # a и b используются двумя способами
10 20 {'a': 1, 'b': 2, 'c': 3}
Это значительно упрощает реализацию функций и методов, которым нужно принимать произвольные именованные аргументы. Например, вот выдержка из кода модуля collections:
class Counter(dict):
def __init__(self, iterable=None, /, **kwds):
# Примечание: «iterable» может быть именованным аргументом
Полное описание см. в PEP 570.
(Автор: Pablo Galindo в bpo-36540.)
Параллельный кэш файловой системы для скомпилированных файлов байт-кода¶Parallel filesystem cache for compiled bytecode files
Новый параметр PYTHONPYCACHEPREFIX (также доступен как -X pycache_prefix) настраивает неявный кэш байт-кода на использование отдельного параллельного дерева файловой системы вместо подкаталогов __pycache__ по умолчанию внутри каждого исходного каталога.
Расположение кэша сообщается в sys.pycache_prefix (None указывает расположение по умолчанию в подкаталогах __pycache__).
(Автор: Carl Meyer в bpo-33499.)
Отладочная сборка использует тот же ABI, что и обычная сборка¶Debug build uses the same ABI as release build
ABI отладочных сборок Python теперь совместим с ABI обычных сборок Python. В Unix, когда Python собран в отладочном режиме, теперь можно загружать расширения на C, собранные в обычном режиме, и расширения на C, собранные со стабильным ABI. Обратное неверно, так как отладочные сборки предоставляют дополнительные символы, недоступные в обычных сборках.
Определение макроса Py_DEBUG больше не подразумевает макрос Py_TRACE_REFS, что вносит единственную несовместимость ABI. Макрос Py_TRACE_REFS, который добавляет функцию sys.getobjects() и переменную окружения PYTHONDUMPREFS, может быть установлен с помощью нового параметра сборки ./configure
--with-trace-refs. (Автор: Victor Stinner в bpo-36465.)
В Unix расширения на C больше не линкуются с libpython, за исключением Android и Cygwin. Теперь стало возможным для статически слинкованного Python загружать расширение на C, собранное с использованием разделяемой библиотеки Python. (Автор: Victor Stinner в bpo-21536.)
В Unix, когда Python собран в отладочном режиме, оператор import теперь также ищет расширения на C, скомпилированные в обычном режиме, и расширения на C, скомпилированные со стабильным ABI. (Автор: Victor Stinner в bpo-36722.)
Чтобы встроить Python в приложение, необходимо передать новый параметр --embed в python3-config --libs --embed для получения -lpython3.8 (линковка приложения с libpython). Для поддержки как 3.8, так и более старых версий, сначала попробуйте python3-config --libs
--embed, а в случае неудачи – python3-config --libs (без --embed).
Добавлен модуль pkg-config python-3.8-embed для встраивания Python в приложение: pkg-config python-3.8-embed --libs включает -lpython3.8. Для поддержки как 3.8, так и более старых версий, сначала попробуйте pkg-config python-X.Y-embed --libs, а в случае неудачи – pkg-config python-X.Y --libs (без --embed), заменив X.Y на версию Python.
С другой стороны, pkg-config python3.8 --libs больше не содержит -lpython3.8. Расширения на C не должны линковаться с libpython (за исключением Android и Cygwin, чьи случаи обрабатываются скриптом); это изменение намеренно нарушает обратную совместимость. (Автор: Victor Stinner в bpo-36721.)
f-строки поддерживают = для самодокументируемых выражений и отладки¶f-strings support = for self-documenting expressions and debugging
Добавлен спецификатор = для f-строк. F-строка вида f'{expr=}' будет разворачиваться в текст выражения, знак равенства, а затем представление вычисленного выражения. Например:
>>> import datetime as dt
>>> user = 'eric_idle'
>>> member_since = dt.date(1975, 7, 31)
>>> f'{user=} {member_since=}'
"user='eric_idle' member_since=datetime.date(1975, 7, 31)"
Обычные спецификаторы формата f-строк позволяют лучше контролировать отображение результата выражения:
>>> delta = dt.date.today() - member_since
>>> f'{user=!s} {delta.days=:,d}'
'user=eric_idle delta.days=16,075'
Спецификатор = отображает всё выражение, чтобы можно было показать вычисления:
>>> print(f'{theta=} {cos(radians(theta))=:.3f}')
theta=30 cos(radians(theta))=0.866
(Авторы: Eric V. Smith и Larry Hastings в bpo-36817.)
PEP 578: Хуки аудита времени выполнения Python¶PEP 578: Python Runtime Audit Hooks
В PEP добавляются Audit Hook и Verified Open Hook. Оба доступны из Python и нативного кода, что позволяет приложениям и фреймворкам, написанным на чистом Python, получать дополнительные уведомления, а также позволяет разработчикам, встраивающим Python, или системным администраторам разворачивать сборки Python, в которых аудит всегда включён.
Подробности см. в PEP 578.
PEP 587: Конфигурация инициализации Python¶PEP 587: Python Initialization Configuration
PEP 587 добавляет новый C API для настройки инициализации Python, обеспечивая более тонкий контроль над всей конфигурацией и улучшенное сообщение об ошибках.
Новые структуры:
Новые функции:
Этот PEP также добавляет поля _PyRuntimeState.preconfig (тип PyPreConfig)
и PyInterpreterState.config (тип PyConfig) в эти
внутренние структуры. PyInterpreterState.config становится новой
эталонной конфигурацией, заменяя глобальные переменные конфигурации и
другие приватные переменные.
См. Python Initialization Configuration в документации.
Полное описание см. в PEP 587.
(Предложено Виктором Стиннером в bpo-36763.)
PEP 590: Vectorcall: быстрый протокол вызова для CPython¶PEP 590: Vectorcall: a fast calling protocol for CPython
В Python/C API добавлен протокол Vectorcall. Он предназначен для формализации существующих оптимизаций, которые уже были выполнены для различных классов. Любой статический тип, реализующий вызываемый объект, может использовать этот протокол.
В настоящее время это экспериментальная возможность. Цель – сделать её полностью общедоступной в Python 3.9.
Полное описание см. в PEP 590.
(Предложено Jeroen Demeyer, Mark Shannon и Petr Viktorin в bpo-36974.)
Протокол Pickle 5 с внеполосными буферами данных¶Pickle protocol 5 with out-of-band data buffers
Когда pickle используется для передачи больших данных между процессами Python
для использования многоядерной или многомашинной обработки,
важно оптимизировать передачу, уменьшая количество копирований памяти, и
возможно применяя пользовательские методы, такие как сжатие, зависящее от данных.
Протокол pickle 5 вводит поддержку внеполосных буферов,
где данные, совместимые с PEP 3118, могут передаваться отдельно от
основного потока pickle, по усмотрению коммуникационного уровня.
Полное описание см. в PEP 574.
(Предложено Antoine Pitrou в bpo-36785.)
Прочие изменения языка ¶Other Language Changes
Оператор
continueбыл недопустим в предложенииfinallyиз-за проблемы в реализации. В Python 3.8 это ограничение было снято. (Предложено Сергеем Сторчакой в bpo-32489.)Типы
bool,intиfractions.Fractionтеперь имеют методas_integer_ratio(), как уfloatиdecimal.Decimal. Это небольшое расширение API позволяет писатьnumerator, denominator = x.as_integer_ratio()и использовать его с различными числовыми типами. (Предложено Lisa Roach в bpo-33073 и Raymond Hettinger в bpo-37819.)Конструкторы
int,floatиcomplexтеперь будут использовать специальный метод__index__(), если он доступен, а соответствующий метод__int__(),__float__()или__complex__()недоступен. (Предложено Сергеем Сторчакой в bpo-20092.)Добавлена поддержка экранирующих последовательностей
\N{name}вregular expressions:>>> notice = 'Copyright © 2019' >>> copyright_year_pattern = re.compile(r'\N{copyright sign}\s*(\d{4})') >>> int(copyright_year_pattern.search(notice).group(1)) 2019
(Предложено Jonathan Eunice и Сергеем Сторчакой в bpo-30688.)
Словари и представления словарей теперь можно перебирать в обратном порядке вставки с помощью
reversed(). (Предложено Rémi Lapeyre в bpo-33462.)Синтаксис, разрешённый для имён ключевых аргументов в вызовах функций, был дополнительно ограничен. В частности,
f((keyword)=arg)больше не допускается. Никогда не предполагалось разрешать более одного простого имени в левой части присваивания ключевого аргумента. (Предложено Benjamin Peterson в bpo-34641.)Обобщённая распаковка итерируемых объектов в операторах
yieldиreturnбольше не требует заключения в скобки. Это приводит синтаксис yield и return в большее соответствие с обычным синтаксисом присваивания:>>> def parse(family): ... lastname, *members = family.split() ... return lastname.upper(), *members ... >>> parse('simpsons homer marge bart lisa maggie') ('SIMPSONS', 'homer', 'marge', 'bart', 'lisa', 'maggie')
(Предложено David Cuthbert и Jordan Chapman в bpo-32117.)
Когда в коде пропущена запятая, например, в
[(10, 20) (30, 40)], компилятор выводитSyntaxWarningс полезной подсказкой. Это улучшает ситуацию по сравнению с простым сообщениемTypeError, указывающим, что первый кортеж не был вызываемым. (Предложено Сергеем Сторчакой в bpo-15248.)Арифметические операции между подклассами
datetime.dateилиdatetime.datetimeи объектамиdatetime.timedeltaтеперь возвращают экземпляр подкласса, а не базового класса. Это также влияет на тип возвращаемого значения операций, реализация которых (прямо или косвенно) использует арифметикуdatetime.timedelta, например,astimezone(). (Предложено Paul Ganssle в bpo-32417.)Когда интерпретатор Python прерывается по Ctrl-C (SIGINT) и возникающее исключение
KeyboardInterruptне перехватывается, процесс Python теперь завершается через сигнал SIGINT или с правильным кодом возврата, так что вызывающий процесс может обнаружить, что он завершился из-за Ctrl-C. Оболочки на POSIX и Windows используют это для корректного завершения скриптов в интерактивных сеансах. (Предложено Google через Gregory P. Smith в bpo-1054041.)Некоторые продвинутые стили программирования требуют обновления объекта
types.CodeTypeдля существующей функции. Поскольку объекты кода неизменяемы, необходимо создать новый объект кода, который моделируется на основе существующего. С 19 параметрами это было довольно утомительно. Теперь новый методreplace()позволяет создать клон с несколькими изменёнными параметрами.Вот пример, который изменяет функцию
statistics.mean(), чтобы предотвратить использование параметра data в качестве ключевого аргумента:>>> 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'
(Предложено Victor Stinner в bpo-37032.)
Для целых чисел трёхаргументная форма функции
pow()теперь допускает отрицательный показатель степени, если основание является взаимно простым с модулем. Затем она вычисляет модульную инверсию основания, когда показатель равен-1, и соответствующую степень этой инверсии для других отрицательных показателей. Например, чтобы вычислить модульную мультипликативную инверсию числа 38 по модулю 137, напишите:>>> pow(38, -1, 137) 119 >>> 119 * 38 % 137 1
Модульные инверсии возникают при решении линейных диофантовых уравнений. Например, чтобы найти целочисленные решения для
4258𝑥 + 147𝑦 = 369, сначала перепишите как4258𝑥 ≡ 369 (mod 147), затем решите:>>> x = 369 * pow(4258, -1, 147) % 147 >>> y = (4258 * x - 369) // -147 >>> 4258 * x + 147 * y 369
(Предложено Mark Dickinson в bpo-36027.)
Генераторы словарей синхронизированы со словарными литералами: сначала вычисляется ключ, а затем значение:
>>> # Генератор словаря >>> cast = {input('role? '): input('actor? ') for i in range(2)} role? King Arthur actor? Chapman role? Black Knight actor? Cleese >>> # Литерал словаря >>> cast = {input('role? '): input('actor? ')} role? Sir Robin actor? Eric Idle
Гарантированный порядок выполнения полезен для выражений присваивания: переменные, присвоенные в выражении ключа, будут доступны в выражении значения:
>>> 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'}
(Автор: Jörn Heissler в bpo-35224.)
Метод
object.__reduce__()теперь может возвращать кортеж длиной от двух до шести элементов. Ранее пределом было пять. Новый, необязательный шестой элемент представляет собой вызываемый объект с сигнатурой(obj, state). Это позволяет напрямую управлять поведением обновления состояния конкретного объекта. Если значение не равно None, этот вызываемый объект будет иметь приоритет над методом__setstate__()объекта. (Авторы: Pierre Glaser и Olivier Grisel в bpo-35900.)
Новые модули ¶New Modules
Новый модуль
importlib.metadataпредоставляет (временную) поддержку для чтения метаданных из сторонних пакетов. Например, он может извлечь номер версии установленного пакета, список точек входа и другое:>>> # Примечание: следующий пример требует, чтобы популярный пакет "requests" >>> # был установлен. >>> >>> 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')]
(Авторы: Barry Warsaw и Jason R. Coombs в bpo-34632.)
Улучшенные модули¶Improved Modules
ast¶
Узлы AST теперь имеют атрибуты end_lineno и end_col_offset, которые указывают точное местоположение конца узла. (Это применимо только к узлам, имеющим атрибуты lineno и col_offset.)
Новая функция ast.get_source_segment() возвращает исходный код для конкретного узла AST.
(Автор: Ivan Levkivskyi в bpo-33416.)
Функция ast.parse() получила несколько новых флагов:
type_comments=Trueзаставляет её возвращать текст PEP 484 и PEP 526 комментариев типов, связанных с определёнными узлами AST;mode='func_type'можно использовать для разбора PEP 484 «комментариев типов сигнатур» (возвращаемых для узлов AST определения функций);feature_version=(3, N)позволяет указать более раннюю версию Python 3. Например,feature_version=(3, 4)будет рассматриватьasyncиawaitкак незарезервированные слова.
(Автор: Guido van Rossum в bpo-35766.)
asyncio¶
asyncio.run() перешёл из временного в стабильный API. Эта функция может использоваться для выполнения корутины и возврата результата с автоматическим управлением циклом событий. Например:
import asyncio
async def main():
await asyncio.sleep(0)
return 42
asyncio.run(main())
Это примерно эквивалентно:
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()
Фактическая реализация значительно сложнее. Поэтому asyncio.run() должен быть предпочтительным способом запуска asyncio-программ.
(Автор: Yury Selivanov в bpo-32314.)
Запуск python -m asyncio запускает нативно асинхронную REPL. Это позволяет быстро экспериментировать с кодом, содержащим await на верхнем уровне. Больше нет необходимости напрямую вызывать asyncio.run(), который при каждом вызове создавал новый цикл событий:
$ 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
(Автор: Yury Selivanov в bpo-37028.)
Исключение asyncio.CancelledError теперь наследуется от BaseException, а не от Exception, и больше не наследуется от concurrent.futures.CancelledError.
(Автор: Yury Selivanov в bpo-32528.)
В Windows цикл событий по умолчанию теперь ProactorEventLoop.
(Автор: Victor Stinner в bpo-34687.)
ProactorEventLoop теперь также поддерживает UDP.
(Авторы: Adam Meily и Andrew Svetlov в bpo-29883.)
ProactorEventLoop теперь можно прервать с помощью KeyboardInterrupt («CTRL+C»).
(Автор: Vladimir Matveev в bpo-23057.)
Добавлен asyncio.Task.get_coro() для получения обёрнутой корутины внутри asyncio.Task.
(Автор: Alex Grönholm в bpo-36999.)
Задачам asyncio теперь можно задавать имена: либо передав именованный аргумент name в asyncio.create_task() или метод create_task() цикла событий, либо вызвав метод set_name() у объекта задачи. Имя задачи видно в выводе repr() команды asyncio.Task, а также может быть получено с помощью метода get_name().
(Автор: Alex Grönholm в bpo-34270.)
Добавлена поддержка Happy Eyeballs для asyncio.loop.create_connection(). Для настройки поведения добавлены два новых параметра: happy_eyeballs_delay и interleave. Алгоритм Happy Eyeballs повышает отзывчивость приложений, поддерживающих IPv4 и IPv6, за счёт попытки одновременного подключения по обоим протоколам.
(Автор: twisteroid ambassador в bpo-33530.)
builtins¶
Встроенная функция compile() была улучшена: теперь она принимает флаг ast.PyCF_ALLOW_TOP_LEVEL_AWAIT. При передаче этого нового флага compile() будет разрешать конструкции верхнего уровня await, async for и async with, которые обычно считаются недопустимым синтаксисом. Затем может быть возвращён асинхронный объект кода, помеченный флагом CO_COROUTINE.
(Автор: Matthias Bussonnier в bpo-34616)
collections¶
Метод _asdict() для
collections.namedtuple() теперь возвращает dict вместо
collections.OrderedDict. Это работает, поскольку обычные словари с Python 3.7 гарантированно упорядочены.
Если требуются дополнительные возможности OrderedDict, рекомендуется привести
результат к нужному типу: OrderedDict(nt._asdict()).
(Предложено Raymond Hettinger в bpo-35864.)
cProfile¶
Класс cProfile.Profile теперь можно использовать как контекстный менеджер.
Профилирование блока кода выполняется командой:
import cProfile
with cProfile.Profile() as profiler:
# код для профилирования
...
(Предложено Scott Sanderson в bpo-29235.)
csv¶
csv.DictReader теперь возвращает экземпляры dict вместо
collections.OrderedDict. Инструмент стал быстрее и использует меньше
памяти, сохраняя порядок полей.
(Предложено Michael Selik в bpo-34003.)
curses¶
Добавлена новая переменная, содержащая структурированную информацию о версии
базовой библиотеки ncurses: ncurses_version.
(Предложено Serhiy Storchaka в bpo-31680.)
ctypes¶
В Windows CDLL и его подклассы теперь принимают параметр winmode,
чтобы задавать флаги для вызова LoadLibraryEx. Флаги по умолчанию настроены так,
чтобы загружать зависимости DLL только из доверенных мест, включая путь,
где находится DLL (если для загрузки исходной DLL используется полный или
частичный путь), а также пути, добавленные add_dll_directory().
(Предложено Steve Dower в bpo-36085.)
datetime¶
Добавлены новые альтернативные конструкторы datetime.date.fromisocalendar() и
datetime.datetime.fromisocalendar(), которые создают объекты date и
datetime соответственно на основе года ISO, номера недели и дня недели;
это обратные операции по отношению к методу isocalendar каждого класса.
(Предложено Paul Ganssle в bpo-36004.)
functools¶
functools.lru_cache() теперь можно использовать напрямую как декоратор, а
не как функцию, возвращающую декоратор. Поэтому теперь поддерживаются оба варианта:
@lru_cache
def f(x):
...
@lru_cache(maxsize=256)
def f(x):
...
(Предложено Raymond Hettinger в bpo-36772.)
Добавлен новый декоратор functools.cached_property() для вычисляемых свойств,
которые кэшируются на всё время жизни экземпляра.
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)
(Предложено Carl Meyer в bpo-21145)
Добавлен новый декоратор functools.singledispatchmethod(), который преобразует
методы в обобщённые функции с помощью
одиночной диспетчеризации:
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]
(Предложено Ethan Smith в bpo-32380)
gc¶
get_objects() теперь может принимать необязательный параметр generation,
указывающий поколение, из которого нужно получить объекты.
(Предложено Pablo Galindo в bpo-36016.)
gettext¶
Добавлены pgettext() и его варианты.
(Предложено Franz Glasner, Éric Araujo и Cheryl Sabella в bpo-2504.)
gzip¶
Добавлен параметр mtime в gzip.compress() для воспроизводимого вывода.
(Предложено Guo Ci Teo в bpo-34898.)
Исключение BadGzipFile теперь возбуждается вместо OSError
для некоторых типов недопустимых или повреждённых gzip-файлов.
(Предложено Filip Gruszczyński, Michele Orrù и Zackery Spytz в
bpo-6584.)
IDLE and idlelib¶
Вывод длиннее N строк (по умолчанию 50) сворачивается в кнопку. N можно изменить в разделе PyShell на вкладке General диалогового окна Settings. Меньшее количество строк, но возможно очень длинных, можно свернуть, щелкнув правой кнопкой по выводу. Свёрнутый вывод можно развернуть на месте двойным щелчком по кнопке, либо в буфер обмена или отдельное окно щелчком правой кнопки по кнопке. (Предложено Tal Einat в bpo-1529353.)
Добавлен пункт «Run Customized» в меню Run для запуска модуля с настраиваемыми параметрами. Введённые аргументы командной строки добавляются в sys.argv. Они также снова отображаются в поле для следующего настраиваемого запуска. Также можно отключить обычный перезапуск главного модуля Shell. (Предложено Cheryl Sabella, Terry Jan Reedy и другими в bpo-5680 и bpo-37627.)
Добавлены опциональные номера строк для окон редактора IDLE. Окна открываются без номеров строк, если не указано иное на вкладке General диалога конфигурации. Номера строк для существующего окна можно показать или скрыть в меню Options. (Предложено Tal Einat и Saimadhav Heblikar в bpo-17535.)
Теперь используется родная кодировка ОС для преобразования между строками Python и объектами Tcl. Это позволяет IDLE работать с эмодзи и другими символами вне BMP. Эти символы можно отображать или копировать и вставлять в/из буфера обмена. Преобразование строк из Tcl в Python и обратно теперь никогда не завершается ошибкой. (Многие люди работали над этим восемь лет, но проблема была окончательно решена Serhiy Storchaka в bpo-13153.)
Новое в 3.8.1:
Добавлена опция для отключения мигания курсора. (Предложено Zackery Spytz в bpo-4603.)
Клавиша Escape теперь закрывает окна автодополнения IDLE. (Предложено Johnny Najera в bpo-38944.)
Эти изменения были перенесены в версии 3.7 с поддержкой.
Добавлены ключевые слова в список автодополнения имён модулей. (Предложено Terry J. Reedy в bpo-37765.)
inspect¶
Функция inspect.getdoc() теперь может находить строки документации для __slots__,
если этот атрибут является dict, значения которого – строки документации.
Это даёт возможности документации, аналогичные тем, что уже есть
для property(), classmethod() и staticmethod():
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)
(Предложено Raymond Hettinger в bpo-36326.)
io¶
В режиме разработки (-X env) и в отладочной сборке финализатор
io.IOBase теперь регистрирует исключение, если метод close()
завершается неудачей. По умолчанию в рабочей сборке исключение молча игнорируется.
(Предложено Victor Stinner в bpo-18748.)
itertools¶
Функция itertools.accumulate() получила необязательный именованный аргумент initial
для задания начального значения:
>>> from itertools import accumulate
>>> list(accumulate([10, 5, 30, 15], initial=1000))
[1000, 1010, 1015, 1045, 1060]
(Предложено Lisa Roach в bpo-34659.)
json.tool¶
Добавлена опция --json-lines для разбора каждой входной строки как отдельного JSON-объекта.
(Предложено Weipeng Hong в bpo-31553.)
logging¶
Добавлен именованный аргумент force в logging.basicConfig().
Если он установлен в true, все существующие обработчики, прикреплённые
к корневому регистратору, удаляются и закрываются перед применением
конфигурации, заданной остальными аргументами.
Это решает давнюю проблему. После вызова логгера или basicConfig() последующие вызовы basicConfig() молча игнорировались. Это затрудняло обновление, эксперименты или обучение различным возможностям настройки логирования в интерактивной оболочке или Jupyter notebook.
(Предложено Raymond Hettinger, реализовано Donghee Na, проверено Vinay Sajip в bpo-33897.)
math¶
Добавлена новая функция math.dist() для вычисления евклидова расстояния
между двумя точками. (Предложено Raymond Hettinger в bpo-33089.)
Функция math.hypot() расширена для работы с несколькими измерениями.
Ранее она поддерживала только двумерный случай.
(Предложено Raymond Hettinger в bpo-33089.)
Добавлена новая функция math.prod(), аналогичная sum(),
которая возвращает произведение начального значения (по умолчанию 1) и элементов
переданной последовательности чисел:
>>> prior = 0.8
>>> likelihoods = [0.625, 0.84, 0.30]
>>> math.prod(likelihoods, start=prior)
0.126
(Предложено Pablo Galindo в bpo-35606.)
Добавлены две новые комбинаторные функции math.perm() и math.comb():
>>> math.perm(10, 3) # Перестановки из 10 элементов по 3
720
>>> math.comb(10, 3) # Сочетания из 10 элементов по 3
120
(Предложено Yash Aggarwal, Keller Fuchs, Serhiy Storchaka и Raymond Hettinger в bpo-37128, bpo-37178 и bpo-35431.)
Добавлена новая функция math.isqrt() для точного вычисления целочисленного
квадратного корня без преобразования в число с плавающей запятой. Новая функция
поддерживает целые числа произвольной величины. Она быстрее floor(sqrt(n)), но медленнее
math.sqrt():
>>> r = 650320427
>>> s = r ** 2
>>> isqrt(s - 1) # правильно
650320426
>>> floor(sqrt(s - 1)) # неправильно
650320427
(Предложено Mark Dickinson в bpo-36887.)
Функция math.factorial() больше не принимает аргументы, не являющиеся
целочисленными. (Предложено Pablo Galindo в bpo-33083.)
mmap¶
Класс mmap.mmap теперь имеет метод madvise() для
доступа к системному вызову madvise().
(Предложено Zackery Spytz в bpo-32941.)
multiprocessing¶
Добавлен новый модуль multiprocessing.shared_memory.
(Предложено Davin Potts в bpo-35813.)
На macOS метод запуска spawn теперь используется по умолчанию. (Автор: Victor Stinner в bpo-33725.)
os¶
Добавлена новая функция add_dll_directory() в Windows для предоставления
дополнительных путей поиска для нативных зависимостей при импорте
модулей расширения или загрузке DLL с помощью ctypes.
(Автор: Steve Dower в bpo-36085.)
Добавлена новая функция os.memfd_create(), оборачивающая
системный вызов memfd_create().
(Авторы: Zackery Spytz и Christian Heimes в bpo-26836.)
В Windows большая часть ручной логики обработки точек повторного анализа (включая
символические ссылки и соединения каталогов) передана операционной системе.
В частности, os.stat() теперь будет обходить всё, что поддерживается
операционной системой, в то время как os.lstat() будет открывать только точки повторного анализа, которые
идентифицируются как «заместители имени», а остальные открываются как для os.stat().
Во всех случаях os.stat_result.st_mode будет иметь S_IFLNK, установленный только для
символических ссылок, а не для других видов точек повторного анализа. Чтобы идентифицировать другие виды
точек повторного анализа, проверьте новый атрибут os.stat_result.st_reparse_tag.
В Windows os.readlink() теперь умеет читать соединения каталогов. Обратите внимание,
что islink() вернёт False для соединений каталогов,
поэтому код, который сначала проверяет islink, продолжит считать соединения каталогов
директориями, а код, обрабатывающий ошибки от os.readlink(), теперь может
считать соединения каталогов ссылками.
(Автор: Steve Dower в bpo-37834.)
os.path¶
Функции os.path, возвращающие булев результат, такие как
exists(), lexists(), isdir(),
isfile(), islink() и ismount(),
теперь возвращают False вместо возбуждения ValueError или его подклассов
UnicodeEncodeError и UnicodeDecodeError для путей, содержащих
символы или байты, непредставимые на уровне ОС.
(Автор: Serhiy Storchaka в bpo-33721.)
expanduser() в Windows теперь отдаёт предпочтение переменной окружения USERPROFILE
и не использует HOME, которая обычно не установлена
для обычных учётных записей пользователей.
(Автор: Anthony Sottile в bpo-36264.)
isdir() в Windows больше не возвращает True для ссылки на
несуществующий каталог.
realpath() в Windows теперь обрабатывает точки повторного анализа, включая
символические ссылки и соединения каталогов.
(Автор: Steve Dower в bpo-37834.)
pathlib¶
Методы pathlib.Path, возвращающие булев результат, такие как
exists(), is_dir(),
is_file(), is_mount(),
is_symlink(), is_block_device(),
is_char_device(), is_fifo(),
is_socket(), теперь возвращают False вместо возбуждения
ValueError или его подкласса UnicodeEncodeError для путей, содержащих
символы, непредставимые на уровне ОС.
(Автор: Serhiy Storchaka в bpo-33721.)
Добавлен pathlib.Path.link_to(), который создаёт жёсткую ссылку, указывающую
на путь.
(Автор: Joannah Nanjekye в bpo-26978)
Обратите внимание, что link_to был объявлен устаревшим в 3.10 и удалён в 3.12 в
пользу метода hardlink_to, добавленного в 3.10, который соответствует
семантике существующего метода symlink_to.
pickle¶
Расширения pickle, наследующие от оптимизированной на C реализации Pickler,
теперь могут переопределять логику сериализации (pickling) функций и классов, определяя
специальный метод reducer_override().
(Авторы: Pierre Glaser и Olivier Grisel в bpo-35900.)
plistlib¶
Добавлена новая plistlib.UID и включена поддержка чтения и записи
бинарных plist-файлов, закодированных NSKeyedArchiver.
(Автор: Jon Janzen в bpo-26707.)
pprint¶
Модуль pprint добавил параметр sort_dicts в несколько функций.
По умолчанию эти функции продолжают сортировать словари перед отображением или
выводом на печать. Однако если sort_dicts установлен в false, словари сохраняют
порядок вставки ключей. Это может быть полезно для сравнения с JSON-данными
при отладке.
Кроме того, добавлена новая удобная функция pprint.pp(), которая работает
как pprint.pprint(), но с параметром sort_dicts, по умолчанию установленным в False:
>>> from pprint import pprint, pp
>>> d = dict(source='input.txt', operation='filter', destination='output.txt')
>>> pp(d, width=40) # Исходный порядок
{'source': 'input.txt',
'operation': 'filter',
'destination': 'output.txt'}
>>> pprint(d, width=40) # Ключи, отсортированные по алфавиту
{'destination': 'output.txt',
'operation': 'filter',
'source': 'input.txt'}
(Автор: Rémi Lapeyre в bpo-30670.)
py_compile¶
py_compile.compile() теперь поддерживает тихий режим.
(Автор: Joannah Nanjekye в bpo-22640.)
shlex¶
Новая функция shlex.join() действует как обратная к shlex.split().
(Автор: Bo Bayles в bpo-32102.)
shutil¶
shutil.copytree() теперь принимает новый именованный аргумент dirs_exist_ok.
(Автор: Josh Bronson в bpo-20849.)
shutil.make_archive() теперь по умолчанию использует современный формат pax (POSIX.1-2001)
для новых архивов для улучшения переносимости и соответствия стандартам,
унаследовано от соответствующего изменения в модуле tarfile.
(Автор: C.A.M. Gerlach в bpo-30661.)
shutil.rmtree() в Windows теперь удаляет соединения каталогов без
предварительного рекурсивного удаления их содержимого.
(Автор: Steve Dower в bpo-37834.)
socket¶
Добавлены функции create_server() и has_dualstack_ipv6()
автоматизирующие типичные задачи при создании серверного сокета, включая приём соединений как по IPv4, так и по IPv6 на одном сокете. (Предложено Giampaolo Rodolà в bpo-17561.)
Функции socket.if_nameindex(), socket.if_nametoindex() и
socket.if_indextoname() реализованы в Windows.
(Предложено Zackery Spytz в bpo-37007.)
ssl¶
Добавлены post_handshake_auth для включения и
verify_client_post_handshake() для запуска аутентификации после рукопожатия TLS 1.3.
(Предложено Christian Heimes в bpo-34670.)
statistics¶
Добавлена statistics.fmean() – более быстрый вариант с плавающей точкой от
statistics.mean(). (Предложено Raymond Hettinger и
Steven D’Aprano в bpo-35904.)
Добавлено statistics.geometric_mean()
(Предложено Raymond Hettinger в bpo-27181.)
Добавлено statistics.multimode(), возвращающее список наиболее распространённых значений. (Предложено Raymond Hettinger в bpo-35892.)
Добавлено statistics.quantiles(), которое делит данные или распределение на равновероятные интервалы (например, квартили, децили или процентили).
(Предложено Raymond Hettinger в bpo-36546.)
Добавлено statistics.NormalDist – инструмент для создания и управления нормальными распределениями случайной величины.
(Предложено Raymond Hettinger в 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) # Вероятность оказаться ниже 3 градусов
0.3184678262814532
>>> # Относительная вероятность 7 градусов против 10
>>> temperature_feb.pdf(7) / temperature_feb.pdf(10)
1.2039930378537762
>>> el_niño = NormalDist(4, 2.5)
>>> temperature_feb += el_niño # Добавить климатический эффект
>>> temperature_feb
NormalDist(mu=10.0, sigma=6.830080526611674)
>>> temperature_feb * (9/5) + 32 # Преобразовать в градусы Фаренгейта
NormalDist(mu=50.0, sigma=12.294144947901014)
>>> temperature_feb.samples(3) # Сгенерировать случайные выборки
[7.672102882379219, 12.000027119750287, 4.647488369766392]
sys¶
Добавлена новая функция sys.unraisablehook(), которую можно переопределить, чтобы управлять обработкой «необрабатываемых исключений». Она вызывается, когда возникает исключение, но у Python нет способа его обработать. Например, когда деструктор порождает исключение или во время сборки мусора
(gc.collect()).
(Предложено Victor Stinner в bpo-36829.)
tarfile¶
Модуль tarfile теперь по умолчанию использует современный формат pax (POSIX.1-2001) для новых архивов вместо прежнего, специфичного для GNU.
Это улучшает кроссплатформенную переносимость благодаря единой кодировке (UTF-8)
в стандартизированном и расширяемом формате, а также предоставляет ряд других преимуществ.
(Предложено C.A.M. Gerlach в bpo-36268.)
threading¶
Добавлена новая функция threading.excepthook(), обрабатывающая неперехваченное исключение threading.Thread.run(). Её можно переопределить, чтобы управлять обработкой неперехваченных исключений threading.Thread.run().
(Предложено Victor Stinner в bpo-1230540.)
Добавлены новая функция threading.get_native_id() и атрибут native_id в класс threading.Thread. Они возвращают собственный целочисленный идентификатор текущего потока, назначаемый ядром.
Эта возможность доступна только на некоторых платформах; подробнее см.
get_native_id.
(Предложено Jake Tesler в bpo-36084.)
tokenize¶
Модуль tokenize теперь неявно генерирует токен NEWLINE, если входные данные не содержат завершающего перевода строки. Такое поведение теперь соответствует тому, что делает внутренний токенизатор C.
(Предложено Ammar Askar в bpo-33899.)
tkinter¶
В класс tkinter.Spinbox добавлены методы selection_from(),
selection_present(),
selection_range() и
selection_to().
(Предложено Juliette Monsel в bpo-34829.)
В класс tkinter.Canvas добавлен метод moveto().
(Предложено Juliette Monsel в bpo-23831.)
У класса tkinter.PhotoImage теперь есть методы transparency_get() и transparency_set(). (Предложено
Zackery Spytz в bpo-25451.)
time¶
Добавлены новые часы CLOCK_UPTIME_RAW для macOS 10.12.
(Предложено Joannah Nanjekye в bpo-35702.)
typing¶
Модуль typing включает несколько новых возможностей:
Тип словаря с типизацией по ключам. См. PEP 589 и
typing.TypedDict. TypedDict использует только строковые ключи. По умолчанию каждый ключ обязан присутствовать. Укажите “total=False”, чтобы сделать ключи необязательными:class Location(TypedDict, total=False): lat_long: tuple grid_square: str xy_coordinate: tuple
Литеральные типы. См. PEP 586 и
typing.Literal. Литеральные типы указывают, что параметр или возвращаемое значение ограничены одним или несколькими конкретными литеральными значениями:def get_status(port: int) -> Literal['connected', 'disconnected']: ...
«Финальные» переменные, функции, методы и классы. См. PEP 591,
typing.Finalиtyping.final(). Квалификатор final указывает статическому проверщику типов ограничивать наследование, переопределение или переназначение:pi: Final[float] = 3.1415926536
Определения протоколов. См. PEP 544,
typing.Protocolиtyping.runtime_checkable(). Простые абстрактные базовые классы (ABC), такие какtyping.SupportsInt, теперь являются подклассамиProtocol.Новый класс протокола
typing.SupportsIndex.Новые функции
typing.get_origin()иtyping.get_args().
unicodedata¶
Модуль unicodedata обновлён для использования версии Unicode 12.1.0.
Новая функция is_normalized() позволяет проверить, находится ли строка в определённой нормальной форме, часто гораздо быстрее, чем при фактической нормализации строки. (Предложено Max Belanger, David Euresti и Greg Price в bpo-32285 и bpo-37966).
unittest¶
Добавлен AsyncMock для поддержки асинхронной версии Mock. Также добавлены соответствующие новые функции assert для тестирования.
(Предложено Lisa Roach в bpo-26467).
Добавлены addModuleCleanup() и addClassCleanup() в unittest для поддержки очистки для setUpModule() и setUpClass().
(Предложено Lisa Roach в bpo-24412.)
Некоторые mock-функции assert теперь также выводят список фактических вызовов при неудаче. (Предложено Petter Strandmark в bpo-35047.)
Модуль unittest получил поддержку использования корутин в качестве тестовых случаев с помощью unittest.IsolatedAsyncioTestCase.
(Предложено Andrew Svetlov в bpo-32972.)
Пример:
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 теперь включает скрипт Activate.ps1 на всех платформах для активации виртуальных окружений в PowerShell Core 6.1.
(Предложено Brett Cannon в bpo-32718.)
weakref¶
Прокси-объекты, возвращаемые weakref.proxy(), теперь поддерживают операторы умножения матриц @ и @= в дополнение к другим числовым операторам. (Предложено Mark Dickinson в bpo-36669.)
xml¶
В качестве меры защиты от DTD и извлечения внешних сущностей модули xml.dom.minidom и xml.sax больше не обрабатывают внешние сущности по умолчанию.
(Предложено Christian Heimes в bpo-17239.)
Методы .find*() в модуле xml.etree.ElementTree поддерживают поиск по шаблону, например {*}tag, который игнорирует пространство имён, и {namespace}*, который возвращает все теги в заданном пространстве имён.
(Предложено Stefan Behnel в bpo-28238.)
Модуль xml.etree.ElementTree предоставляет новую функцию canonicalize(), реализующую C14N 2.0.
(Предложено Stefan Behnel в bpo-13611.)
Целевой объект xml.etree.ElementTree.XMLParser может получать события объявления пространства имён через новые методы колбэков start_ns() и end_ns(). Кроме того, цель xml.etree.ElementTree.TreeBuilder можно настроить на обработку событий о комментариях и инструкциях обработки, чтобы включить их в создаваемое дерево.
(Предложено Stefan Behnel в bpo-36676 и bpo-36673.)
xmlrpc¶
xmlrpc.client.ServerProxy теперь поддерживает необязательный именованный аргумент headers для последовательности HTTP-заголовков, отправляемых с каждым запросом. В частности, это позволяет перейти с базовой аутентификации по умолчанию на более быструю сессионную аутентификацию.
(Предложено Cédric Krier в bpo-35153.)
Оптимизации¶Optimizations
Модуль
subprocessтеперь может использовать функциюos.posix_spawn()в некоторых случаях для повышения производительности. В настоящее время он используется только в macOS и Linux (с glibc 2.24 или новее) при соблюдении всех следующих условий:close_fds имеет значение false;
параметры preexec_fn, pass_fds, cwd и start_new_session не заданы;
путь executable содержит каталог.
(Предложено Joannah Nanjekye и Victor Stinner в bpo-35537.)
shutil.copyfile(),shutil.copy(),shutil.copy2(),shutil.copytree()иshutil.move()используют платформозависимые системные вызовы «fast-copy» в Linux и macOS для более эффективного копирования файлов. «fast-copy» означает, что операция копирования происходит внутри ядра, избегая использования буферов пользовательского пространства в Python, как в «outfd.write(infd.read())». В Windowsshutil.copyfile()использует больший размер буфера по умолчанию (1 МиБ вместо 16 КиБ) и используется вариантshutil.copyfileobj()на основеmemoryview(). Ускорение копирования файла размером 512 МиБ в пределах одного раздела составляет около +26% в Linux, +50% в macOS и +40% в Windows. Кроме того, потребляется гораздо меньше тактов ЦП. См. раздел Эффективные операции копирования, зависящие от платформы. (Предложено Giampaolo Rodolà в bpo-33671.)shutil.copytree()использует функциюos.scandir(), и все функции копирования, зависящие от неё, используют кэшированные значенияos.stat(). Ускорение копирования каталога с 8000 файлов составляет около +9% в Linux, +20% в Windows и +30% в общей папке Windows SMB. Кроме того, количество системных вызововos.stat()сокращено на 38%, что делаетshutil.copytree()особенно быстрее в сетевых файловых системах. (Предложено Giampaolo Rodolà в bpo-33695.)Протоколом по умолчанию в модуле
pickleтеперь является Протокол 4, впервые представленный в Python 3.4. Он обеспечивает более высокую производительность и меньший размер по сравнению с Протоколом 3, доступным с Python 3.0.Удалён один элемент
Py_ssize_tизPyGC_Head. Размер всех объектов, отслеживаемых GC (например, tuple, list, dict), уменьшен на 4 или 8 байт. (Предложено Inada Naoki в bpo-33597.)uuid.UUIDтеперь использует__slots__для уменьшения потребления памяти. (Предложено Wouter Bolsterlee и Tal Einat в bpo-30977)Производительность
operator.itemgetter()улучшена на 33%. Оптимизирована обработка аргументов и добавлен быстрый путь для распространённого случая одного неотрицательного целочисленного индекса в кортеже (что является типичным случаем использования в стандартной библиотеке). (Предложено Raymond Hettinger в bpo-35664.)Ускорен поиск полей в
collections.namedtuple(). Теперь он выполняется более чем в два раза быстрее, что делает его самой быстрой формой поиска переменных экземпляра в Python. (Разработка Рэймонда Хеттингера, Пабло Галиндо, Джо Джевника и Сергея Сторчаки – bpo-32492.)Конструктор
listбольше не выделяет лишнюю память для внутреннего буфера элементов, если длина входного итерируемого объекта известна (вход реализует__len__). Благодаря этому создаваемый список в среднем на 12% меньше. (Разработка Рэймонда Хеттингера и Пабло Галиндо – bpo-33234.)Скорость записи переменных класса удвоена. При обновлении атрибута, не являющегося дандером, выполнялся лишний вызов для обновления слотов. (Разработка Стефана Бенела, Пабло Галиндо Сальгадо, Рэймонда Хеттингера, Нила Шеменауэра и Сергея Сторчаки – bpo-36012.)
Снижены накладные расходы на преобразование аргументов, передаваемых многим встроенным функциям и методам. Это ускорило вызов некоторых простых встроенных функций и методов на 20–50%. (Разработка Сергея Сторчаки – bpo-23867, bpo-35582 и bpo-36127.)
Инструкция
LOAD_GLOBALтеперь использует новый механизм «per opcode cache». Она стала примерно на 40% быстрее. (Разработка Юрия Селиванова и Инады Наоки – bpo-26219.)
Изменения в сборке и C API¶Build and C API Changes
Значение по умолчанию
sys.abiflagsстало пустой строкой: флагmдля pymalloc стал бесполезен (сборки с pymalloc и без него ABI-совместимы), поэтому он был удалён. (Разработка Виктора Стиннера – bpo-36707.)Пример изменений:
Устанавливается только программа
python3.8, программаpython3.8mудалена.Устанавливается только скрипт
python3.8-config, скриптpython3.8m-configудалён.Флаг
mудалён из суффикса имён файлов динамических библиотек: модулей расширения стандартной библиотеки, а также тех, что создаются и устанавливаются сторонними пакетами (например, загруженными из PyPI). В Linux, например, суффикс.cpython-37m-x86_64-linux-gnu.soдля Python 3.7 стал.cpython-38-x86_64-linux-gnu.soв Python 3.8.
Заголовочные файлы были переорганизованы для лучшего разделения различных видов API:
Include/*.h– это переносимый публичный стабильный C API.Include/cpython/*.h– это нестабильный C API, специфичный для CPython; публичный API, с некоторыми приватными частями, имеющими префикс_Pyили_PY.Include/internal/*.h– это приватный внутренний C API, очень специфичный для CPython. Этот API не предоставляет гарантий обратной совместимости и не должен использоваться за пределами CPython. Он открыт только для особых нужд, таких как отладчики и профилировщики, которым требуется доступ к внутренностям CPython без вызова функций. Теперь этот API устанавливается с помощьюmake install.
(Разработка Виктора Стиннера – bpo-35134 и bpo-35081; работа начата Эриком Сноу в Python 3.7.)
Некоторые макросы преобразованы в статические встраиваемые функции: типы параметров и возвращаемое значение чётко определены, отсутствуют проблемы, свойственные макросам, переменные имеют локальную область видимости. Примеры:
PyObject_INIT,PyObject_INIT_VARПриватные функции:
_PyObject_GC_TRACK(),_PyObject_GC_UNTRACK(),_Py_Dealloc()
(Разработка Виктора Стиннера – bpo-35059.)
Функции
PyByteArray_Init()иPyByteArray_Fini()удалены. Они ничего не делали начиная с Python 2.7.4 и Python 3.2.0, были исключены из ограниченного API (стабильного ABI) и не документировались. (Разработка Виктора Стиннера – bpo-35713.)Результат
PyExceptionClass_Name()теперь имеет типconst char *, а неchar *. (Разработка Сергея Сторчаки – bpo-33818.)Двойственность
Modules/Setup.distиModules/Setupустранена. Раньше при обновлении исходного дерева CPython приходилось вручную копироватьModules/Setup.dist(внутри исходного дерева) вModules/Setup(внутри дерева сборки), чтобы отразить любые изменения. Это приносило небольшую пользу сборщикам пакетов, но часто раздражало разработчиков, следящих за разработкой CPython, так как забыв скопировать файл, можно было получить сбой сборки.Теперь система сборки всегда читает из
Modules/Setupвнутри исходного дерева. Тем, кто хочет настроить этот файл, рекомендуется поддерживать свои изменения в git-форке CPython или в виде патч-файлов, как и любые другие изменения исходного дерева.(Разработка Антуана Питру – bpo-32430.)
Функции, преобразующие число Python в целое C, такие как
PyLong_AsLong(), и функции разбора аргументов, напримерPyArg_ParseTuple(), с форматными единицами преобразования в целое, например'i', теперь будут использовать специальный метод__index__()вместо__int__(), если он доступен. Предупреждение об устаревании будет выдаваться для объектов, у которых есть метод__int__(), но отсутствует__index__()(например,DecimalиFraction).PyNumber_Check()теперь будет возвращать1для объектов, реализующих__index__().PyNumber_Long(),PyNumber_Float()иPyFloat_AsDouble()также теперь используют метод__index__(), если он доступен. (Разработка Сергея Сторчаки – bpo-36048 и bpo-20092.)Объекты типов, выделяемые в куче, теперь будут увеличивать счётчик ссылок в
PyObject_Init()(и в параллельном макросеPyObject_INIT) вместоPyType_GenericAlloc(). Типы, которые изменяют выделение или освобождение экземпляров, возможно, потребуют корректировки. (Разработка Эдди Элизондо – bpo-35810.)Новая функция
PyCode_NewWithPosOnlyArgs()позволяет создавать объекты кода, какPyCode_New(), но с дополнительным параметром posonlyargcount для указания количества позиционных аргументов. (Разработка Пабло Галиндо – bpo-37221.)Py_SetPath()теперь устанавливаетsys.executableв полный путь программы (Py_GetProgramFullPath()), а не в имя программы (Py_GetProgramName()). (Разработка Виктора Стиннера – bpo-38234.)
Устарело¶Deprecated
Команда distutils
bdist_wininstтеперь устарела; вместо неё используйтеbdist_wheel(пакеты wheel). (Разработка Виктора Стиннера – bpo-37481.)Устаревшие методы
getchildren()иgetiterator()в модулеElementTreeтеперь порождаютDeprecationWarningвместоPendingDeprecationWarning. Они будут удалены в Python 3.9. (Разработка Сергея Сторчаки – bpo-29209.)Передача
loop.set_default_executor()объекта, не являющегося экземпляромconcurrent.futures.ThreadPoolExecutor, объявлена устаревшей и будет запрещена в Python 3.9. (Разработка Элвиса Пранскевичуса – bpo-34075.)Методы
__getitem__()классовxml.dom.pulldom.DOMEventStream,wsgiref.util.FileWrapperиfileinput.FileInputобъявлены устаревшими.Реализации этих методов игнорировали параметр index и вместо этого возвращали следующий элемент. (Разработка Беркера Пексага – bpo-9372.)
Класс
typing.NamedTupleобъявил устаревшим атрибут_field_typesв пользу атрибута__annotations__, который содержит ту же информацию. (Автор: Raymond Hettinger в bpo-36320.)Классы
astNum,Str,Bytes,NameConstantиEllipsisсчитаются устаревшими и будут удалены в будущих версиях Python. Вместо них следует использоватьConstant. (Автор: Serhiy Storchaka в bpo-32892.)Методы
ast.NodeVisitorvisit_Num(),visit_Str(),visit_Bytes(),visit_NameConstant()иvisit_Ellipsis()теперь устарели и не будут вызываться в будущих версиях Python. Добавьте методvisit_Constant()для обработки всех постоянных узлов. (Автор: Serhiy Storchaka в bpo-36917.)@asyncio.coroutineдекоратор устарел и будет удалён в версии 3.10. Вместо@asyncio.coroutineиспользуйтеasync def. (Автор: Andrew Svetlov в bpo-36921.)В
asyncioявная передача аргумента цикл событий устарела и будет удалена в версии 3.10 для следующих:asyncio.sleep(),asyncio.gather(),asyncio.shield(),asyncio.wait_for(),asyncio.wait(),asyncio.as_completed(),asyncio.Task,asyncio.Lock,asyncio.Event,asyncio.Condition,asyncio.Semaphore,asyncio.BoundedSemaphore,asyncio.Queue,asyncio.create_subprocess_exec()иasyncio.create_subprocess_shell().Явная передача объектов корутин в
asyncio.wait()устарела и будет удалена в версии 3.11. (Автор: Yury Selivanov в bpo-34790.)Следующие функции и методы устарели в модуле
gettext:lgettext(),ldgettext(),lngettext()иldngettext(). Они возвращают закодированные байты, и возможны неожиданные исключения, связанные с Unicode, при проблемах с кодировкой переведённых строк. Гораздо лучше использовать альтернативы, которые возвращают строки Unicode в Python 3. Эти функции давно не работают должным образом.Функция
bind_textdomain_codeset(), методыNullTranslations.output_charset()иNullTranslations.set_output_charset(), а также параметр codeset функцийtranslation()иinstall()также устарели, поскольку используются только для функцийl*gettext(). (Автор: Serhiy Storchaka в bpo-33710.)Метод
isAlive()классаthreading.Threadустарел. (Автор: Donghee Na в bpo-35283.)Многие встроенные и расширенные функции, принимающие целочисленные аргументы, теперь выводят предупреждение об устаревании для
Decimal,Fractionи любых других объектов, которые могут быть преобразованы в целые числа только с потерей (например, имеющих метод__int__(), но не имеющих метода__index__()). В будущих версиях это станет ошибкой. (Автор: Serhiy Storchaka в bpo-36048.)Устарела передача следующих аргументов в качестве именованных:
func в
functools.partialmethod(),weakref.finalize(),profile.Profile.runcall(),cProfile.Profile.runcall(),bdb.Bdb.runcall(),trace.Trace.runfunc()иcurses.wrapper().function в
unittest.TestCase.addCleanup().fn в методе
submit()классовconcurrent.futures.ThreadPoolExecutorиconcurrent.futures.ProcessPoolExecutor.callback in
contextlib.ExitStack.callback(),contextlib.AsyncExitStack.callback()andcontextlib.AsyncExitStack.push_async_callback().c и typeid в методе
create()классовmultiprocessing.managers.Serverиmultiprocessing.managers.SharedMemoryServer.obj в
weakref.finalize().
В будущих версиях Python они станут только позиционными. (Автор: Serhiy Storchaka в bpo-36492.)
Удаление API и функций¶API and Feature Removals
Следующие функции и API были удалены из Python 3.8:
Начиная с Python 3.3, импорт ABC из
collectionsбыл устаревшим, и импорт следует производить изcollections.abc. Возможность импорта из collections была отмечена для удаления в 3.8, но отложена до 3.9. (См. gh-81134.)Модуль
macpath, устаревший в Python 3.7, был удалён. (Автор: Victor Stinner в bpo-35471.)Функция
platform.popen()была удалена после того, как была устаревшей начиная с Python 3.3: используйте вместо неёos.popen(). (Автор: Victor Stinner в bpo-35345.)Функция
time.clock()была удалена после того, как была устаревшей начиная с Python 3.3: используйтеtime.perf_counter()илиtime.process_time()в зависимости от ваших требований, чтобы получить строго определённое поведение. (Автор: Matthias Bussonnier в bpo-36895.)Скрипт
pyvenvбыл удалён в пользуpython3.8 -m venv, чтобы устранить путаницу с тем, к какому интерпретатору Python привязан скриптpyvenv. (Автор: Brett Cannon в bpo-25427.)parse_qs,parse_qslиescapeудалены из модуляcgi. Они устарели в Python 3.2 или старше. Их следует импортировать из модулейurllib.parseиhtml.Функция
filemodeудалена из модуляtarfile. Она не документирована и устарела начиная с Python 3.3.Конструктор
XMLParserбольше не принимает аргумент html. Он никогда не имел эффекта и был устаревшим в Python 3.4. Все остальные параметры теперь только именованные. (Автор: Serhiy Storchaka в bpo-29209.)Удалён метод
doctype()классаXMLParser. (Автор: Serhiy Storchaka в bpo-29209.)Кодек «unicode_internal» удалён. (Автор: Inada Naoki в bpo-36297.)
Объекты
CacheиStatementмодуляsqlite3не доступны пользователю. (Автор: Aviv Palivoda в bpo-30262.)Именованный аргумент
bufsizeфункцийfileinput.input()иfileinput.FileInput(), который игнорировался и был устаревшим начиная с Python 3.6, удалён. bpo-36952 (Автор: Matthias Bussonnier.)Функции
sys.set_coroutine_wrapper()иsys.get_coroutine_wrapper(), объявленные устаревшими в Python 3.7, были удалены; bpo-36933 (Автор: Matthias Bussonnier.)
Перенос на Python 3.8¶Porting to Python 3.8
В этом разделе перечислены ранее описанные изменения и другие исправления ошибок, которые могут потребовать изменений в вашем коде.
Изменения в поведении Python¶Changes in Python behavior
Выражения yield (как
yield, так иyield from) теперь запрещены в включениях и генераторных выражениях (за исключением итерируемого выражения в крайнем левом предложенииfor). (Автор: Serhiy Storchaka в bpo-10544.)Теперь компилятор выводит
SyntaxWarning, когда проверки идентичности (isиis not) используются с определёнными типами литералов (например, строки, числа). В CPython они часто могут работать случайно, но языковая спецификация этого не гарантирует. Предупреждение советует использовать вместо них проверки на равенство (==и!=). (Автор: Serhiy Storchaka в bpo-34850.)Интерпретатор CPython может проглатывать исключения при некоторых обстоятельствах. В Python 3.8 это происходит в меньшем числе случаев. В частности, исключения, возникающие при получении атрибута из словаря типа, больше не игнорируются. (Автор: Serhiy Storchaka в bpo-35459.)
Удалены реализации
__str__из встроенных типовbool,int,float,complexи нескольких классов из стандартной библиотеки. Теперь они наследуют__str__()отobject. В результате определение метода__repr__()в подклассе этих классов повлияет на их строковое представление. (Автор: Serhiy Storchaka в bpo-36793.)На AIX
sys.platformбольше не содержит мажорную версию. Теперь это всегда'aix', вместо'aix3'..'aix7'. Поскольку старые версии Python включают номер версии, рекомендуется всегда использоватьsys.platform.startswith('aix'). (Автор: M. Felt в bpo-36588.)PyEval_AcquireLock()иPyEval_AcquireThread()теперь завершают текущий поток, если вызваны во время финализации интерпретатора, что делает их согласованными сPyEval_RestoreThread(),Py_END_ALLOW_THREADS()иPyGILState_Ensure(). Если такое поведение нежелательно, защитите вызов проверкой_Py_IsFinalizing()илиsys.is_finalizing(). (Автор: Joannah Nanjekye в bpo-36475.)
Изменения в Python API¶Changes in the Python API
Функция
os.getcwdb()теперь использует кодировку UTF-8 в Windows, вместо кодовой страницы ANSI: см. PEP 529 для обоснования. Эта функция больше не считается устаревшей в Windows. (Автор: Victor Stinner в bpo-37412.)subprocess.Popenтеперь может использоватьos.posix_spawn()в некоторых случаях для повышения производительности. В подсистеме Windows для Linux и эмуляции пользовательского режима QEMU конструкторPopen, использующийos.posix_spawn(), больше не вызывает исключение при ошибках типа «программа не найдена». Вместо этого дочерний процесс завершается с ненулевымreturncode. (Авторы: Joannah Nanjekye и Victor Stinner в bpo-35537.)Аргумент preexec_fn функции *
subprocess.Popenбольше не совместим с подинтерпретаторами. Использование этого параметра в подинтерпретаторе теперь вызываетRuntimeError. (Автор: Eric Snow в bpo-34651, доработано Christian Heimes в bpo-37951.)Метод
imaplib.IMAP4.logout()больше не игнорирует произвольные исключения без предупреждения. (Автор: Victor Stinner в bpo-36348.)Функция
platform.popen()была удалена после того, как была объявлена устаревшей начиная с Python 3.3: используйтеos.popen()вместо неё. (Автор: Victor Stinner в bpo-35345.)Функция
statistics.mode()больше не вызывает исключение при передаче мультимодальных данных. Вместо этого она возвращает первую моду, встреченную во входных данных. (Автор: Raymond Hettinger в bpo-35892.)Метод
selection()классаtkinter.ttk.Treeviewбольше не принимает аргументы. Его использование с аргументами для изменения выделения было объявлено устаревшим в Python 3.6. Используйте специализированные методы, напримерselection_set(), для изменения выделения. (Автор: Serhiy Storchaka в bpo-31508.)Методы
writexml(),toxml()иtoprettyxml()классаxml.dom.minidom, а также методwrite()классаxml.etree.ElementTreeтеперь сохраняют порядок атрибутов, заданный пользователем. (Авторы: Diego Rojas и Raymond Hettinger в bpo-34160.)База данных
dbm.dumb, открытая с флагами'r', теперь доступна только для чтения.dbm.dumb.open()с флагами'r'и'w'больше не создаёт базу данных, если она не существует. (Автор: Serhiy Storchaka в bpo-32749.)Метод
doctype(), определённый в подклассеXMLParser, больше не будет вызываться и будет выдаватьRuntimeWarningвместоDeprecationWarning. Определите методdoctype()на цели для обработки объявления типа документа XML. (Автор: Serhiy Storchaka в bpo-29209.)Теперь вызывается
RuntimeError, когда пользовательский метакласс не предоставляет запись__classcell__в пространстве имён, переданном вtype.__new__. В Python 3.6–3.7 выдавалосьDeprecationWarning. (Автор: Serhiy Storchaka в bpo-23722.)Класс
cProfile.Profileтеперь можно использовать как менеджер контекста. (Автор: Scott Sanderson в bpo-29235.)shutil.copyfile(),shutil.copy(),shutil.copy2(),shutil.copytree()иshutil.move()используют платформозависимые системные вызовы «быстрого копирования» (см. раздел Эффективные операции копирования, зависящие от платформы).Размер буфера по умолчанию
shutil.copyfile()в Windows изменён с 16 Киб на 1 МиБ.Структура
PyGC_Headполностью изменена. Весь код, который обращался к полям структуры, должен быть переписан. (См. bpo-33597.)Структура
PyInterpreterStateбыла перемещена во «внутренние» заголовочные файлы (конкретно Include/internal/pycore_pystate.h). НепрозрачныйPyInterpreterStateпо-прежнему доступен как часть публичного API (и стабильного ABI). В документации указано, что ни одно из полей структуры не является публичным, поэтому мы надеемся, что никто их не использовал. Однако, если вы действительно полагаетесь на одно или несколько из этих частных полей и у вас нет альтернативы, пожалуйста, откройте проблему на BPO. Мы поможем вам адаптироваться (возможно, включая добавление функций доступа в публичный API). (См. bpo-35886.)Метод
mmap.flush()теперь возвращаетNoneв случае успеха и вызывает исключение при ошибке на всех платформах. Ранее его поведение зависело от платформы: на Windows возвращалось ненулевое значение при успехе; ноль при ошибке. На Unix возвращалось нулевое значение при успехе; при ошибке вызывалось исключение. (Автор: Berker Peksag в bpo-2122.)Модули
xml.dom.minidomиxml.saxбольше не обрабатывают внешние сущности по умолчанию. (Автор: Christian Heimes в bpo-17239.)Удаление ключа из базы данных
dbm, доступной только для чтения (dbm.dumb,dbm.gnuилиdbm.ndbm), вызываетerror(dbm.dumb.error,dbm.gnu.errorилиdbm.ndbm.error) вместоKeyError. (Автор: Xiang Zhang в bpo-33106.)Упрощён AST для литералов. Все константы будут представлены как экземпляры
ast.Constant. Создание экземпляров старых классовNum,Str,Bytes,NameConstantиEllipsisбудет возвращать экземплярConstant. (Автор: Serhiy Storchaka в bpo-32892.)expanduser()в Windows теперь предпочитает переменную окруженияUSERPROFILEи не используетHOME, которая обычно не установлена для обычных учётных записей пользователей. (Автор: Anthony Sottile в bpo-36264.)Исключение
asyncio.CancelledErrorтеперь наследуется отBaseExceptionвместоExceptionи больше не наследуется отconcurrent.futures.CancelledError. (Автор: Yury Selivanov в bpo-32528.)Функция
asyncio.wait_for()теперь корректно ожидает отмены при использовании экземпляраasyncio.Task. Ранее по достижении timeout она отменялась и сразу возвращала управление. (Автор: Elvis Pranskevichus в bpo-32751.)Функция
asyncio.BaseTransport.get_extra_info()теперь возвращает готовый к использованию объект сокета, когда 'socket' передаётся в параметр name. (Автор: Yury Selivanov в bpo-37027.)asyncio.BufferedProtocolперешёл в стабильный API.
Зависимости DLL для модулей расширения и DLL, загружаемых с помощью
ctypesв Windows, теперь разрешаются более безопасно. Для поиска зависимостей во время загрузки используются только системные пути, каталог, содержащий DLL- или PYD-файл, и каталоги, добавленные с помощьюadd_dll_directory(). В частности,PATHи текущий рабочий каталог больше не используются, и изменения в них больше не будут влиять на обычное разрешение DLL. Если ваше приложение полагается на эти механизмы, следует проверить наличиеadd_dll_directory()и, если он существует, использовать его для добавления каталога ваших DLL во время загрузки библиотеки. Обратите внимание, что пользователи Windows 7 должны убедиться, что установлено обновление Windows KB2533623 (это также проверяется установщиком). (Автор: Steve Dower в bpo-36085.)Заголовочные файлы и функции, связанные с pgen, были удалены после его замены на чистую реализацию на Python. (Автор: Pablo Galindo в bpo-36623.)
types.CodeTypeимеет новый параметр на второй позиции конструктора (posonlyargcount) для поддержки позиционных аргументов, определённых в PEP 570. Первый аргумент (argcount) теперь представляет общее количество позиционных аргументов (включая позиционные аргументы). Новый методreplace()классаtypes.CodeTypeможно использовать для обеспечения перспективности кода.Параметр
digestmodдляhmac.new()больше не использует дайджест MD5 по умолчанию.
Изменения в C API¶Changes in the C API
Структура
PyCompilerFlagsполучила новое поле cf_feature_version. Его следует инициализировать значениемPY_MINOR_VERSION. По умолчанию это поле игнорируется и используется только в том случае, если в cf_flags установлен флагPyCF_ONLY_AST. (Автор: Guido van Rossum в bpo-35766.)Функция
PyEval_ReInitThreads()удалена из C API. Её не следует вызывать явно; вместо этого используйтеPyOS_AfterFork_Child(). (Автор: Victor Stinner в bpo-36728.)В Unix расширения на C больше не линкуются с libpython, за исключением Android и Cygwin. Когда Python встраивается,
libpythonдолжна загружаться не с помощьюRTLD_LOCAL, а с помощьюRTLD_GLOBAL. Ранее с использованиемRTLD_LOCALуже было невозможно загрузить расширения на C, которые не были слинкованы сlibpython, например расширения на C из стандартной библиотеки, собранные разделом*shared*файлаModules/Setup. (Автор: Victor Stinner в bpo-21536.)Использование вариантов форматов
#при разборе или построении значения (например,PyArg_ParseTuple(),Py_BuildValue(),PyObject_CallFunction()и т.д.) без определенияPY_SSIZE_T_CLEANтеперь вызываетDeprecationWarning. Это будет удалено в версии 3.10 или 4.0. Подробнее читайте в Parsing arguments and building values. (Автор: Inada Naoki в bpo-36381.)Экземпляры типов, выделяемых в куче (например, созданных с помощью
PyType_FromSpec()), содержат ссылку на свой объект-тип. Увеличение счётчика ссылок этих объектов-типов было перенесено изPyType_GenericAlloc()в более низкоуровневые функцииPyObject_Init()иPyObject_INIT. Это заставляет типы, созданные черезPyType_FromSpec(), вести себя как другие классы в управляемом коде.Статически выделенные типы не затрагиваются.
В подавляющем большинстве случаев побочных эффектов не должно быть. Однако типы, которые вручную увеличивают счётчик ссылок после выделения экземпляра (возможно, в обход ошибки), теперь могут стать бессмертными. Чтобы этого избежать, таким классам необходимо вызывать Py_DECREF для объекта-типа во время освобождения экземпляра.
Чтобы правильно перенести эти типы в 3.8, примените следующие изменения:
Удалите
Py_INCREFдля объекта-типа после выделения экземпляра – если таковой имеется. Это может произойти после вызоваPyObject_New,PyObject_NewVar,PyObject_GC_New(),PyObject_GC_NewVar()или любого другого пользовательского аллокатора, использующегоPyObject_Init()илиPyObject_INIT.Пример:
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 // Обходной путь для Python issue 35810; начиная с Python 3.8 больше не нужен PY_INCREF(type) #endif return foo; }
Убедитесь, что все пользовательские функции
tp_deallocтипов, выделяемых в куче, уменьшают счётчик ссылок типа.Пример:
static void foo_dealloc(foo_struct *instance) { PyObject *type = Py_TYPE(instance); PyObject_GC_Del(instance); #if PY_VERSION_HEX >= 0x03080000 // До Python 3.8 в этом не было необходимости (Python issue 35810) Py_DECREF(type); #endif }
(Автор: Eddie Elizondo в bpo-35810.)
Макрос
Py_DEPRECATED()реализован для MSVC. Теперь макрос должен размещаться перед именем символа.Пример:
Py_DEPRECATED(3.8) PyAPI_FUNC(int) Py_OldFunction(void);
(Автор: Zackery Spytz в bpo-33407.)
Интерпретатор больше не претендует на поддержку двоичной совместимости типов расширений между выпусками с новыми возможностями. Экспортируемая модулем расширения третьей стороны структура
PyTypeObjectдолжна содержать все слоты, ожидаемые в текущей версии Python, включаяtp_finalize(Py_TPFLAGS_HAVE_FINALIZEбольше не проверяется перед чтениемtp_finalize).(Автор: Antoine Pitrou в bpo-32388.)
Функции
PyNode_AddChild()иPyParser_AddToken()теперь принимают два дополнительных аргументаint: end_lineno и end_col_offset.Файл
libpython38.a, позволяющий инструментам MinGW линковаться напрямую сpython38.dll, больше не включается в обычный дистрибутив Windows. Если вам требуется этот файл, его можно сгенерировать с помощью инструментовgendefиdlltool, которые входят в пакет MinGW binutils:gendef - python38.dll > tmp.def dlltool --dllname python38.dll --def tmp.def --output-lib libpython38.a
Расположение установленного файла
pythonXY.dllбудет зависеть от параметров установки, а также версии и языка Windows. См. Using Python on Windows для получения дополнительной информации. Полученную библиотеку следует поместить в тот же каталог, что иpythonXY.lib, который обычно находится в каталогеlibsвашей установки Python.(Автор: Steve Dower в bpo-37351.)
Изменения байткода CPython¶CPython bytecode changes
Цикл интерпретатора был упрощён за счёт переноса логики разворачивания стека блоков в компилятор. Теперь компилятор генерирует явные инструкции для корректировки стека значений и вызова кода очистки для
break,continueиreturn.Удалены опкоды
BREAK_LOOP,CONTINUE_LOOP,SETUP_LOOPиSETUP_EXCEPT. Добавлены новые опкодыROT_FOUR,BEGIN_FINALLY,CALL_FINALLYиPOP_FINALLY. Изменено поведениеEND_FINALLYиWITH_CLEANUP_START.(Авторы: Mark Shannon, Antoine Pitrou и Serhiy Storchaka в bpo-17611.)
Добавлен новый опкод
END_ASYNC_FORдля обработки исключений, возникающих при ожидании следующего элемента в циклеasync for. (Автор: Serhiy Storchaka в bpo-33041.)MAP_ADDтеперь ожидает значение как первый элемент в стеке, а ключ – как второй элемент. Это изменение было сделано для того, чтобы ключ всегда вычислялся до значения в словарных включениях, как предложено в PEP 572. (Автор: Jörn Heissler в bpo-35224.)
Демонстрации и инструменты¶Demos and Tools
Добавлен скрипт для бенчмаркинга различных способов доступа к переменным: Tools/scripts/var_access_benchmark.py.
(Автор: Raymond Hettinger в bpo-35884.)
Краткий обзор улучшений производительности с 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
Тесты производительности проводились на процессоре Intel® Core™ i7-4960HQ processor под управлением 64-битных сборок macOS с python.org. Скрипт тестирования выводит время в наносекундах.
Заметные изменения в Python 3.8.1¶Notable changes in Python 3.8.1
Из-за серьёзных проблем безопасности параметр reuse_address функции
asyncio.loop.create_datagram_endpoint() больше не поддерживается. Это связано
с поведением сокетной опции SO_REUSEADDR в UDP. Подробнее
см. в документации loop.create_datagram_endpoint().
(Авторы: Kyle Stanley, Antoine Pitrou и Yury Selivanov в
bpo-37228.)
Заметные изменения в Python 3.8.2¶Notable changes in Python 3.8.2
Исправлена регрессия с колбэком ignore функции shutil.copytree().
Типы аргументов снова стали str и List[str].
(Авторы: Manuel Barkhau и Giampaolo Rodola в gh-83571.)
Заметные изменения в Python 3.8.3¶Notable changes in Python 3.8.3
Константные значения флагов future в модуле __future__
обновлены, чтобы предотвратить конфликт с флагами компилятора. Ранее
PyCF_ALLOW_TOP_LEVEL_AWAIT конфликтовал с CO_FUTURE_DIVISION.
(Автор: Batuhan Taskaya в gh-83743)
Заметные изменения в Python 3.8.8¶Notable changes in Python 3.8.8
В более ранних версиях Python допускалось использование как ;, так и & в качестве
разделителей параметров запроса в urllib.parse.parse_qs() и
urllib.parse.parse_qsl(). В связи с проблемами безопасности и для соответствия
новым рекомендациям W3C, теперь разрешён только один ключ-разделитель,
по умолчанию &. Это изменение также затрагивает
cgi.parse() и cgi.parse_multipart(), так как они внутренне используют затронутые
функции. Подробнее см. в их документации.
(Авторы: Adam Goldschmidt, Senthil Kumaran и Ken Jin в bpo-42967.)
Заметные изменения в Python 3.8.9¶Notable changes in Python 3.8.9
Исправление безопасности изменяет поведение ftplib.FTP так, чтобы не доверять
IPv4-адресу, отправленному удалённым сервером при установке пассивного
канала данных. Вместо этого используется IP-адрес FTP-сервера. Для
нестандартного кода, требующего старого поведения, установите атрибут
trust_server_pasv_ipv4_address вашего экземпляра FTP в значение True. (См. gh-87451)
Заметные изменения в Python 3.8.10¶Notable changes in Python 3.8.10
Поддержка macOS 11.0 (Big Sur) и Mac на Apple Silicon¶macOS 11.0 (Big Sur) and Apple Silicon Mac support
Начиная с версии 3.8.10, Python поддерживает сборку и запуск на macOS 11
(Big Sur) и на Mac с Apple Silicon (на архитектуре ARM64).
Доступна новая универсальная сборка universal2, которая позволяет нативно
поддерживать как ARM64, так и Intel 64 в одном наборе исполняемых файлов.
Обратите внимание, что поддержка «слабого связывания» (weaklinking) – сборки
бинарных файлов для новых версий macOS, которые также корректно работают на
старых версиях благодаря проверке отсутствующих функций во время выполнения –
не включена в этот бэкпорт из Python 3.9; для поддержки диапазона версий macOS
продолжайте ориентироваться на самую старую версию в этом диапазоне и собирать
на ней.
(Первоначально предоставлено Ronald Oussoren и Lawrence D’Anna в gh-85272, с исправлениями от FX Coudert и Eli Rykoff, бэкпортировано в 3.8 Maxime Bélanger и Ned Deily)
Заметные изменения в Python 3.8.10¶Notable changes in Python 3.8.10
urllib.parse¶
The presence of newline or tab characters in parts of a URL allows for some
forms of attacks. Following the WHATWG specification that updates RFC 3986,
ASCII newline \n, \r and tab \t characters are stripped from the
URL by the parser in urllib.parse preventing such attacks. The removal
characters are controlled by a new module level variable
urllib.parse._UNSAFE_URL_BYTES_TO_REMOVE. (See bpo-43882)
Заметные изменения в Python 3.8.12¶Notable changes in Python 3.8.12
Изменения в Python API¶Changes in the Python API
Начиная с Python 3.8.12 модуль ipaddress больше не принимает
ведущие нули в строках IPv4-адресов. Ведущие нули неоднозначны и
некоторые библиотеки интерпретируют их как восьмеричную запись. Например, устаревшая
функция socket.inet_aton() трактует ведущие нули как восьмеричную запись.
Реализация glibc современного inet_pton() не принимает
ведущие нули.
(Первоначально предоставлено Christian Heimes в bpo-36384, бэкпортировано в 3.8 Achraf Merzouki.)
Заметная функция безопасности в 3.8.14¶Notable security feature in 3.8.14
Преобразование между int и str по основаниям, отличным от 2 (двоичное), 4, 8 (восьмеричное), 16 (шестнадцатеричное) или 32, таким как основание 10 (десятичное), теперь вызывает ValueError, если количество цифр в строковом представлении превышает лимит, чтобы избежать потенциальных атак типа «отказ в обслуживании» из-за алгоритмической сложности. Это смягчение для CVE 2020-10735. Этот лимит можно настроить или отключить с помощью переменной окружения, флага командной строки или API sys. См. документацию ограничения длины строкового представления целых чисел. Лимит по умолчанию – 4300 цифр в строковом представлении.
Заметные изменения в 3.8.17¶Notable changes in 3.8.17
tarfile¶
Методы извлечения в
tarfileиshutil.unpack_archive()получили новый аргумент filter, позволяющий ограничивать возможности tar, которые могут быть неожиданными или опасными, например создание файлов за пределами целевого каталога. Подробнее см. Extraction filters. В Python 3.12 использование без аргумента filter вызоветDeprecationWarning. В Python 3.14 значение по умолчанию будет изменено на'data'. (Автор: Petr Viktorin в PEP 706.)