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

Python 개선 제안 한국어 번역

PEP 561 – 타입 정보 배포 및 패키징

Author:
Emma Harper Smith <emma at python.org>
Status:
Final
Type:
Standards Track
Topic:
Packaging, Typing
Created:
09-Sep-2017
Python-Version:
3.7
Post-History:
10-Sep-2017, 12-Sep-2017, 06-Oct-2017, 26-Oct-2017, 12-Apr-2018

Table of Contents

번역·라이선스 안내

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

Important

This PEP is a historical document: see Type information in libraries for up-to-date specs and documentation. Canonical typing specs are maintained at the typing specs site; runtime typing behaviour is described in the CPython documentation.

×

See the typing specification update process for how to propose changes to the typing spec.

초록

PEP 484는 타이핑을 점진적으로 적용하고 쉽게 도입할 수 있도록 하는 것을 목표로 Python에 타입 힌트를 도입했습니다. 현재 타입 정보는 수동으로 배포해야 합니다. 이 PEP는 기존 도구를 활용하여 최소한의 작업으로 타입 정보를 패키징하고 배포하는 표준화된 방법과, 타입 검사기가 모듈을 확인하고 타입 검사를 위해 이 정보를 수집할 수 있도록 하는 순서를 제공합니다.

근거

현재 패키지 작성자는 인라인 타입 정보가 포함된 코드를 배포하고자 합니다. 또한 유지 관리자는 새로운 어노테이션 구문을 사용하면서 Python 2 하위 호환성을 유지하기 위해 스텁 파일을 배포하고자 합니다. 그러나 타입 정보가 포함된 패키지를 배포하는 표준 방법은 없습니다. 또한 스텁 파일을 비공개로 제공하려는 경우 사용할 수 있는 유일한 방법은 MYPYPATH 또는 이에 상응하는 설정을 통해 스텁을 수동으로 가리키는 것입니다. 패키지를 공개적으로 릴리스할 수 있다면 typeshed [1]에 추가할 수 있습니다. 그러나 이는 확장되지 않으며 typeshed 유지 관리자에게 부담이 됩니다. 또한 스텁의 버그 수정을 typeshed를 사용하는 도구의 릴리스에 종속시킵니다.

PEP 484에는 타이핑 정보 배포에 관한 간략한 절이 있습니다. 이 에서 PEP는 스텁 파일을 제공할 때 shared/typehints/pythonX.Y/를 사용할 것을 권장합니다. 그러나 각 서드 파티 라이브러리의 스텁 파일 경로를 수동으로 추가하는 방식은 확장되지 않습니다. 사람들이 선택한 가장 간단한 방법은 site-packagesMYPYPATH에 추가하는 것이지만, 이로 인해 타입 검사기가 매우 동적인 패키지(예: sqlalchemy 및 Django)에서 실패합니다.

용어 정의

“MAY”, “MUST”, “SHOULD” 및 “SHOULD NOT”의 정의는 RFC 2119에 설명된 대로 해석해야 합니다.

“inline” - PEP 526PEP 3107 구문을 사용하여 타입이 런타임 코드의 일부인 경우입니다(파일 이름은 .py로 끝납니다).

“stubs” - 타입 정보만 포함하고 런타임 코드는 포함하지 않는 파일입니다(파일 이름은 .pyi로 끝납니다).

“Distributions”는 릴리스를 공개하고 배포하는 데 사용되는 패키징된 파일입니다. (PEP 426)

“Module”은 Python 런타임 코드 또는 스텁 타입 정보가 포함된 파일입니다.

“Package”는 Python 모듈을 네임스페이스로 만드는 하나 이상의 디렉터리입니다. (패키지와 배포물의 차이에 유의하십시오. 대부분의 배포물은 설치하는 하나의 패키지 이름을 따르지만, 일부 배포물은 여러 패키지를 설치합니다.)

사양

패키지에서 타이핑을 지원하는 데에는 여러 동기와 방법이 있습니다. 이 PEP는 타이핑 사용자가 만들고자 하는 패키지를 세 가지 유형으로 구분합니다.

  1. 패키지 유지 관리자는 인라인으로 타입 정보를 추가하고자 합니다.
  2. 패키지 유지 관리자는 스텁을 통해 타입 정보를 추가하고자 합니다.
  3. 서드 파티 또는 패키지 유지 관리자는 패키지의 스텁 파일을 공유하고자 하지만, 해당 스텁 파일을 패키지 소스에 포함하고 싶어 하지 않습니다.

이 PEP는 세 가지 시나리오를 모두 지원하고 패키징 및 배포에 간단히 추가할 수 있도록 하는 것을 목표로 합니다.

이 명세의 두 주요 부분은 패키징 명세와 모듈 타입 정보를 해결하기 위한 순서입니다. 타입 검사 명세는 shared/typehints/pythonX.Y/ PEP 484의 명세를 대체하기 위한 것입니다.

새 서드파티 스텁 라이브러리는 typeshed에 추가하는 대신 이 PEP에서 제안하는 서드파티 패키징 방법을 통해 스텁을 배포해야 합니다. Typeshed는 계속 사용되지만, 유지 관리자가 확보되면 typeshed의 서드파티 스텁을 자체 패키지로 분리할 수 있습니다.

타입 정보 패키징

타입 정보를 최대한 간단하고 쉽게 패키징하고 배포하기 위해, 패키징과 배포는 기존 프레임워크를 통해 수행합니다.

코드의 타입 검사를 지원하려는 패키지 유지 관리자는 타이핑을 지원하는 패키지에 py.typed라는 이름의 마커 파일을 추가해야 합니다. 이 마커는 재귀적으로 적용됩니다. 최상위 패키지가 이 마커를 포함하면 모든 하위 패키지도 타입 검사를 지원해야 합니다. 이 파일을 패키지와 함께 설치하려면 유지 관리자는 아래에 표시된 distutils의 package_data와 같은 기존 패키징 옵션을 사용할 수 있습니다.

Distutils 옵션 예제:

setup(
    ...,
    package_data = {
        'foopkg': ['py.typed'],
    },
    ...,
    )

네임스페이스 패키지(PEP 420 참조)의 경우 충돌을 방지하고 명확성을 높이기 위해 py.typed 파일을 네임스페이스의 하위 모듈에 두어야 합니다.

이 PEP는 네임스페이스 패키지 내의 모듈 전용 배포판이나 단일 파일 모듈의 일부로 타이핑 정보를 배포하는 것을 지원하지 않습니다.

단일 파일 모듈은 패키지로 리팩터링하고, 위에서 설명한 방식으로 해당 패키지가 타이핑을 지원한다는 것을 나타내야 합니다.

스텁 전용 패키지

모든 타입 정보가 포함된 스텁 파일을 제공하려는 패키지 유지 관리자의 경우, *.pyi 스텁을 해당 *.py 파일과 나란히 두는 것이 바람직합니다. 그러나 스텁을 별도의 패키지에 넣어 별도로 배포할 수도 있습니다. 서드파티가 스텁 파일을 배포하려는 경우에도 이 방법이 유용할 수 있습니다. 스텁 패키지의 이름은 foopkg라는 패키지의 타입 스텁에 대해 foopkg-stubs 체계를 따라야 합니다. 스텁 전용 패키지에는 py.typed 마커를 추가할 필요가 없습니다. *-stubs라는 이름만으로도 해당 패키지가 타이핑 정보의 출처임을 나타내기에 충분하기 때문입니다.

스텁 파일을 배포하려는 서드파티는 패키지 유지 관리자가 패키지와 함께 배포하는 방안을 논의할 수 있도록 해당 유지 관리자에게 연락하는 것이 권장됩니다. 유지 관리자가 스텁 파일이나 타입 정보를 인라인으로 유지 관리하거나 패키징하기를 원하지 않는 경우에는 서드파티 스텁 전용 패키지를 만들 수 있습니다.

또한 스텁 전용 배포판은 일반적인 의존성 데이터를 통해 런타임 배포판의 지원 버전을 표시함으로써 어떤 런타임 패키지 버전을 지원하는지 나타내야 합니다. 예를 들어, flyingcircus-stubs 스텁 패키지는 distutils 기반 도구의 install_requires를 통해 또는 다른 패키징 도구의 동등한 기능을 통해 지원하는 런타임 flyingcircus 배포판의 버전을 나타낼 수 있습니다. pip 9.0에서는 flyingcircus-stubs를 업데이트하면 flyingcircus도 업데이트된다는 점에 유의하십시오. pip 9.0에서는 --upgrade-strategy=only-if-needed 플래그를 사용할 수 있습니다. pip 10.0에서는 이것이 기본 동작입니다.

