Following system colour scheme Selected dark colour scheme Selected light colour scheme

Python 개선 제안 한국어 번역

PEP 606 – Python 호환성 버전

Author:
Victor Stinner <vstinner at python.org>
Status:
Rejected
Type:
Standards Track
Created:
18-Oct-2019
Python-Version:
3.9

Table of Contents

번역·라이선스 안내

이 비공식 한국어 번역은 원문 Copyright 절의 Public Domain or CC0-1.0, whichever is more permissive 조건에 따라 제공합니다. 원저자와 공식 원문은 그대로 표시합니다. 수정되지 않은 기준 원문 · 공식 최신판

초록

요청한 파이썬 버전과의 부분적인 호환성을 활성화하는 sys.set_python_compat_version(version)을 추가합니다. sys.get_python_compat_version()을 추가합니다.

Python 3.8과의 부분 호환성을 구현하기 위해 표준 라이브러리의 몇몇 함수를 수정합니다.

version보다 오래된 파이썬 버전과의 하위 호환성을 거부하는 sys.set_python_min_compat_version(version)을 추가합니다.

-X compat_version=VERSION과 -X min_compat_version=VERSION 명령줄 옵션을 추가합니다. PYTHONCOMPATVERSION과 PYTHONCOMPATMINVERSION 환경 변수를 추가합니다.

근거

자주 발전해야 할 필요성

시의성과 유용성을 유지하려면 Python은 자주 발전해야 하며, 일부 개선 사항은 호환되지 않는 변경을 필요로 합니다. 호환되지 않는 변경은 어떤 것이든 수를 알 수 없는 Python 프로젝트를 망가뜨릴 수 있습니다. 이 때문에 개발자가 기능을 구현하지 않기로 결정할 수도 있습니다.

사용자는 새로운 기능과 더 나은 성능을 얻기 위해 최신 Python 버전을 사용하고 싶어 합니다. 호환되지 않는 변경 몇 가지 때문에 사용자가 최신 Python 버전에서 자신의 애플리케이션을 사용하지 못할 수 있습니다.

이 PEP는 두 사용 사례를 모두 충족하는 절충안으로서 오래된 Python 버전과의 부분 호환성을 추가할 것을 제안합니다.

Python 2에서 Python 3으로의 이전에서 주된 문제는 Python 3이 하위 호환되지 않는다는 점이 아니라, 호환되지 않는 변경이 도입된 방식이었습니다.

Python 유지보수 부담을 최소화하기 위한 부분 호환성

기술적으로는 오래된 파이썬 버전과의 완전한 호환성을 제공할 수도 있겠지만, 이 PEP는 파이썬 프로젝트(CPython)의 유지보수 부담을 줄이기 위해 하위 호환성을 처리하는 함수의 수를 최소화할 것을 제안합니다.

함수에 백포트 호환성을 도입하는 각 변경은 장기적인 유지보수 비용을 추정할 수 있도록 충분히 논의되어야 합니다.

하위 호환성 코드는 Python 릴리스마다 사례별로 제거됩니다. 각 호환성 함수는 유지보수 비용과, 제거했을 때의 추정 위험(망가지는 프로젝트의 수)에 따라 지원되는 Python 릴리스 수가 서로 다를 수 있습니다.

유지보수 비용은 하위 호환성을 구현하는 코드뿐만 아니라 추가되는 테스트에서도 발생합니다.

하위 호환성에서 제외되는 경우

sys.set_python_compat_version()이 호출되지 않을 때는 모든 호환성 코드의 성능 오버헤드가 낮아야 합니다.

C API는 이 PEP의 범위에 포함되지 않습니다. Py_LIMITED_API 매크로와 안정 ABI가 이 문제를 다른 방식으로 해결하고 있으니, PEP 384: Defining a Stable ABI를 참고하십시오.

의도적으로 하위 호환성을 깨뜨리는 보안 수정에는 호환성 계층이 제공되지 않습니다. 호환성보다 보안이 더 중요하기 때문입니다. 예를 들어, http.client.HTTPSConnection은 Python 3.4.3에서 필요한 모든 인증서 및 호스트 이름 검사를 기본으로 수행하도록 수정되었습니다. 이는 PEP 476: Enabling certificate verification by default for stdlib http clients에서 비롯된 의도적인 변경이었습니다(bpo-22417).

