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 조건에 따라 제공합니다. 원저자와 공식 원문은 그대로 표시합니다. 수정되지 않은 기준 원문 · 공식 최신판

초록

요청된 Python 버전과 부분적인 호환성을 활성화하도록 sys.set_python_compat_version(version)를 추가합니다. sys.get_python_compat_version()을 추가합니다.

Python 3.8과 부분적인 호환성을 구현하도록 표준 라이브러리의 일부 함수를 수정합니다.

version보다 오래된 Python 버전에 대한 하위 호환성을 거부하도록 sys.set_python_min_compat_version(version)을 추가합니다.

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

근거

자주 발전해야 할 필요성

Python이 관련성과 유용성을 유지하려면 자주 발전해야 하며, 일부 개선에는 호환성이 깨지는 변경이 필요합니다. 호환성이 깨지는 변경은 알 수 없는 수의 Python 프로젝트를 중단시킬 수 있습니다. 개발자는 이러한 이유로 기능을 구현하지 않기로 결정할 수 있습니다.

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

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

Python 2에서 Python 3으로의 마이그레이션에서 가장 큰 문제는 Python 3에 하위 호환성이 없다는 것이 아니라, 호환성이 깨지는 변경이 도입된 방식입니다.

Python 유지 관리 부담을 최소화하기 위한 부분적인 호환성

기술적으로는 이전 Python 버전과 완전한 호환성을 제공할 수 있지만, 이 PEP는 Python 프로젝트(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의 새로운 DeprecationWarningPendingDeprecatingWarning 경고는 Python 3.8 호환성 모드에서 비활성화되지 않습니다. 프로젝트가 -Werror(모든 경고를 오류로 처리)를 사용하여 테스트 모음을 실행하는 경우, 이러한 경고를 수정하거나 특정 사용 중단 경고를 사례별로 무시해야 합니다.

프로젝트를 최신 Python으로 업그레이드하기

하위 호환성이 없으면 호환되지 않는 모든 변경 사항을 한 번에 수정해야 하므로, 큰 장애물이 될 수 있습니다. 프로젝트를 이전 Python과 여러 릴리스만큼 차이가 나는 최신 Python으로 업그레이드하는 경우에는 상황이 더욱 나빠집니다.

업그레이드를 미루면 상황은 더욱 나빠질 뿐입니다. 건너뛴 각 릴리스마다 호환되지 않는 변경 사항이 더해집니다. 기술 부채는 시간이 지남에 따라 꾸준히 증가할 뿐입니다.

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

“전부 아니면 전무” 방식은 대규모 Python 2 코드 기반을 Python 3으로 이식하는 데 치명적인 장애물입니다. Python 2와 Python 3 사이의 호환되지 않는 변경 사항 목록은 길며, Python 3.x가 릴리스될 때마다 더 길어지고 있습니다.

Python 및 DeprecationWarning 정리하기

다음은 Zen of Python (PEP 20) 모토 중 하나입니다:

이를 수행하는 분명한 방법은 하나, 가능하면 오직 하나만 있어야 합니다.

Python이 발전하면 새로운 방법이 필연적으로 등장합니다. DeprecationWarnings 경고는 새로운 방법을 사용하도록 제안하기 위해 발생하지만, 많은 개발자는 기본적으로 조용히 처리되는 이러한 경고를 무시합니다(__main__ 모듈은 예외입니다. PEP 565를 참조하십시오). 경고가 너무 많으면 일부 개발자는 모든 경고를 단순히 무시하므로, 사용 중단된 코드가 제거될 때 예외만 처리하게 됩니다.

때로는 두 방법을 모두 지원하는 데 약간의 유지 관리 비용이 들지만, 개발자는 코드를 정리하기 위해 이전 방법을 제거하는 것을 선호합니다. 이러한 종류의 변경 사항은 하위 호환성이 없습니다.

일부 개발자는 Python 2 지원 종료를 평소보다 더 많은 호환되지 않는 변경 사항을 적용할 기회로 삼을 수 있습니다.

선택적으로 활성화할 수 있는 하위 호환성을 추가하면 애플리케이션이 중단되는 것을 방지하고 개발자가 이러한 정리를 계속할 수 있게 합니다.

유지 관리 부담 재분배하기

하위 호환성은 호환되지 않는 변경 사항의 작성자를 업그레이드 경로에 더 많이 참여시킵니다.

하위 호환성의 예

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}')

