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

Python 개선 제안 한국어 번역

PEP 613 – 명시적 타입 별칭

Author:
Shannon Zhu <szhu at fb.com>
Sponsor:
Guido van Rossum <guido at python.org>
Discussions-To:
Typing-SIG thread
Status:
Final
Type:
Standards Track
Topic:
Typing
Created:
21-Jan-2020
Python-Version:
3.10
Post-History:
21-Jan-2020

Table of Contents

번역·라이선스 안내

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

Important

This PEP is a historical document: see Type aliases and typing.TypeAlias 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는 할당을 타입 별칭으로 명시적으로 선언하는 방법을 공식화합니다.

동기

타입 별칭은 최상위 수준의 변수 할당으로 선언합니다. PEP 484에서는 유효한 타입 별칭과 전역 변수의 구분이 암묵적으로 결정되었습니다. 최상위 수준 할당에 어노테이션이 없고 할당된 값이 유효한 타입이면, 할당 대상 이름은 유효한 타입 별칭입니다. 그렇지 않으면 그 이름은 타입 힌트로 사용할 수 없는 단순한 전역 값일 뿐입니다.

이러한 암묵적 타입 별칭 선언 규칙은 타입 별칭이 전방 참조나 유효하지 않은 타입을 포함하거나, 타입 별칭 선언에 적용되는 다른 제약을 위반할 때 혼란을 일으킵니다. 어노테이션이 없는 값과 타입 별칭의 구분이 암묵적이기 때문에, 모호하거나 잘못된 타입 별칭 선언은 암묵적으로 유효한 값 할당으로 처리됩니다. 이 때문에 타입 별칭으로 표현할 수 없는 표현식이 생기고, 잘못된 형식의 타입 별칭에 대한 오류 진단이 이후 단계로 미뤄집니다.

다음 예제들은 각각 기존의 암묵적 별칭 선언 때문에 생기는 최적이 아니거나 혼란스러운 동작 일부를 보여 줍니다. 비교를 위해 여기서 TypeName: TypeAlias = Expression 형식의 명시적 별칭도 소개하지만, 이 문법은 이후 섹션에서 더 자세히 다룹니다.

전방 참조:

MyType = "ClassName"
def foo() -> MyType: ...

이 코드 조각은 ClassName이 나중에 정의되기만 하면 오류가 나지 않아야 합니다. 그러나 타입 검사기는 MyType을 타입 별칭이 아닌 값 할당으로 가정할 수밖에 없으므로, (1) MyType이 어노테이션 없는 전역 문자열이라는 오류와 (2) MyType이 유효한 타입이 아니므로 반환 어노테이션으로 사용할 수 없다는 오류를 잘못 발생시킬 수 있습니다.

MyType: TypeAlias = "ClassName"
def foo() -> MyType: ...

명시적 별칭은 모호함을 없애므로 위의 두 오류 모두 발생하지 않습니다. 또한 ClassName에 문제가 있으면(즉, 실제로 나중에 정의되지 않으면) 타입 검사기가 오류를 발생시킬 수 있습니다.

오류 메시지:

MyType1 = InvalidType
MyType2 = MyGeneric(int)  # i.e., intention was MyGeneric[int]

타입 검사기는 이 코드 조각에 대해 InvalidType이 유효한 타입이 아니므로 표현식에 어노테이션을 달거나 타입 별칭을 구성하는 데 사용할 수 없다고 경고해야 합니다. 그 대신 타입 검사기는 (1) MyType이 어노테이션이 누락된 전역 표현식이라는 오류와 (2) 코드베이스 전체에서 MyType을 사용하는 모든 곳에서 MyType이 유효한 타입이 아니라는 오류를 잘못 발생시킬 수밖에 없습니다.

MyType1: TypeAlias = InvalidType
MyType2: TypeAlias = MyGeneric(int)