Python 언어는 하위 호환성을 제공하지 않습니다.

명백히 비호환이라고 할 수 없는 변경 사항은 이 PEP에서 다루지 않습니다. 예를 들어, Python 3.9에서는 pickle 모듈의 기본 프로토콜을 Python 3.4에서 처음 도입된 Protocol 4로 변경했습니다. 이 변경은 Python 3.4까지 하위 호환성이 있습니다. Python 3.8과의 호환성이 요청되더라도 기본적으로 프로토콜 3을 사용할 필요는 없습니다.

Python 3.9에서 새로 추가된 DeprecationWarning 및 PendingDeprecatingWarning 경고는 Python 3.8 호환 모드에서도 비활성화되지 않습니다. 프로젝트가 -Werror(모든 경고를 오류로 취급)를 사용하여 테스트 스위트를 실행한다면, 이러한 경고를 수정하거나 특정 폐지 경고를 사례별로 무시해야 합니다.

프로젝트를 더 새로운 Python으로 업그레이드하기

하위 호환성이 없으면 호환되지 않는 모든 변경 사항을 한꺼번에 수정해야 하며, 이는 진행을 가로막는 문제가 될 수 있습니다. 프로젝트를 기존 Python과 여러 릴리스만큼 떨어진 새로운 Python으로 업그레이드하는 경우에는 상황이 더욱 나빠집니다.

업그레이드를 미루면 상황이 악화될 뿐입니다. 건너뛴 릴리스마다 호환되지 않는 변경 사항이 더 늘어납니다. 기술 부채는 시간이 지날수록 꾸준히 늘어나기만 합니다.

하위 호환성이 있으면 모든 문제를 한꺼번에 수정하지 않고도 프로젝트에서 Python을 점진적으로 업그레이드할 수 있습니다.

“전부 아니면 전무(all-or-nothing)” 방식은 대규모 Python 2 코드베이스를 Python 3으로 이식하는 데 결정적인 걸림돌입니다. Python 2와 Python 3 사이의 호환되지 않는 변경 사항 목록은 길며, Python 3.x 릴리스가 나올 때마다 더 길어지고 있습니다.

Python 정리와 DeprecationWarning

Zen of Python (PEP 20)의 좌우명 중 하나는 다음과 같습니다:

어떤 일을 하는 분명한 방법이 하나– 가급적이면 오직 하나만 –있어야 합니다.

Python이 발전하면 새로운 방법이 필연적으로 등장합니다. 새로운 방법을 사용하도록 권하기 위해 DeprecationWarning이 발생하지만, 많은 개발자는 기본적으로 표시되지 않는 이 경고를 무시합니다(__main__ 모듈은 예외입니다. PEP 565를 참조하십시오). 일부 개발자는 경고가 너무 많으면 모든 경고를 그냥 무시하며, 따라서 사용 중단된 코드가 제거되어 예외가 발생할 때에야 비로소 신경을 씁니다.

때로는 두 가지 방법을 모두 지원하는 데 드는 유지 보수 비용이 크지 않지만, 개발자들은 코드를 정리하기 위해 이전 방법을 제거하는 쪽을 선호합니다. 이러한 종류의 변경은 하위 호환성을 깨뜨립니다.

일부 개발자는 Python 2 지원 종료를 평소보다 더 많은 비호환 변경을 밀어붙일 기회로 삼을 수 있습니다.

선택적(opt-in) 하위 호환성을 추가하면 애플리케이션이 깨지는 것을 방지하면서도 개발자들이 이러한 정리 작업을 계속할 수 있습니다.

유지 보수 부담의 재분배

하위 호환성은 호환되지 않는 변경을 만든 사람들이 업그레이드 과정에 더 많이 관여하게 만듭니다.

하위 호환성의 예

collections ABC 별칭

collections.abc의 ABC 클래스에 대한 별칭은 Python 3.3부터 사용 중단 상태였다가 Python 3.9에서 collections 모듈에서 제거되었습니다. 예를 들어, collections.Mapping은 더 이상 존재하지 않습니다.

Python 3.6에서는 collections/__init__.py에서 from _collections_abc import *로 별칭을 만들었습니다.

Python 3.7에서는 속성에 처음 접근할 때 DeprecationWarning을 발생시키도록 collections 모듈에 __getattr__()가 추가되었습니다:

def __getattr__(name):
    # For backwards compatibility, continue to make the collections ABCs
    # through Python 3.6 available through the collections module.
    # Note: no new collections ABCs were added in Python 3.7
    if name in _collections_abc.__all__:
        obj = getattr(_collections_abc, name)
        import warnings
        warnings.warn("Using or importing the ABCs from 'collections' instead "
                      "of from 'collections.abc' is deprecated since Python 3.3, "
                      "and in 3.9 it will be removed.",
                      DeprecationWarning, stacklevel=2)
        globals()[name] = obj
        return obj
    raise AttributeError(f'module {__name__!r} has no attribute {name!r}')

Python 3.9에서 __getattr__() 함수를 다시 추가하면 Python 3.8과의 호환성을 복원할 수 있지만, 이는 하위 호환성이 요청된 경우에만 해당합니다:

def __getattr__(name):
    if (sys.get_python_compat_version() < (3, 9)
       and name in _collections_abc.__all__):
        ...
    raise AttributeError(f'module {__name__!r} has no attribute {name!r}')

사용 중단된 open() “U” 모드

open()의 "U" 모드는 Python 3.4부터 사용 중단되었으며 DeprecationWarning을 발생시킵니다. bpo-37330은 이 모드를 제거할 것을 제안합니다. 제거되면 open(filename, "rU")는 예외를 발생시킵니다.

이 변경은 “정리(cleanup)” 범주에 속합니다. 즉, 기능을 구현하는 데 필요한 변경이 아닙니다.

하위 호환성 모드는 구현하기가 매우 쉬우며 사용자들도 환영할 것입니다.

명세

sys 함수

sys 모듈에 함수 3개를 추가합니다.

  • sys.set_python_compat_version(version): Python 호환성 버전을 설정합니다. 이전에 호출된 적이 있으면 요청된 버전 중 가장 낮은 버전을 사용합니다. sys.set_python_min_compat_version(min_version)이 호출된 적이 있고 version < min_version이면 예외를 발생시킵니다. version은 (3, 0) 이상이어야 합니다.
  • sys.set_python_min_compat_version(min_version): 최소 호환성 버전을 설정합니다. 이전에 sys.set_python_compat_version(old_version)이 호출된 적이 있고 old_version < min_version이면 예외를 발생시킵니다. min_version은 (3, 0) 이상이어야 합니다.
  • sys.get_python_compat_version(): Python 호환성 버전을 가져옵니다. 정수 3개로 이루어진 tuple을 반환합니다.

version은 정수 2개 또는 3개로 이루어진 튜플이어야 합니다. (major, minor) 버전은 (major, minor, 0)과 같습니다.

기본적으로 sys.get_python_compat_version()은 현재 Python 버전을 반환합니다.

예를 들어 Python 3.8.0과의 호환성을 요청하려면 다음과 같이 합니다.:

import collections

sys.set_python_compat_version((3, 8))

# collections.Mapping alias, removed from Python 3.9, is available
# again, even if collections has been imported before calling
# set_python_compat_version().
parent = collections.Mapping

당연히 sys.set_python_compat_version(version)을 호출해도 호출 이전에 실행된 코드에는 아무런 영향이 없습니다. Python 시작 시점에 호환성 버전을 설정하려면 -X compat_version=VERSION 명령줄 옵션이나 PYTHONCOMPATVERSIONVERSION=VERSION 환경 변수를 사용하십시오.

명령줄

-X compat_version=VERSION 및 -X min_compat_version=VERSION 명령줄 옵션을 추가합니다. 각각 sys.set_python_compat_version()과 sys.set_python_min_compat_version()을 호출합니다. VERSION은 숫자 2개 또는 3개로 이루어진 버전 문자열(major.minor.micro 또는 major.minor)입니다. 예를 들어 -X compat_version=3.8은 sys.set_python_compat_version((3, 8))을 호출합니다.

PYTHONCOMPATVERSIONVERSION=VERSION 및 PYTHONCOMPATMINVERSION=VERSION=VERSION 환경 변수를 추가합니다. 각각 sys.set_python_compat_version()과 sys.set_python_min_compat_version()을 호출합니다. VERSION은 명령줄 옵션과 같은 형식의 버전 문자열입니다.

하위 호환성

