프로그래밍/C, C++, Java, Python

Python annotationlib 사용법

포도알77 2026. 7. 26. 15:10

Python annotationlib 사용법

annotationlib는 Python 3.14에서 추가된 표준 라이브러리 모듈이다. 공식 문서 기준으로 이 모듈은 함수, 클래스, 모듈의 annotation을 안전하게 읽기 위한 도구를 제공한다.

핵심은 세 가지다. Python 3.14부터 annotation은 기본적으로 지연 평가된다. 그래서 __annotations__를 직접 읽는 기존 습관이 항상 가장 안전한 선택은 아니다. 이때 annotationlib.get_annotations()Format 열거형을 기준으로 읽는 편이 더 명확하다.

annotationlib는 왜 생겼을까?

Python 3.14의 What's New 문서는 함수, 클래스, 모듈의 annotation이 더 이상 즉시 평가되지 않고 필요할 때 평가된다고 설명한다. 이 변경은 forward reference 문제를 줄이지만, 런타임에서 annotation을 읽는 도구에는 새로운 기준이 필요해졌다.

annotationlib는 바로 그 기준을 제공한다. PEP 749는 이 모듈이 get_annotations(), annotation format enum, ForwardRef, 그리고 __annotate__ 호출을 위한 helper를 포함한다고 설명한다.

무엇을 할 수 있을까?

공식 문서 기준으로 annotationlib의 주된 대상은 모듈, 클래스, 함수의 annotation introspection이다. 가장 자주 보는 API는 아래 세 가지다.

  • get_annotations(): annotation dict를 요청한 형식으로 계산한다.
  • Format: VALUE, FORWARDREF, STRING 형식을 고른다.
  • ForwardRef: 아직 해석되지 않은 이름을 프록시 객체로 다룬다.

실무 기준으로는 "annotation 값을 실제 객체로 바로 평가할지", "정의되지 않은 이름을 보존할지", "문자열 표현만 필요할지"를 먼저 결정하면 된다.

Format은 어떻게 고르면 될까?

형식 의미 적합한 경우
Format.VALUE annotation을 실제 값으로 평가 정상적으로 import 가능한 타입 정보를 바로 쓸 때
Format.FORWARDREF 정의되지 않은 이름은 ForwardRef로 유지 forward reference가 섞여 있어도 구조를 먼저 보고 싶을 때
Format.STRING annotation을 문자열 형태로 반환 문서화나 표시 목적처럼 사람이 읽는 표현이 필요할 때

공식 문서는 VALUE가 가장 직관적이지만, 정의되지 않은 이름이 있으면 예외가 날 수 있다고 설명한다. 반대로 FORWARDREF는 아직 풀 수 없는 이름을 보존하므로, 런타임 도구나 메타프로그래밍 코드에서 더 안전한 기본값이 될 수 있다.

get_annotations는 어떻게 쓰면 될까?

from annotationlib import Format, get_annotations

def func(value: UndefinedType) -> "None":
    return None

annotations = get_annotations(func, format=Format.FORWARDREF)
print(annotations)

Python 3.14 문서는 get_annotations()가 함수, 클래스, 모듈의 annotation dict를 계산한다고 설명한다. Format.FORWARDREF를 쓰면 아직 정의되지 않은 이름이 있어도 ForwardRef 객체로 유지할 수 있다.

반대로 실제 런타임 객체가 꼭 필요하면 Format.VALUE를 쓸 수 있다. 다만 공식 문서는 이 경우 이름 해석 실패 같은 예외가 발생할 수 있다고 명시한다.

__annotations__를 직접 읽는 것과 무엇이 다를까?

Python 3.14 포팅 가이드는 __annotations__를 직접 읽는 코드가 있다면 변경을 검토하라고 안내한다. 예시로 dataclasses도 이제 annotationlib.get_annotations()FORWARDREF 형식을 사용한다고 설명한다.

즉 단순한 애플리케이션 코드에서는 __annotations__만으로도 충분할 수 있지만, 라이브러리나 프레임워크처럼 다양한 annotation 상태를 다뤄야 하는 코드라면 annotationlib가 더 안정적인 인터페이스다.

클래스 생성 중에도 쓸 수 있을까?

공식 문서는 get_annotate_from_class_namespace()를 별도 함수로 제공한다. 이 함수는 클래스가 완전히 만들어지기 전, 예를 들어 metaclass에서 namespace를 다루는 시점에 annotate function을 꺼낼 때 유용하다고 설명한다.

클래스가 이미 생성된 뒤에는 보통 get_annotations()를 쓰면 된다. 정리하면 "생성 중이면 namespace helper, 생성 후면 get_annotations"로 기억하면 된다.

보안 관점에서 주의할 점

공식 문서는 annotationlib의 대부분 기능이 임의 코드를 실행할 수 있다고 경고한다. PEP 749도 annotation 접근 자체가 임의 코드 실행으로 이어질 수 있다고 설명한다.

따라서 신뢰하지 않는 코드 객체의 annotation을 자동으로 읽는 도구를 만들 때는 주의가 필요하다. 특히 서버에서 외부 플러그인이나 사용자 코드의 annotation을 분석한다면, "단순 조회니까 안전하다"라고 가정하면 안 된다.

버전 호환은 어떻게 봐야 할까?

annotationlib는 Python 3.14에서 추가됐다. 2026년 7월 26일 기준 최신 안정 문서는 Python 3.14.6이며, What's New 문서는 Python 3.14가 2025년 10월 7일 릴리스됐다고 설명한다.

또한 같은 문서는 from __future__ import annotations의 현재 동작이 Python 3.14에서 그대로 유지되지만, 이 future import는 deprecated 되었고 Python 3.13 지원 종료 이후에 제거될 예정이라고 안내한다. 따라서 Python 3.13 이하 호환이 남아 있다면 버전별 동작 차이를 같이 고려해야 한다.

실무 적용 기준

  • Python 3.14 이상에서 annotation introspection이 필요하면 annotationlib.get_annotations()를 우선 검토한다.
  • 정의되지 않은 이름이 섞일 수 있으면 Format.FORWARDREF가 무난하다.
  • 문서 출력이나 UI 표시 목적이면 Format.STRING이 더 직접적이다.
  • 신뢰하지 않는 코드의 annotation을 읽을 때는 코드 실행 가능성을 전제로 설계한다.

annotationlib는 단순히 새 모듈 하나가 추가된 정도가 아니다. Python 3.14의 지연 평가 annotation 모델을 런타임에서 다루기 위한 표준 인터페이스에 가깝다. annotation을 읽는 라이브러리, 문서 생성기, 메타프로그래밍 코드라면 우선 이해해 둘 가치가 있다.

FAQ

annotationlib는 Python 3.13에서도 쓸 수 있을까?

표준 라이브러리의 annotationlib는 Python 3.14에서 추가됐다. Python 3.13 이하에서는 표준 모듈로 사용할 수 없다.

기본값으로는 어떤 Format이 무난할까?

실제 값이 반드시 필요한 상황이 아니라면 Format.FORWARDREF가 더 안전한 편이다. 공식 문서도 VALUE 형식은 이름 해석 오류를 일으킬 수 있다고 설명한다.

STRING 형식이면 코드 실행 위험이 없을까?

아니다. PEP 749는 STRING 형식을 써도 annotation 접근이 임의 코드 실행으로 이어질 수 있다고 설명한다.

참고 자료

반응형
페이스북으로 공유카카오톡으로 공유카카오스토리로 공유트위터로 공유URL 복사