명시적 별칭을 사용하면 타입 검사기는 잘못된 타입 별칭의 실제 정의 위치에서 오류를 발생시키고, MyGeneric(int)와 InvalidType이 유효한 타입이 아니라는 이유를 설명할 만큼 충분한 정보를 갖게 됩니다. 값 표현식이 더 이상 전역 값으로 평가되지 않으면, 코드베이스 전체에서 MyType을 사용하는 모든 곳에서 발생하던 조치할 수 없는 타입 오류를 억제할 수 있습니다.

스코프 제약:

class Foo:
  x = ClassName
  y: TypeAlias = ClassName
  z: Type[ClassName] = ClassName

타입 별칭은 클래스 스코프 안에서 암묵적으로(x)든 명시적으로(y)든 유효합니다. 해당 줄을 클래스 변수로 해석해야 한다면, 명시적으로 어노테이션을 달아야 합니다(z).

x = ClassName
def foo() -> None:
  x = ClassName

바깥쪽 x는 유효한 타입 별칭이지만, 타입 별칭은 함수 안에서 정의할 수 없으므로 안쪽 x가 타입으로 사용되면 타입 검사기는 오류를 발생시켜야 합니다. 이는 별칭 선언 규칙이 명시적이지 않고, 타입 오류가 내부 타입 별칭 선언 위치가 아니라 이후의 모든 사용 사례에서 발생하기 때문에 혼란스럽습니다.

x: TypeAlias = ClassName
def foo() -> None:
  x = ClassName
def bar() -> None:
  x: TypeAlias = ClassName

명시적 별칭을 사용해도 바깥쪽 할당은 여전히 유효한 타입 변수입니다. foo 안에서 안쪽 할당은 x: Type[ClassName]으로 해석되어야 합니다. bar 안에서 타입 검사기는 타입 별칭을 함수 안에서 정의할 수 없다는 점을 작성자에게 알리는 명확한 오류를 발생시켜야 합니다.

명세

명시적 별칭 선언 문법은 가능한 세 가지 대입 종류, 즉 타입이 지정된 전역 표현식, 타입이 지정되지 않은 전역 표현식, 타입 별칭을 명확하게 구분합니다. 이를 통해 어노테이션을 추가하면 타입 검사가 깨지는 할당이 생기지 않으며, 값의 타입에 따라 할당의 성격을 분류하는 일도 피할 수 있습니다.

암시적 문법(기존):

x = 1  # untyped global expression
x: int = 1  # typed global expression

x = int  # type alias
x: Type[int] = int  # typed global expression

명시적 문법:

x = 1  # untyped global expression
x: int = 1  # typed global expression

x = int  # untyped global expression (see note below)
x: Type[int] = int  # typed global expression

x: TypeAlias = int  # type alias
x: TypeAlias = "MyClass"  # type alias

참고: 위 예제는 암묵적 별칭 선언과 명시적 별칭 선언을 각각 따로 보여 줍니다. 하위 호환성을 위해 타입 검사기는 두 가지를 동시에 지원해야 합니다. 즉, 타입이 지정되지 않은 전역 표현식 x = int도 여전히 유효한 타입 별칭으로 간주됩니다.

하위 호환성

명시적 별칭은 타입 별칭을 선언하는 또 다른 방법을 제공하지만, 기존의 모든 코드와 이전 방식의 별칭 선언은 예전과 같이 동작합니다.

참조 구현

Pyre 타입 검사기는 명시적 타입 별칭 선언을 지원합니다.

기각된 아이디어

명시적 별칭을 위해 몇 가지 대안 문법이 검토되었습니다:

MyType: TypeAlias[int]

이는 초기화되지 않은 변수와 매우 비슷해 보입니다.

MyType = TypeAlias[int]

위의 선택지와 마찬가지로, 이 형식은 MyType의 런타임 값이 무엇인지에 대해 혼란을 더할 수 있습니다.

이에 비해 채택된 문법인 MyType: TypeAlias = int는 여전히 MyType = int 대입 문법을 유지하면서 순전히 어노테이션으로 타입 검사기에 정보를 추가한다는 점에서 매력적입니다.

버전 이력

  • 2021-11-16
    • 클래스 스코프 안에서 TypeAlias를 허용합니다.