sys.set_python_compat_version() 함수를 도입하면 애플리케이션이 호환성 버전에 따라 다르게 동작하게 됩니다. 게다가 버전을 여러 번 낮출 수 있으므로 애플리케이션이 임포트 순서에 따라 다르게 동작할 수 있습니다.

sys.set_python_compat_version((3, 8))을 사용한 Python 3.9는 Python 3.8과 완전히 호환되지 않습니다. 호환성은 부분적일 뿐입니다.

보안 영향

sys.set_python_compat_version()은 보안 수정 사항을 비활성화해서는 안 됩니다.

대안

호환되지 않는 변경마다 우회 방법 제공

애플리케이션은 자신에게 영향을 주는 호환되지 않는 변경 대부분을 우회할 수 있습니다.

예를 들어, collections 별칭은 다음을 사용하여 다시 추가할 수 있습니다:

import collections.abc
collections.Mapping = collections.abc.Mapping
collections.Sequence = collections.abc.Sequence

파서에서 하위 호환성 처리하기

파서는 Python 언어의 여러 버전(문법)을 지원하도록 수정됩니다.

현재의 Python 파서는 이를 위해 쉽게 수정할 수 없습니다. AST와 문법은 단일 Python 버전에 하드코딩되어 있습니다.

Python 3.8에서 compile()에는 async와 await를 키워드로 간주하지 않도록 하는 문서화되지 않은 _feature_version이 있습니다.

가장 최근의 하위 호환되지 않는 주요 언어 변경은 async와 await를 진짜 키워드로 만든 Python 3.7이었습니다. 영향을 받은 프로젝트는 Twisted뿐이었던 것으로 보이며, Twisted에서도 영향을 받은 함수는 하나뿐이었습니다(async라는 매개변수를 사용했습니다).

파서에서 하위 호환성을 처리하는 것은 파서를 수정하는 일뿐만 아니라, 어떤 버전의 Python 언어가 사용되는지 확인해야 하는 개발자에게도 상당히 복잡해 보입니다.

from __future__ import python38_syntax

__future__ 모듈에 pythonXY_syntax를 추가합니다. 이는 Python X.Y 문법과의 하위 호환성을 활성화하지만, 현재 파일에 대해서만 적용됩니다.

이 방식을 사용하면 파서가 같은 입력에 대해 항상 같은 출력을 생성하므로(최적화 수준은 제외), 다른 .pyc 파일 이름을 사용하기 위해 sys.implementation.cache_tag를 변경할 필요가 없습니다.

예를 들면:

from __future__ import python35_syntax

async = 1
await = 2

cache_tag 갱신하기

Python 언어의 버전을 선택하기 위해 sys.get_python_compat_version()을 사용하도록 파서를 수정합니다.

sys.set_python_compat_version()은 마이크로 버전을 제외한 호환 버전을 접미사로 포함하도록 sys.implementation.cache_tag를 갱신합니다. 예를 들어, 파이썬 3.9는 기본적으로 'cpython-39'를 사용하지만, sys.set_python_compat_version((3, 7, 2))는 cache_tag를 'cpython-39-37'로 설정합니다. 이제 마이크로 릴리스에서도 Python 언어 변경이 허용됩니다.

한 가지 문제는 이전에 sys.set_python_compat_version((3, 6))이 호출되었다면 import asyncio가 실패할 가능성이 높다는 것입니다. asyncio 모듈의 코드는 async와 await가 진짜 키워드여야 합니다(Python 3.7에서 이루어진 변경).

또 다른 문제는 일반 사용자가 시스템 디렉터리에 .pyc 파일을 쓸 수 없으므로, 필요할 때 이를 생성할 수 없다는 것입니다. 이는 하위 호환성 모드에서는 .pyc 최적화를 사용할 수 없다는 뜻입니다.

이에 대한 한 가지 해결책은 Python 설치 프로그램과 Python 패키지 설치 프로그램을 수정하여 현재 Python 버전뿐만 아니라 여러 이전 Python 버전(Python 3.0까지?)에 대해서도 .pyc 파일을 미리 컴파일하는 것입니다.

각 .py 파일은 3n개의 .pyc 파일(3가지 최적화 수준)을 갖게 되며, 여기서 n은 지원되는 Python 버전의 수입니다. 예를 들어, Python 3.8과 Python 3.9를 지원하려면 .pyc 파일이 3개가 아니라 6개가 됩니다.

호환되지 않는 변경에 대한 일시적 모라토리엄