하위 호환성이 요청된 경우에만 __getattr__()함수를 다시 추가하여 Python 3.9에서 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): minimum호환성 버전을 설정합니다. 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.8sys.set_python_compat_version((3, 8))을 호출합니다.

PYTHONCOMPATVERSIONVERSION=VERSIONPYTHONCOMPATMINVERSION=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()에는 asyncawait를 키워드로 간주하지 않도록 하는 문서화되지 않은 _feature_version이 있습니다.

언어의 가장 최근 주요 하위 호환성이 깨지는 변경은 Python 3.7에서 이루어졌으며, 이 변경으로 asyncawait가 실제 키워드가 되었습니다. 영향을 받은 프로젝트는 Twisted뿐이었던 것으로 보이며, Twisted에는 영향을 받은 함수가 하나 있었고(이 함수는 async라는 매개변수를 사용했습니다)입니다.

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

from __future__ import python38_syntax

pythonXY_syntax__future__ 모듈에 추가합니다. 이렇게 하면 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를 업데이트합니다. 예를 들어 Python 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 모듈의 코드는 asyncawait가 실제 키워드일 것을 요구합니다(변경은 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 Language Moratorium”은 Python 3.1과 Python 3.2에 대해 Python 언어의 구문, 의미론 및 내장 기능에 대한 모든 변경을 일시적으로 유예(중단)할 것을 제안했습니다.

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

Barry Warsaw가 이에 대해 요청한 내용:

Python이 향후 10년 동안 계속 중요하고 유용한 상태로 남는 방법이 언어의 모든 발전을 중단하는 것이라고는 믿지 않습니다. 5년 후, 하물며 10년 후의 컴퓨팅 환경이 어떤 모습일지 누가 알겠습니까? 10년간의 유예 기간처럼 자의적인 조치는 (다시 말해, 제 개인적인 의견으로는) 언어에 대한 사형 선고입니다.

PEP 387

PEP 387 – Backwards Compatibility Policy는 호환되지 않는 변경을 수행하기 위한 프로세스를 제안합니다. 핵심은 프로세스의 네 번째 단계입니다.

피드백이 있는지 확인하십시오. 원래 논의에 참여하지 않았던 사용자도 경고를 본 후 이제 의견을 제시할 수 있습니다. 재고해 볼 수도 있습니다.

PEP 497

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

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

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

호환되지 않는 변경의 예

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의 호환되지 않는 변경 사항 예시:

  • asyncawait는 이제 예약어입니다.
  • 문서화되지 않은 여러 내부 임포트가 제거되었습니다. 한 예로 os.errno는 더 이상 사용할 수 없으므로, 대신 직접 import errno를 사용하십시오. 이러한 문서화되지 않은 내부 임포트는 마이크로 버전 릴리스에서도 예고 없이 언제든지 제거될 수 있음에 유의하십시오.
  • re.sub()의 치환 템플릿에서 '\'와 ASCII 문자로 구성된 알 수 없는 이스케이프는 Python 3.5에서 폐지 예고되었으며, 이제 오류를 발생시킵니다.
  • asyncio.windows_utils.socketpair() 함수가 제거되었습니다: 이는 socket.socketpair()의 별칭이었습니다.
  • asyncio는 더 이상 selectors_overlapped 모듈을 asyncio.selectorsasyncio._overlapped로 내보내지 않습니다. from asyncio import selectorsimport selectors로 교체하십시오.
  • PEP 479가 Python 3.7의 모든 코드에 대해 활성화되어, 코루틴과 제너레이터에서 직접 또는 간접적으로 발생한 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, compileallpy_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_okTrue이고 디렉터리가 이미 존재하는 경우에도, 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()asyncio 모듈에 Python 3.5.2에서 추가되었습니다.

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

참고 자료

승인된 PEP:

초안 PEP: