본문으로 건너뛰기
블로그로 돌아가기
개발·자동화

파이썬 3.15 변경점 정리: UTF-8 기본·lazy import·업그레이드 점검

파이썬 3.15는 2026년 10월 9일 정식 출시됐고 기본 인코딩이 UTF-8로 바뀌었다. lazy import, frozendict, Tachyon 프로파일러와 업그레이드 전 호환성 점검 항목을 정리했다.

6분 소요개발·자동화
파이썬 3.15파이썬 신기능파이썬 업그레이드lazy importUTF-8 기본 인코딩
파이썬 3.15 변경점 정리: UTF-8 기본·lazy import·업그레이드 점검

파이썬 3.15는 2026년 10월 9일 정식(final) 버전으로 나왔고, 기본 인코딩이 UTF-8로 바뀐 것이 기존 코드에 가장 먼저 영향을 주는 변경이다. 모듈 로딩을 첫 사용 때로 미루는 lazy import, 불변 딕셔너리 frozendict, 새 샘플링 프로파일러 Tachyon도 들어갔다. 업그레이드 전에는 파일을 여는 코드에 encoding이 명시돼 있는지부터 본다(2026년 10월 10일 기준).

파이썬 공식 블로그의 3.15.0 출시 공지에 따르면 3.14 이후 5,643개 커밋에 1,012명이 참여했다. 세부 동작은 Python 3.15 What's New에 나와 있다.

파이썬 3.15 신기능 한눈에 보기

인터프리터, 표준 라이브러리, 타입 힌트, C API, 빌드 쪽 변경이 함께 들어왔다. 일반 개발자가 직접 만나게 되는 것부터 정리하면 다음과 같다.

변경내용PEP
UTF-8 기본 인코딩시스템 로캘과 무관하게 입출력 기본값이 UTF-8686
lazy importlazy import json처럼 첫 사용 때 모듈을 로딩810
frozendict내장 불변 매핑 타입814
sentinel고유한 센티넬 값을 만드는 내장 타입661
컴프리헨션 언패킹[*L for L in lists]처럼 *, ** 사용798
profiling 패키지, Tachyon추적·샘플링 프로파일러를 한 패키지로 묶음799
TypedDict 추가 항목, TypeForm타입 힌트 확장728, 747

실험적 JIT 컴파일러도 개선돼, 공지에는 x86-64 Linux에서 표준 인터프리터 대비 기하평균 7~8%, AArch64 macOS에서 tail-calling 인터프리터 대비 11~12% 빨라졌다고 적혀 있다. 비교 기준이 서로 다른 수치이므로 한 표에 놓고 견주지 않는다.

파이썬 기본 인코딩 UTF-8 변경, 무엇이 달라지나

3.15부터는 open('flying-circus.txt')처럼 encoding을 주지 않아도 UTF-8로 열린다. 공식 문서는 시스템 환경과 무관하게 UTF-8이 기본이 된다고 설명한다(PEP 686). 따라서 encoding 없이 파일을 여는 기존 코드는 3.15에서 UTF-8로 해석되고, 파일이 다른 인코딩으로 저장돼 있다면 읽기 결과가 달라질 수 있다.

파이썬 3.15 기본 인코딩이 3.14까지의 로캘 인코딩에서 UTF-8로 바뀌는 것을 보여 주는 비교 도해

이전 동작이 필요하면 환경 변수 PYTHONUTF8=0 또는 실행 옵션 -X utf8=0을 쓴다. 근본적인 해결은 encoding을 명시하는 것이고, 시스템 로캘 인코딩이 꼭 필요한 곳에는 encoding='locale'(3.10부터 지원)을 쓴다. 영향받는 코드는 io 모듈 문서의 선택형(opt-in) 인코딩 경고로 찾는다. 3.10 이상에서 python -X warn_default_encoding app.py로 실행하면 encoding이 빠진 open() 호출마다 EncodingWarning이 출력되므로, 경고가 0건이 되면 인코딩 명시가 끝난 것이다.

PYTHONUTF8=0 python app.py
python -X utf8=0 app.py

lazy import 사용법: 시작 시간을 줄이는 지연 임포트

lazy import(PEP 810)는 모듈 맨 위에서 lazy를 붙여 로딩을 첫 사용 시점까지 미루는 문법이다. 공지는 명시적 lazy import가 시작 시간을 줄인다고 설명한다.

파이썬 3.15 lazy import가 import 시점에는 로딩하지 않고 첫 사용 때 모듈을 로딩하는 흐름 도해
lazy import json
lazy from pathlib import Path

print("Starting up...")  # json, pathlib은 아직 완전히 로딩되지 않음
data = json.loads('{"key": "value"}')  # 이 시점에 json 로딩

제약이 있다. 모듈 최상위에서만 쓸 수 있고 함수, 클래스 본문, try/except/finally 안에서는 SyntaxError가 난다. 로딩 실패도 임포트 줄이 아니라 처음 사용하는 줄에서 예외로 나타나므로, 모듈이 없을 때의 오류 위치가 달라진다. 전체에 적용하려면 -X lazy_imports=all 또는 PYTHON_LAZY_IMPORTS 환경 변수를 쓰고, 기본값은 normal이다. 3.15 미만과 같이 쓰는 코드는 __lazy_modules__ = ["json", "pathlib"]로 같은 효과를 낼 수 있다.