2009년에 PEP 3003 “Python 언어 모라토리엄”은 Python 3.1과 Python 3.2에 대해 Python 언어 문법, 의미, 내장에 대한 모든 변경을 일시적으로 유예(중단)할 것을 제안했습니다.

2018년 5월, PEP 572 논의 중에 파이썬의 변경 속도를 늦추자는 제안도 있었습니다. python-dev 스레드 Slow down…를 참고하십시오.

이에 대한 Barry Warsaw의 의견:

저는 Python이 앞으로 10년 동안 계속 의미 있고 유용한 언어로 남는 방법이 언어의 모든 발전을 멈추는 것이라고 생각하지 않습니다. 10년 후는 고사하고 5년 후의 컴퓨팅 환경이 어떤 모습일지 누가 알겠습니까? 10년 모라토리엄처럼 자의적인 조치는 (다시 말하지만, 제 소견으로는) 언어에 대한 사형 선고입니다.

PEP 387

PEP 387 – Backwards Compatibility Policy는 호환되지 않는 변경을 하기 위한 절차를 제안합니다. 핵심은 이 절차의 4번째 단계입니다:

피드백이 있는지 확인하십시오. 처음 논의에 참여하지 않았던 사용자들이 이제 경고를 보고 의견을 낼 수 있습니다. 필요하다면 재고하십시오.

PEP 497

PEP 497 – A standard mechanism for backward compatibility는 하위 호환성을 제공하기 위한 여러 해결책을 제안합니다.

__past__ 메커니즘 아이디어를 제외하면, PEP 497은 구체적인 해결책을 제안하지 않습니다:

핵심 언어 문법이나 의미론에 호환되지 않는 변경이 이루어질 때, Python-dev의 정책은 새로운 future_statements와 같이 상위 호환성을 위해 제안된 메커니즘에 더해, 호환성을 깨는 변경이 기본으로 채택된 이후의 향후 Python 버전을 위해 가능한 한 하위 호환성 메커니즘도 고려하고 제공하는 것을 선호하고 기대하는 것입니다.

호환되지 않는 변경의 예

Python 3.8

Python 3.8에서 호환되지 않는 변경의 예:

  • (베타 단계 동안) PyCode_New()에 새 매개변수가 필요해졌습니다: 이로 인해 모든 Cython 확장(미리 컴파일된 Cython 코드를 배포하는 모든 프로젝트)이 깨졌습니다. 이 변경은 3.8 베타 단계 중에 되돌려졌으며, 대신 새로운 PyCode_NewWithPosOnlyArgs() 함수가 추가되었습니다.
  • types.CodeType에 필수 매개변수가 하나 더 필요합니다. 프로젝트가 더 이상 CodeType 생성자의 정확한 시그니처에 의존하지 않도록 돕기 위해 CodeType.replace() 함수가 추가되었습니다.
  • C 확장은 더 이상 libpython에 링크되지 않습니다.
  • sys.abiflags가 'm'에서 빈 문자열로 바뀌었습니다. 예를 들어, python3.8m 프로그램은 사라졌습니다.
  • C 구조체 PyInterpreterState가 불투명해졌습니다.
  • XML 속성 순서: bpo-34160. 깨진 프로젝트:

이 모든 변경 사항에 하위 호환성을 추가할 수는 없습니다. 예를 들어, C API와 빌드 시스템의 변경 사항은 이 PEP의 범위를 벗어납니다.

전체 변경 사항은 What’s New In Python 3.8: API and Feature Removals를 참조하십시오.

What’s New In Python 3.8의 Porting to Python 3.8 절도 참조하십시오.

Python 3.7