네임스페이스 패키지(PEP 420 참조)의 경우 스텁 전용 패키지는 루트 네임스페이스 패키지에만 -stubs 접미사를 사용해야 합니다. 모든 스텁 전용 네임스페이스 패키지는 __init__.pyi 파일을 생략해야 합니다. 스텁 전용 패키지에는 py.typed 마커 파일이 필요하지 않지만, 인라인 타입이 있는 패키지와 마찬가지로 사용하는 경우에는 충돌을 방지하고 명확성을 높이기 위해 네임스페이스의 하위 모듈에 두어야 합니다.

예를 들어, pentagonhexagonshapes.polygons 네임스페이스 패키지 내에 설치되는 별도의 배포판인 경우, 이에 대응하는 타입 전용 배포판은 다음과 같이 배치된 패키지를 생성해야 합니다.:

shapes-stubs
└── polygons
    └── pentagon
        └── __init__.pyi

shapes-stubs
└── polygons
    └── hexagon
        └── __init__.pyi

타입 검사기 모듈 해결 순서

다음은 이 PEP를 지원하는 타입 검사기가 타입 정보를 포함하는 모듈을 해결해야 하는 순서입니다.

  1. 경로의 시작 부분에 수동으로 배치된 스텁 또는 Python 소스입니다. 타입 검사기는 사용자가 사용할 스텁을 완전히 제어하고 패키지의 손상된 스텁이나 인라인 타입을 수정할 수 있도록 이를 제공해야 합니다. mypy에서는 $MYPYPATH 환경 변수를 사용할 수 있습니다.
  2. 사용자 코드 — 타입 검사기가 실행 중인 파일입니다.
  3. 스텁 패키지 — 이러한 패키지는 설치된 모든 인라인 패키지보다 우선해야 합니다. foopkg 패키지의 경우 foopkg-stubs에서 찾을 수 있습니다.
  4. py.typed 마커 파일이 있는 패키지의 경우—설치된 패키지를 재정의하는 것이 없고 또한 타입 검사에 참여하는 경우, 패키지에 포함된 타입을 사용해야 합니다(해당 타입이 .pyi 타입 스텁 파일에 있든 .py 파일에 인라인으로 있든 관계없이).
  5. Typeshed(사용되는 경우) — 표준 라이브러리 타입과 여러 서드 파티 라이브러리를 제공합니다.

타입 검사기가 3단계에서 원하는 모듈이 없는 스텁 전용 네임스페이스 패키지를 식별하면 4/5단계로 계속 진행해야 합니다. 타입 검사기는 __init__.pyi가 없는 것을 기준으로 네임스페이스 패키지를 식별해야 합니다. 이를 통해 서로 다른 서브패키지가 인라인 방식과 스텁 전용 방식 중 하나를 독립적으로 선택할 수 있습니다.

실행 중인 버전과 다른 Python 버전을 검사하는 타입 검사기는 해당 Python 버전의 site-packages/dist-packages에서 타입 정보를 찾아야 합니다. 예를 들어 pythonX.Y -c 'import site; print(site.getsitepackages())'로 이를 조회할 수 있습니다. 타입 검사기가 경로에 없는 경우를 대비하여 사용자가 특정 Python 바이너리를 지정할 수 있도록 하는 것도 권장됩니다.

부분 스텁 패키지

많은 스텁 패키지는 특히 처음에는 라이브러리의 타입 인터페이스 중 일부만 완성합니다. 타입 검사와 코드 편집기에 도움이 되도록 패키지를 “부분적”으로 만들 수 있습니다. 이는 스텁 패키지에서 찾을 수 없는 모듈을 위의 모듈 확인 순서 중 4단계와 5단계, 즉 인라인 패키지와 Typeshed에서 검색해야 함을 의미합니다.

타입 검사기는 스텁 패키지와 런타임 패키지 또는 Typeshed 디렉터리를 병합해야 합니다. 이는 기능적으로 스텁 패키지를 해당 런타임 패키지 또는 Typeshed 폴더와 동일한 디렉터리에 복사한 다음 결합된 디렉터리 구조를 타입 검사하는 것과 같다고 생각할 수 있습니다. 따라서 타입 검사기는 *.py 파일보다 *.pyi 파일을 먼저 검사하는 일반적인 확인 순서를 유지해야 합니다.

스텁 패키지 배포본이 부분적이면 py.typed 파일에 partial\n을 포함해야 합니다. 네임스페이스 패키지 내에서 배포되는 스텁 패키지(PEP 420 참조)의 경우, py.typed 파일은 네임스페이스의 서브모듈에 있어야 합니다.

여러 배포본이 네임스페이스 패키지를 채울 수 있으므로, 타입 검사기는 스텁 패키지 내의 네임스페이스 패키지를 불완전한 것으로 취급해야 합니다. 스텁 패키지 배포본의 네임스페이스 패키지 내 일반 패키지는 partial\n이 포함된 py.typed 파일이 없는 한 완전한 것으로 간주됩니다.

구현

타입 지정 지원을 나타내기 위해 제안된 방식은 완전히 하위 호환되며 패키지 도구를 수정할 필요가 없습니다. 인라인 타입이 포함된 샘플 패키지 [typed_package][stub_package]를 사용할 수 있습니다. 설치된 패키지의 메타데이터를 읽고 해당 상태를 타입 미지정, 인라인 타입 지정 또는 스텁 패키지로 보고하는 샘플 패키지 검사기 [pkg_checker]도 있습니다.

mypy 타입 검사기에는 PEP 561 검색 구현이 있으며, 이에 대한 내용은 mypy 문서 [4]에서 확인할 수 있습니다.

[numpy-stubs]는 numpy 배포본을 위한 실제 스텁 전용 패키지의 예입니다.

감사의 말

이 PEP는 Ivan Levkivskyi, Jelle Zijlstra, Alyssa Coghlan, Daniel F Moisset, Andrey Vlasovskikh, Nathaniel Smith, Guido van Rossum의 아이디어, 피드백 및 지원 없이는 가능하지 않았습니다.

버전 기록

  • 2023-01-13
    • 관련 모듈 해석 순서의 4단계가 인라인 패키지뿐만 아니라 py.typed 마커 파일이 있는 모든 패키지에 적용됨을 명확히 하십시오.
  • 2021-09-20
    • 스텁 전용 네임스페이스 패키지에 대한 예상 사항과 타입 검사기의 동작을 명확히 하십시오.
    • 네임스페이스 패키지 내 단일 파일 모듈의 처리를 명확히 하십시오.
  • 2018-07-09
    • 스텁 전용 패키지 예제에 대한 링크를 추가하십시오.
  • 2018-06-19
    • 부분 스텁 패키지는 런타임 패키지뿐만 아니라 typeshed도 참조할 수 있습니다.
  • 2018-05-15
    • 부분 스텁 패키지 사양을 추가하십시오.
  • 2018-04-09
    • mypy 구현에 대한 참조를 추가하십시오.
    • 스텁 패키지 우선순위를 명확히 하십시오.
  • 2018-02-02
    • 스텁 전용 패키지 접미사를 _stubs가 아니라 -stubs로 변경하십시오.
    • 스텁 전용 패키지에는 py.typed가 필요하지 않다는 점을 명시하십시오.
    • pip 및 스텁 패키지 업그레이드에 대한 참고 사항을 추가하십시오.
  • 2017-11-12
    • 기존 도구만 사용하도록 다시 작성되었습니다.
    • 메타데이터에 타입 정보의 종류를 나타낼 필요가 없습니다.
    • 마커 파일의 이름이 .typeinfo에서 py.typed로 변경되었습니다.
  • 2017-11-10
    • 사양이 배포 메타데이터 대신 패키지 메타데이터를 사용하도록 다시 작성되었습니다.
    • 스텁 전용 패키지를 제거하고 서드 파티 패키지 사양에 통합했습니다.
    • 타입 검사기가 런타임 버전 확인을 고려하도록 제안한 내용을 제거했습니다.
    • 구현이 PEP 변경 사항을 반영하도록 업데이트되었습니다.
  • 2017-10-26
    • 구현 참조를 추가했습니다.
    • 감사의 말과 버전 기록을 추가했습니다.
  • 2017-10-06
    • distutils 전용 명령 대신 .distinfo/METADATA를 사용하도록 재작성되었습니다.
    • 서드파티 스텁 패키지의 버전 관리 방식을 명확히 했습니다.
  • 2017-09-11
    • 현재의 해결책과 typeshed에 대한 정보를 추가했습니다.
    • 근거를 명확히 했습니다.

참조