frozendict, sentinel, 컴프리헨션 언패킹

frozendict는 값을 바꿀 수 없는 매핑이다. dict의 하위 클래스가 아니라서 isinstance(arg, dict)로 타입을 검사하던 코드는 isinstance(arg, (dict, frozendict)) 또는 collections.abc.Mapping 기준으로 바꿔야 한다. 키와 값이 모두 해시 가능하면 frozendict도 해시 가능하다(PEP 814).

a = frozendict(x=1, y=2)
a['z'] = 3   # TypeError: 'frozendict' object does not support item assignment

컴프리헨션 언패킹(PEP 798)은 중첩 리스트를 펼치는 코드를 짧게 만든다. [*L for L in lists]는 [x for L in lists for x in L]와 같은 결과이고, 집합은 {*s for s in sets}, 딕셔너리는 {**d for d in dicts}로 쓴다. sentinel(PEP 661)은 고유한 센티넬 값을 간결한 표현으로 만드는 내장 타입으로, 복사 후에도 identity가 유지되고 | 연산자로 타입 표현식에 쓸 수 있다.

Tachyon 프로파일러와 profiling 패키지

PEP 799로 profiling 패키지가 생겼다. 함수 호출을 빠짐없이 기록하는 profiling.tracing(기존 cProfile의 위치)과, 일정 간격으로 스택을 표본 추출하는 profiling.sampling(Tachyon)으로 나뉜다. cProfile은 호환 별칭으로 남지만 profile 모듈은 deprecated이며 3.17에서 제거될 예정이다.

Tachyon은 실행 중인 프로세스에 코드 수정이나 재시작 없이 붙을 수 있고, 시간 기준을 wall(기본), cpu, gil 중에서 고를 수 있다. 최대 1,000,000Hz로 표본을 추출하고, 출력은 pstats, collapsed, flamegraph, gecko, heatmap 형식을 지원한다. 자세한 사용법은 What's New의 Tachyon 항목에서 이어진다.

파이썬 3.15 업그레이드 전 확인할 것

공식 문서의 호환성 항목 가운데 실제 코드에 걸릴 가능성이 큰 순서로 정리했다.

확인 항목바뀐 점할 일
파일 읽기·쓰기기본 인코딩이 UTF-8encoding 명시 또는 PYTHONUTF8=0
__cached__ 사용3.13부터 deprecated였고 이제 설정되지 않음__spec__.cached 사용
.pth 파일의 import 줄조용히 deprecated대응하는 .start 파일 형식 검토
tarfile 추출거부된 멤버를 추출하지 않음추출 결과 누락 여부 점검
importlib.metadata메타데이터 없으면 MetadataNotFound 예외예외 처리 추가
argparsesuggest_on_error 기본값 True오류 메시지 형식에 의존하는 테스트 확인
profile 모듈deprecated, 3.17 제거 예정profiling으로 이동

macOS 27.0에서는 IDLE과 tkinter의 대화상자 메뉴를 열면 앱이 멈출 수 있다고 공지에 적혀 있다. macOS 27.0 쪽 동작 변경이 원인으로 보고됐고 추적 이슈는 #158053이다. 해당 환경이라면 IDLE 사용 흐름을 먼저 시험해 본다.

파이썬 3.15 업그레이드 전 인코딩 명시, 의존성 호환, 프로파일링 교체를 점검하는 체크리스트

점검은 새 버전으로 별도 가상환경을 만들어 기존 테스트를 돌리는 것으로 시작한다. 인코딩 경고를 켜고 돌려 encoding이 빠진 호출을 찾고, 테스트가 통과하고 경고가 정리되면 배포 환경에 올린다. 새 환경에서 python --version이 3.15.0으로 나오는지, 한글이 든 텍스트 파일을 읽어 글자가 깨지지 않는지까지 확인하면 점검이 끝난다. 오늘 할 일은 프로젝트에서 open(을 검색해 encoding이 없는 줄이 몇 개인지 세는 것이다.

자주 묻는 질문

파이썬 3.15로 바로 업그레이드해도 되나요?

운영 중인 서비스라면 별도 환경에서 테스트를 먼저 돌린다. 공식 문서의 호환성 항목 가운데 encoding 없이 파일을 여는 코드와 __cached__, tarfile 추출 동작 변경이 기존 코드에 가장 먼저 걸린다.

UTF-8 기본 변경을 끄려면 어떻게 하나요?

PYTHONUTF8=0 환경 변수나 -X utf8=0 옵션으로 이전 동작을 유지할 수 있다. 다만 장기적으로는 encoding을 코드에 명시하는 쪽이 버전과 운영체제에 관계없이 안전하다.

lazy import를 함수 안에서 쓸 수 있나요?

쓸 수 없다. 모듈 최상위에서만 허용되고 함수, 클래스 본문, try 블록 안에서는 SyntaxError가 난다.

같은 주제 글

이 글이 도움이 되었다면 공유해주세요

최신 인사이트

관련 프로젝트

새 글을 이메일로 받아보세요

마케팅, 분석, 개발 인사이트를 정리해서 보내드려요.