Python 3.7의 비호환 변경 사항 예시:

  • async와 await는 이제 예약 키워드입니다.
  • 문서화되지 않은 여러 내부 임포트가 제거되었습니다. 한 가지 예로, os.errno는 더 이상 사용할 수 없습니다. 대신 import errno를 직접 사용하십시오. 이처럼 문서화되지 않은 내부 임포트는 마이크로 버전 릴리스에서도 예고 없이 언제든 제거될 수 있다는 점에 유의하십시오.
  • re.sub()의 치환 템플릿에서 '\'와 ASCII 문자로 이루어진 알 수 없는 이스케이프는 Python 3.5에서 폐지 예정이 되었으며, 이제는 오류를 일으킵니다.
  • asyncio.windows_utils.socketpair() 함수가 제거되었습니다. 이 함수는 socket.socketpair()의 별칭이었습니다.
  • asyncio는 더 이상 selectors와 _overlapped 모듈을 asyncio.selectors와 asyncio._overlapped로 내보내지 않습니다. from asyncio import selectors를 import selectors로 바꾸십시오.
  • Python 3.7에서는 모든 코드에 PEP 479가 활성화됩니다. 즉, 코루틴과 제너레이터에서 직접 또는 간접적으로 발생한 StopIteration 예외는 RuntimeError 예외로 변환됩니다.
  • socketserver.ThreadingMixIn.server_close()는 이제 데몬이 아닌 모든 스레드가 완료될 때까지 기다립니다. 3.7 이전의 동작을 얻으려면 새로운 block_on_close 클래스 속성을 False로 설정하십시오.
  • struct.Struct.format의 타입은 이제 bytes가 아닌 str입니다.
  • datetime.timedelta의 repr이 출력에 키워드 인자를 포함하도록 변경되었습니다.
  • tracemalloc.Traceback 프레임은 이제 traceback과 더 일관되도록 가장 오래된 것부터 가장 최근 것 순으로 정렬됩니다.

이 변경 사항 대부분에 하위 호환성을 추가하는 것은 쉬울 것입니다.

What’s New In Python 3.7의 Porting to Python 3.7 절도 참조하십시오.

마이크로 릴리스

때로는 버그나 보안 취약점을 수정하기 위해 마이크로 릴리스(major.minor.micro의 micro)에서 비호환 변경이 도입되기도 합니다. 예는 다음과 같습니다

  • Python 3.7.2, compileall과 py_compile 모듈: invalidation_mode 매개변수의 기본값이 None으로 변경되었습니다. SOURCE_DATE_EPOCH 환경 변수는 더 이상 invalidation_mode 인자의 값을 재정의하지 않으며, 대신 그 기본값을 결정합니다.
  • Python 3.7.1, xml 모듈: 기본 보안을 강화하기 위해 SAX 파서는 더 이상 기본적으로 일반 외부 엔티티를 처리하지 않습니다.
  • Python 3.5.2, os.urandom(): Linux에서 getrandom() 시스템 호출이 블록되면(urandom 엔트로피 풀이 아직 초기화되지 않은 경우) /dev/urandom을 읽는 방식으로 대체합니다.
  • Python 3.5.1, sys.setrecursionlimit(): 새 한도가 현재 재귀 깊이에 비해 너무 낮으면 이제 RecursionError 예외가 발생합니다.
  • Python 3.4.4, ssl.create_default_context(): 기본 암호 문자열에서 RC4가 제거되었습니다.
  • Python 3.4.3, http.client: HTTPSConnection은 이제 기본적으로 필요한 모든 인증서 및 호스트 이름 검사를 수행합니다.
  • Python 3.4.2, email.message: EmailMessage.is_attachment()는 Message.is_multipart()와의 일관성을 위해 이제 프로퍼티가 아닌 메서드입니다.
  • Python 3.4.1, os.makedirs(name, mode=0o777, exist_ok=False): Python 3.4.1 이전에는 exist_ok가 True이고 디렉터리가 이미 존재하더라도, mode가 기존 디렉터리의 모드와 일치하지 않으면 makedirs()가 여전히 오류를 발생시켰습니다. 이 동작은 안전하게 구현할 수 없었기 때문에 Python 3.4.1에서 제거되었습니다(bpo-21082).

마이크로 릴리스에서 이루어졌지만 하위 호환성을 깨뜨리지 않는 변경의 예는 다음과 같습니다:

  • ssl.OP_NO_TLSv1_3 상수는 OpenSSL 1.0.2와의 하위 호환성을 위해 2.7.15, 3.6.3, 3.7.0에 추가되었습니다.
  • typing.AsyncContextManager는 Python 3.6.2에 추가되었습니다.
  • zipfile 모듈은 Python 3.6.2부터 경로류 객체(path-like object)를 받습니다.
  • loop.create_future()는 Python 3.5.2에서 asyncio 모듈에 추가되었습니다.

이러한 종류의 변경에는 하위 호환성 코드가 필요하지 않습니다.

참고 문헌

채택된 PEP:

초안 PEP: