PEP 747 – 타입 폼 어노테이션
- Author:
- David Foster <david at dafoster.net>, Eric Traut <erictr at microsoft.com>
- Sponsor:
- Jelle Zijlstra <jelle.zijlstra at gmail.com>
- Discussions-To:
- Discourse thread
- Status:
- Final
- Type:
- Standards Track
- Topic:
- Typing
- Created:
- 27-May-2024
- Python-Version:
- 3.15
- Post-History:
- 19-Apr-2024, 04-May-2024, 17-Jun-2024
- Resolution:
- 20-Feb-2026
Table of Contents
번역·라이선스 안내
이 비공식 한국어 번역은 원문 Copyright 절의 Public Domain or CC0-1.0, whichever is more permissive 조건에 따라 제공합니다. 원저자와 공식 원문은 그대로 표시합니다. 수정되지 않은 기준 원문 · 공식 최신판
초록
타입 표현식은 Python 타입 시스템에서 타입을 지정하는 표준화된 방법을 제공합니다. 타입 표현식을 런타임에 평가하면, 그 결과로 생성되는 타입 폼 객체에 타입 표현식이 제공한 정보가 인코딩됩니다. 이를 통해 런타임 타입 검사, 인트로스펙션, 메타프로그래밍 등 다양한 사용 사례가 가능해집니다.
이러한 사용 사례는 크게 늘어났지만, 현재 타입 폼 객체를 받는 함수에 정확하게 어노테이션을 달 방법은 없습니다. 개발자는 object처럼 지나치게 넓은 타입을 사용할 수밖에 없으며, 이 때문에 일부 사용 사례는 불가능해지고 전반적으로 타입 안전성이 떨어집니다. 이 PEP는 새로운 특수 형식 typing.TypeForm을 도입하여 이러한 한계를 해결합니다.
이 PEP는 Python 문법을 변경하지 않습니다. TypeForm을 올바르게 사용하는지는 Python 런타임이 아니라 타입 검사기만 강제하도록 의도되었습니다.
동기
타입 폼 객체를 다루는 함수는 타입 표현식의 세부 정보가 이러한 객체에 어떻게 인코딩되는지 이해해야 합니다. 예를 들어 int | str, "int | str", list[int], MyTypeAlias는 모두 유효한 타입 표현식이며, 각각 types.UnionType, builtins.str, types.GenericAlias, typing.TypeAliasType의 인스턴스로 평가됩니다.
현재는 어떤 함수가 타입 폼 객체를 받으며 이를 다루는 방법을 알고 있다는 것을 타입 검사기에 알릴 방법이 없습니다. TypeForm은 이러한 한계를 해결합니다. 예를 들어, 다음은 값이 지정된 타입에 할당 가능한지 검사하고, 할당 가능하지 않으면 None을 반환하는 함수입니다:
def trycast[T](typx: TypeForm[T], value: object) -> T | None: ...
TypeForm과 타입 변수 T를 사용하면 매개변수 typx에 전달된 타입 폼과 함수의 반환 타입 사이의 관계가 기술됩니다.
TypeForm을 TypeIs와 함께 사용하여 사용자 정의 타입 좁히기 동작을 정의할 수도 있습니다:
def isassignable[T](value: object, typx: TypeForm[T]) -> TypeIs[T]: ...
request_json: object = ...
if isassignable(request_json, MyTypedDict):
assert_type(request_json, MyTypedDict) # Type of variable is narrowed
isassignable 함수는 향상된 isinstance 검사와 비슷한 기능을 구현합니다. 이는 JSON에서 디코딩된 값이 중첩된 TypedDict, 리스트, 유니언, Literal, 또는 타입 표현식으로 기술할 수 있는 그 밖의 타입 폼으로 이루어진 특정 구조를 따르는지 검증할 때 유용합니다. 이러한 종류의 검사는 PEP 589에서 암시된 바 있지만, TypeForm 없이는 구현할 수 없었습니다.
왜 type[C]가 아닙니까?
type[C]로도 이러한 사용 사례에 충분하다고 생각할 수 있습니다. 그러나 type[C]에는 클래스 객체(builtins.type 클래스의 인스턴스)만 할당할 수 있습니다. 많은 타입 폼 객체는 이 요건을 충족하지 않습니다:
def trycast[T](typx: type[T], value: object) -> T | None: ...
trycast(str, 'hi') # OK
trycast(Literal['hi'], 'hi') # Type violation
trycast(str | None, 'hi') # Type violation
trycast(MyProtocolClass, obj) # Type violation
TypeForm 사용 사례
A survey of Python libraries를 보면 TypeForm의 혜택을 받을 수 있는 여러 범주의 함수가 있음을 알 수 있습니다:
- 할당 가능성 검사기:
- 값이 지정된 타입에 할당 가능한지 판단합니다
- 패턴 1:
def is_assignable[T](value: object, typx: TypeForm[T]) -> TypeIs[T] - 패턴 2:
def is_match[T](value: object, typx: TypeForm[T]) -> TypeGuard[T] - 예: beartype.is_bearable, trycast.isassignable, typeguard.check_type, xdsl.isa
- 변환기:
- 값이 지정된 타입에 할당 가능하면(또는 강제 변환 가능하면) 변환기는 해당 타입으로 좁혀진(또는 강제 변환된) 값을 반환합니다. 그렇지 않으면 예외가 발생합니다.
- 패턴 1:
def convert[T](value: object, typx: TypeForm[T]) -> T
- 패턴 2:
class Converter[T]: def __init__(self, typx: TypeForm[T]) -> None: ... def convert(self, value: object) -> T: ...
- 예: pydantic.TypeAdapter(T).validate_python, mashumaro.JSONDecoder(T).decode
- 타입이 지정된 필드 정의:
- 패턴:
class Field[T]: value_type: TypeForm[T]
- 예: attrs.make_class, dataclasses.make_dataclass [1], openapify
- 패턴:
조사에서는 런타임 타입 폼을 입력으로 받는 인트로스펙션 함수도 일부 확인했습니다. 현재 이 함수들은 object로 어노테이션되어 있습니다:
- 일반적인 인트로스펙션 연산:
- 패턴:
def get_annotation_info(typx: object) -> object - 예: typing.{get_origin, get_args}, typing_inspect.{is_*_type, get_origin, get_parameters}
- 패턴:
이 함수들은 타입 표현식뿐만 아니라 임의의 어노테이션 표현식을 평가한 값도 받으므로 TypeForm을 사용하도록 변경할 수 없습니다.
명세
타입 표현식이 런타임에 평가되면 그 결괏값은 타입 폼 객체입니다. 이 값은 타입 표현식에 주어진 정보를 담고 있으며, 해당 타입 표현식이 기술하는 타입을 나타냅니다.
TypeForm은 타입 표현식에서 사용될 때 타입 폼 객체의 집합을 기술하는 특수 형식입니다. TypeForm은 하나의 타입 인자를 받으며, 이 인자는 유효한 타입 표현식이어야 합니다. TypeForm[T]는 T 타입 또는 T에 할당 가능한 타입을 나타내는 모든 타입 폼 객체의 집합을 기술합니다. 예를 들어 TypeForm[str | None]은 str | None에 할당 가능한 타입을 나타내는 모든 타입 폼 객체의 집합을 기술합니다:
ok1: TypeForm[str | None] = str | None # OK
ok2: TypeForm[str | None] = str # OK
ok3: TypeForm[str | None] = None # OK
ok4: TypeForm[str | None] = Literal[None] # OK
ok5: TypeForm[str | None] = Optional[str] # OK
ok6: TypeForm[str | None] = "str | None" # OK
ok7: TypeForm[str | None] = Any # OK
err1: TypeForm[str | None] = str | int # Error
err2: TypeForm[str | None] = list[str | None] # Error
같은 정의에 따라 TypeForm[object]는 object 타입 또는 object에 할당 가능한 임의의 타입을 나타내는 타입 폼 객체를 기술합니다. Python 타입 시스템의 모든 타입은 object에 할당 가능하므로, TypeForm[object]는 모든 유효한 타입 표현식에서 평가된 모든 타입 형식 객체의 집합을 나타냅니다.
TypeForm[Any]는 타입 인자가 정적으로 알려져 있지는 않지만 유효한 타입 폼 객체인 TypeForm 타입을 기술합니다. 따라서 이 타입은 다른 어떤 TypeForm 타입과도 양방향으로 할당 가능합니다(Any는 어떤 타입과도 양방향으로 할당 가능하기 때문입니다).
타입 인자가 주어지지 않은 타입 표현식 TypeForm은 TypeForm[Any]와 동등합니다.
암시적 TypeForm 평가
정적 타입 검사기가 유효한 타입 표현식을 만나면, 그 표현식이 기술하는 타입이 T에 할당 가능한 경우 해당 표현식의 평가된 타입은 TypeForm[T]에 할당 가능해야 합니다.
예를 들어 정적 타입 검사기가 str | None 표현식을 만나면, 이 표현식은 types.UnionType의 인스턴스인 런타임 값을 생성하므로 보통은 그 타입을 UnionType으로 평가할 수 있습니다. 그러나 이 표현식은 유효한 타입 표현식이므로 TypeForm[str | None] 타입에도 할당 가능합니다:
v1_actual: UnionType = str | None # OK
v1_type_form: TypeForm[str | None] = str | None # OK
v2_actual: type = list[int] # OK
v2_type_form: TypeForm = list[int] # OK
Annotated 특수 형식은 타입 표현식에서 허용되므로, TypeForm에 할당 가능한 표현식에도 나타날 수 있습니다. Annotated에 관한 타이핑 명세의 규칙에 따라, 정적 타입 검사기는 이해하지 못하는 Annotated 메타데이터를 무시하도록 선택할 수 있습니다:
v3: TypeForm[int | str] = Annotated[int | str, "metadata"] # OK
v4: TypeForm[Annotated[int | str, "metadata"]] = int | str # OK
유효한 타입 표현식을 담은 문자열 리터럴 표현식도 마찬가지로 TypeForm에 할당할 수 있어야 합니다:
v5: TypeForm[set[str]] = "set[str]" # OK
유효한 타입 표현식
타이핑 명세는 타입 표현식의 구문 규칙을 형식 문법의 형태로 정의합니다. 의미 규칙은 문법 정의와 함께 주석으로 명시되어 있습니다. 문맥상의 요구 사항은 타이핑 명세 곳곳에서 타입 표현식 안에 나타나는 개념을 다루는 절에 자세히 설명되어 있습니다. 예를 들어, 특수 형식 Self는 클래스 안에서만 타입 표현식에 사용할 수 있으며, 타입 변수는 유효한 스코프와 연결되어 있을 때만 타입 표현식 안에서 사용할 수 있습니다.
유효한 타입 표현식이란 타입 표현식의 구문 규칙, 의미 규칙, 문맥 규칙을 모두 따르는 표현식입니다.
유효한 타입 표현식이 아닌 표현식은 TypeForm 타입으로 평가되어서는 안 됩니다:
bad1: TypeForm = tuple() # Error: Call expression not allowed in type expression
bad2: TypeForm = (1, 2) # Error: Tuple expression not allowed in type expression
bad3: TypeForm = 1 # Non-class object not allowed in type expression
bad4: TypeForm = Self # Error: Self not allowed outside of a class
bad5: TypeForm = Literal[var] # Error: Variable not allowed in type expression
bad6: TypeForm = Literal[f""] # Error: f-strings not allowed in type expression
bad7: TypeForm = ClassVar[int] # Error: ClassVar not allowed in type expression
bad8: TypeForm = Required[int] # Error: Required not allowed in type expression
bad9: TypeForm = Final[int] # Error: Final not allowed in type expression
bad10: TypeForm = Unpack[Ts] # Error: Unpack not allowed in this context
bad11: TypeForm = Optional # Error: Invalid use of Optional special form
bad12: TypeForm = T # Error if T is an out-of-scope TypeVar
bad13: TypeForm = "int + str" # Error: invalid quoted type expression
명시적 TypeForm 평가
TypeForm은 인자 하나로 호출할 수 있는 함수 역할도 합니다. 타입 검사기는 이 인자가 유효한 타입 표현식인지 검증해야 합니다:
x1 = TypeForm(str | None)
reveal_type(x1) # Revealed type is "TypeForm[str | None]"
x2 = TypeForm('list[int]')
reveal_type(x2) # Revealed type is "TypeForm[list[int]]"
x3 = TypeForm('type(1)') # Error: invalid type expression
TypeForm(T)의 정적 타입은 TypeForm[T]입니다.
런타임에 TypeForm(...) 호출 가능 객체는 전달받은 값을 그대로 반환합니다.
이 명시적 문법에는 두 가지 목적이 있습니다. 첫째, 해당 값을 타입 폼 객체로 사용하려는 개발자의 의도를 문서화합니다. 둘째, 정적 타입 검사기가 타입 표현식의 모든 규칙이 지켜졌는지 검증합니다:
x4 = type(1) # No error, evaluates to "type[int]"
x5 = TypeForm(type(1)) # Error: call not allowed in type expression
할당 가능성
TypeForm에는 타입 매개변수가 하나 있으며, 이 매개변수는 공변(covariant)입니다. 즉, B를 A에 할당할 수 있으면 TypeForm[B]를 TypeForm[A]에 할당할 수 있습니다:
def get_type_form() -> TypeForm[int]: ...
t1: TypeForm[int | str] = get_type_form() # OK
t2: TypeForm[str] = get_type_form() # Error
type[T]는 TypeForm[T]의 서브타입입니다. 즉, B를 A에 할당할 수 있으면 type[B]를 TypeForm[A]에 할당할 수 있습니다:
def get_type() -> type[int]: ...
t3: TypeForm[int | str] = get_type() # OK
t4: TypeForm[str] = get_type() # Error
TypeForm은 object의 서브타입이며, object의 모든 속성과 메서드를 가진 것으로 간주됩니다.
하위 호환성
이 PEP는 “값 표현식” 문맥(즉, 타이핑 명세가 타입 표현식을 요구하지 않는 문맥)에서 타입 표현식을 평가할 때 정적 타입 검사기가 어떻게 동작해야 하는지 명확히 합니다. TypeForm 타입 어노테이션이 없으면 기존의 타입 평가 동작이 그대로 유지되므로, 하위 호환성 문제는 생기지 않을 것으로 예상됩니다. 예를 들어, 정적 타입 검사기가 이전에 str | None 표현식의 타입을 UnionType으로 평가했다면, 이 표현식을 TypeForm 타입으로 어노테이션된 변수나 매개변수에 할당하지 않는 한 계속 그렇게 평가합니다.
교육 방법
타입 표현식은 어노테이션에서 함수 매개변수가 받는 값, 함수가 반환하는 값, 변수에 저장되는 값이 무엇인지 설명하는 데 사용됩니다:
parameter type return type
| |
v v
def plus(n1: int, n2: int) -> int:
sum: int = n1 + n2
^
|
variable type
return sum
타입 표현식은 런타임에 유효한 타입 폼 객체로 평가되며, 프로그램의 다른 데이터처럼 변수에 할당하고 조작할 수 있습니다:
a variable a type expression
| |
v v
int_type_form: TypeForm = int | None
^
|
the type of a type form object
TypeForm[]은 타입 폼 객체의 타입을 표기하는 방법입니다. 타입 폼 객체란 타입을 런타임에 표현한 것입니다.
TypeForm은 type과 비슷하지만, type은 int, str, list, MyClass 같은 클래스 객체와만 호환됩니다. TypeForm은 유효한 타입 표현식으로 표현할 수 있는 모든 타입 폼을 받아들입니다. 여기에는 대괄호를 사용하는 것(list[int]), 유니온 연산자를 사용하는 것(int | None), 특수 형식(Any, LiteralString, Never 등)이 포함됩니다.
대부분의 프로그래머는 TypeForm 매개변수를 받거나 TypeForm 값을 반환하는 함수를 직접 정의하지는 않을 것입니다. 그보다는 타입 폼 객체를 해석하고 사용할 줄 아는 라이브러리 함수에 그러한 객체를 전달하는 경우가 더 흔합니다.
예를 들어, trycast 라이브러리의 isassignable 함수는 Python의 내장 isinstance 함수처럼 사용하여 값이 특정 타입의 형태와 일치하는지 확인할 수 있습니다. isassignable은 어떤 타입 형식 객체든 입력으로 받습니다.
- 올바른 예:
from trycast import isassignable if isassignable(some_object, MyTypedDict): # OK: MyTypedDict is a TypeForm[] ...
- 잘못된 예:
if isinstance(some_object, MyTypedDict): # ERROR: MyTypedDict is not a type[] ...
고급 예제
자체 런타임 타입 검사기나 런타임에 타입 폼 객체를 값으로 다루는 함수를 작성하려는 경우, 이 절에서는 그러한 함수가 TypeForm을 사용하는 방법의 예를 제공합니다.
타입 폼 객체 인트로스펙션
typing.get_origin과 typing.get_args 같은 함수를 사용하여 일부 타입 폼 객체의 구성 요소를 추출할 수 있습니다.
import typing
from typing import TypeForm, cast
def strip_annotated_metadata[T](typx: TypeForm[T]) -> TypeForm[T]:
if typing.get_origin(typx) is typing.Annotated:
typx = cast(TypeForm[T], typing.get_args(typx)[0])
return typx
isinstance와 is를 사용하여 서로 다른 종류의 타입 폼 객체를 구별할 수도 있습니다:
import types
import typing
from typing import TypeForm, cast
def split_union(typx: TypeForm) -> tuple[TypeForm, ...]:
if isinstance(typx, types.UnionType): # X | Y
return cast(tuple[TypeForm, ...], typing.get_args(typx))
if typing.get_origin(typx) is typing.Union: # Union[X, Y]
return cast(tuple[TypeForm, ...], typing.get_args(typx))
if typx in (typing.Never, typing.NoReturn,):
return ()
return (typx,)
타입 변수와 결합하기
TypeForm은 같은 함수 정의 안의 다른 곳에서 사용되는 타입 변수로 매개변수화할 수 있습니다:
def as_instance[T](typx: TypeForm[T]) -> T | None:
return typx() if isinstance(typx, type) else None
type과 결합하기
같은 함수 정의 안에서 TypeForm과 type을 모두 같은 타입 변수로 매개변수화할 수 있습니다:
def as_type[T](typx: TypeForm[T]) -> type[T] | None:
return typx if isinstance(typx, type) else None
TypeIs 및 TypeGuard와 결합하기
타입 변수는 TypeIs 또는 TypeGuard 반환 타입에서도 사용할 수 있습니다:
def isassignable[T](value: object, typx: TypeForm[T]) -> TypeIs[T]: ...
count: int | str = ...
if isassignable(count, int):
assert_type(count, int)
else:
assert_type(count, str)
모든 TypeForm을 받을 때의 어려움
임의의 TypeForm을 입력으로 받는 함수는 가능한 다양한 타입 폼 객체를 지원해야 합니다. 이러한 함수는 작성하기 쉽지 않습니다.
- Python의 새 버전이 나올 때마다 새로운 특수 형식이 도입되며, 각각에 대해 특별한 처리가 필요할 수 있습니다.
- 따옴표로 묶인 어노테이션 [2] (
'list[str]'같은)은 (list[str]같은 것으로) 구문 분석해야 합니다. - 타입 표현식 안의 따옴표로 묶인 전방 참조를 해석하는 작업은 보통
eval()로 수행하는데, 이는 안전하게 사용하기 어렵습니다. IntTree = list[int | 'IntTree']같은 재귀 타입은 해석하기 어렵습니다.- 사용자 정의 제네릭 타입(Django의
QuerySet[User]같은)은 런타임 지원이 필요한 비표준 동작을 도입할 수 있습니다.
참조 구현
Pyright(버전 1.1.379)는 TypeForm의 참조 구현을 제공합니다.
Mypy(commit 1b7e71; 2025년 11월 3일)는 TypeForm의 참조 구현을 제공합니다.
런타임 구성 요소의 참조 구현은 typing_extensions 모듈에서 제공됩니다.
기각된 아이디어
대체 이름
TypeForm의 대체 이름들이 검토되었습니다. TypeObject와 TypeType은 너무 일반적이라고 판단되었습니다. TypeExpression과 TypeExpr도 검토되었지만, 이 객체들은 그 자체로 “표현식”이 아니라 타입 표현식을 평가한 결과이므로 혼란을 준다고 판단되었습니다.
모든 타입 표현식을 지원하도록 type[C]를 확장하기
type은 클래스 객체, 즉 type 클래스의 서브클래스를 기술하도록 설계되었습니다(designed). 타입이 type인 값은 생성자 호출을 통해 인스턴스화할 수 있다고 가정됩니다. 임의의 타입 형식 객체를 나타내도록 type의 의미를 넓히면 하위 호환성 문제가 생기고, type의 서브클래스로 한정된 값의 집합을 기술할 방법이 사라집니다.
임의의 어노테이션 표현식 허용
어떤 특수 형식은 타입 한정자 역할을 하며, 일부 어노테이션 문맥에서는 사용할 수 있지만 모든 어노테이션 문맥에서 사용할 수 있는 것은 아닙니다:
예를 들어, 타입 한정자 Final은 변수 타입으로는 사용할 수 있지만 매개변수 타입이나 반환 타입으로는 사용할 수 없습니다:
some_const: Final[str] = ... # OK
def foo(not_reassignable: Final[object]): ... # Error: Final not allowed here
def nonsense() -> Final[object]: ... # Error: Final not allowed here
Annotated를 예외로 하면, 타입 한정자는 타입 표현식에 허용되지 않습니다. TypeForm의 할당 가능성 규칙은 타입의 할당 가능성 규칙에 기반하므로 TypeForm은 타입 표현식으로 제한됩니다. Final[int]는 유효한 타입 표현식이 아니므로, Final[int]를 int에 할당할 수 있는지 묻는 것은 무의미합니다.
어노테이션 표현식을 평가하여 얻은 객체를 다루려는 함수는 앞으로도 그러한 입력을 object 매개변수로 받을 수 있습니다.
타입 형식에 대한 패턴 매칭
일부 함수는 시그니처에 있는 타입 표현식의 내부를 패턴 매칭하고 싶어 할 수 있다는 주장이 있었습니다.
한 가지 사용 사례는 함수가 입력으로 지원하는 특정한 종류의 타입 표현식을 모두 명시적으로 열거할 수 있게 하는 것입니다. 다음과 같은 패턴 매칭 문법을 생각해 봅시다:
@overload
def checkcast(typx: TypeForm[AT=Annotated[T, *A]], value: str) -> T: ...
@overload
def checkcast(typx: TypeForm[UT=Union[*Ts]], value: str) -> Union[*Ts]: ...
@overload
def checkcast(typx: type[C], value: str) -> C: ...
# ... (more)
실제로 관찰된 함수 중 개념적으로 타입 형식 객체를 받는 함수는 모두 대체로 모든 종류의 타입 표현식을 지원하려고 하므로, 특정한 부분 집합을 열거하는 것은 그다지 가치가 없어 보입니다.
또한 위의 문법은 실제로 쓰이는 전형적인 함수의 입력 제약 조건을 완전히 기술할 만큼 정밀하지 않습니다. 예를 들어, 많은 함수가 list['Movie']처럼 따옴표로 묶인 하위 표현식을 포함하는 타입 표현식을 지원하지 않습니다.
패턴 매칭의 두 번째 사용 사례는 Annotated 형식을 명시적으로 매칭하여 내부 타입 인자를 추출하고 메타데이터를 모두 제거하는 것입니다:
def checkcast(
typx: TypeForm[T] | TypeForm[AT=Annotated[T, *A]],
value: object
) -> T:
그러나 정적 타입 검사기는 이미 Annotated[T, metadata]를 T와 동등하게 취급합니다. 이 동작을 명시적으로 표현한다고 해서 얻는 추가적인 가치는 없습니다. 위의 예제는 다음과 같이 동등하면서 더 간단한 형태로 작성할 수 있습니다:
def checkcast(typx: TypeForm[T], value: object) -> T:
감사의 글
- David Foster는 이 PEP의 첫 버전 초안과 mypy 구현 초안을 작성했으며, PEP 절차 전반에 걸쳐 이 PEP를 이끌었습니다.
- Eric Traut는 설계 과정 내내 수많은 피드백을 제공하고, 원래 PEP 본문의 대대적인 개정안을 작성했으며, pyright 구현 초안을 작성했습니다.
- Jelle Zijlstra는 특히 PEP의 초기 초안에 대해 피드백을 제공하고,
TypeExpr특수 형식의typing_extensions구현 초안을 작성했습니다. - Carl Meyer와 Mehdi Drissi는 귀중한 피드백을 제공했으며, 특히
type을TypeForm에 할당하도록 허용할지 여부에 관해 의견을 주었습니다. - Cecil Curry(leycec)는 런타임 타입 검사기의 관점에서 피드백을 제공하고, 개발 중인
TypeForm특수 형식을 실제 런타임 타입 검사기(beartype)에서 실험했습니다. - Jukka Lehtosalo는 TypeForm의 mypy 구현에 대해 피드백을 제공하여 검사 알고리즘이 더 빠르게 실행되고 메모리를 덜 사용하도록 도왔습니다.
- Michael H(mikeshardmind)는 특정 종류의 타입 형식을 매칭하기 위한 문법 아이디어를 제안했습니다.
- Paul Moore는 타입 지정 입문자도 PEP에 더 쉽게 다가갈 수 있도록 여러 변경 사항을 지지했습니다.
- Tin Tvrtković(Tinche)와 Salvo ‘LtWorf’ Tomaselli는 여러 차례에 걸쳐 더 넓은 커뮤니티의 입장에서 이 PEP가 유용할 것이라는 긍정적인 피드백을 제공했습니다.
각주
Copyright
This document is placed in the public domain or under the CC0-1.0-Universal license, whichever is more permissive.