파이썬 3.15 정식 출시, 윈도우는 UTF-8부터 확인

파이썬으로 스크립트를 짜거나 AI 도구를 돌리는 사람이라면, 2026년 10월 9일에 나온 파이썬 3.15.0에서 가장 먼저 볼 곳은 속도 표가 아니라 open() 한 줄이다.
3.15부터는 파일을 열 때 문자표(인코딩)를 따로 적지 않으면 어느 컴퓨터에서든 UTF-8로 읽고 쓴다. 공식 What’s New 문서가 “시스템 환경과 무관하게 UTF-8을 기본으로 쓴다”고 적었고, 이 변경을 제안한 PEP 686은 더 직접적이다. 이 변경은 대부분 윈도우 사용자에게 영향을 주고, 오류와 글자 깨짐, 심하면 조용한 데이터 손상까지 일으킬 수 있으니 크게 알려야 한다는 문장이 그대로 들어 있다.
이 글은 파이썬을 막 쓰기 시작한 사람도 읽을 수 있게 썼다. 인코딩, import, 프로파일러 같은 말은 나올 때마다 한 줄로 풀었다. 근거로 삼은 자료는 파이썬 공식 릴리스 페이지와 What’s New 문서, PEP 686·810 원문, Tachyon 공식 문서, 10월 1일 지원 종료 공지, 개발자 미겔 그린버그의 비공식 속도 측정, Hacker News 토론이다.
이 사이트가 3.15.0을 설치해 돌려 본 것은 없다. 직접 돌려 본 것은 두 가지다. 현재 쓰는 3.14.6에서 인코딩 경고 플래그가 실제로 어떻게 보이는지, 그리고 3.15의 새 문법이 3.14에서는 거부되는지. 나머지는 전부 공식 문서에 적힌 내용이다.
한 표로 보는 3.15: 무엇이 들어왔고 누구에게 닿나
파이썬 3.15.0은 릴리스 페이지에 따르면 커밋 5,643개, 기여자 1,012명이 만든 버전이다. 큰 변화를 한 줄씩 정리하면 이렇다.
| 이름 | 한 줄 설명 | 내 코드에 닿는 정도 |
|---|---|---|
| PEP 686 | 인코딩을 안 적은 입출력의 기본값이 UTF-8 | 윈도우에서 가장 크다 |
| PEP 810 lazy import | lazy import json — 쓰는 순간에 불러온다 |
선택 기능, 안 쓰면 변화 없음 |
| PEP 814 frozendict | 만든 뒤 바꿀 수 없는 딕셔너리가 내장 타입으로 | isinstance(x, dict) 검사에 영향 |
| PEP 661 sentinel | 고유한 표식 값을 만드는 내장 타입 | 선택 |
| PEP 798 | 컴프리헨션 안에서 *와 **로 펼치기 |
선택, 3.14 이하에선 문법 오류 |
| PEP 799 Tachyon | 돌고 있는 프로세스에 붙는 샘플링 프로파일러 | 새 도구, 기존 코드 영향 없음 |
| PEP 829 | 시작 시 실행할 코드를 적는 .start 파일 |
패키지 도구 만드는 사람 |
| PEP 831 | 프레임 포인터를 기본으로 켜고 빌드 | 네이티브 확장 만드는 사람 |
| PEP 803 | free-threaded 빌드용 안정 ABI | C 확장 만드는 사람 |
| 실험적 JIT | 공식 문서가 “크게 개선”이라고 쓴 실험 기능 | 아직 실험 |
릴리스 페이지에는 두 가지가 더 적혀 있다. 공식 윈도우 64비트 설치 파일이 꼬리 호출(tail-calling) 방식의 인터프리터를 쓰기 시작했고, 공식 맥 설치 파일은 free-threading(GIL 없는 병렬 실행) 지원을 기본으로 설치한다.
제일 먼저 확인할 것: open()의 기본 문자표가 바뀌었다
인코딩은 글자를 파일에 저장할 때 쓰는 번호표다. 같은 “가”라도 UTF-8 번호표와 CP949 번호표에서 저장되는 숫자가 다르다. 읽을 때 저장할 때와 다른 번호표를 쓰면 글자가 깨지거나 오류가 난다.
그동안 파이썬은 open("메모.txt")처럼 번호표를 안 적으면 컴퓨터의 지역 설정이 정한 번호표를 썼다. 맥과 리눅스는 대부분 UTF-8이라 문제가 눈에 안 띄었다. 윈도우는 설정에 따라 달랐다. 한국어 윈도우는 보통 CP949를 쓰는데, 이건 공식 발표문이 아니라 윈도우의 일반적인 동작이다. 같은 코드가 내 맥에서는 되고 회사 윈도우 PC에서는 깨지는 일이 여기서 나왔다.
3.15는 이 줄을 이렇게 바꿨다.
# 3.14까지: 컴퓨터마다 읽는 방식이 달랐다
# 3.15부터: 어디서나 UTF-8
with open("메모.txt") as f:
text = f.read()
# 어느 버전에서나 같게 읽히는 쓰기 방식
with open("메모.txt", encoding="utf-8") as f:
text = f.read()
What’s New 문서는 번호표를 직접 적는 습관이 버전 간 호환에 제일 좋다고 권한다. 되돌리고 싶을 때의 스위치도 적혀 있다. PYTHONUTF8=0 환경 변수나 -X utf8=0 옵션으로 UTF-8 모드를 끄면 이전 동작으로 돌아간다. encoding="locale"을 쓰면 현재 컴퓨터의 지역 설정 번호표를 명시적으로 쓸 수 있고, 이 인자는 3.10부터 지원됐다.
PEP 686은 이유로 이런 점을 든다. 웹사이트와 JSON·TOML·YAML이 UTF-8이고, Visual Studio Code와 윈도우 메모장도 UTF-8이 기본이며, Node.js·Go·Rust·Java도 UTF-8을 기본으로 쓴다. 다른 언어가 먼저 움직인 전례도 적혀 있다. 루비는 3.0(2020년)에서 윈도우의 기본 외부 인코딩을 UTF-8로 바꿨고, 자바는 JDK 18(2022년)에서 바꿨다.
내 코드에서 해당 줄을 찾는 법, 3.14.6에서 직접 돌려 봤다
번호표를 안 적은 open()을 찾는 도구가 이미 있다. What’s New 문서가 “선택해서 켜는 인코딩 경고”라고 부르는 기능이다. 이 사이트의 맥에서 쓰는 파이썬 3.14.6으로 돌려 봤다. 파일 두 줄짜리 스크립트다. 첫 open()은 인코딩을 안 적었고, 두 번째는 encoding="utf-8"을 적었다.
$ python3 -X warn_default_encoding enc.py
enc.py:1: EncodingWarning: 'encoding' argument not specified
with open("ko.txt") as f:
name = "파이썬"
name = "파이썬"
경고는 인코딩을 안 적은 첫 번째 줄에만 떴고, 적은 줄에는 안 떴다. 환경 변수로 켜는 PYTHONWARNDEFAULTENCODING=1도 같은 경고를 냈다. 즉 업그레이드하기 전에, 지금 쓰는 3.14에서 이 플래그로 내 프로그램을 한 번 돌려 보면 3.15에서 영향을 받을 줄이 미리 나온다.
경고가 나온 줄을 고치는 방법은 셋이다. 파일이 UTF-8이면 encoding="utf-8"을 적는다. 옛 윈도우 메모장으로 저장한 CP949 파일이면 encoding="cp949"를 적거나, 파일을 UTF-8로 다시 저장한다. 판단이 안 서면 encoding="locale"로 지금까지의 동작을 그대로 유지한다.
lazy import는 “필요해질 때 가져온다”는 뜻이다
import는 다른 파일(모듈)을 불러오는 줄이다. 지금까지 파이썬은 파일 맨 위의 import를 프로그램이 시작할 때 전부 실행했다. 쓰지도 않을 모듈까지 불러오느라 시작이 느렸다.
3.15에는 lazy라는 새 키워드가 생겼다. What’s New 문서의 예제를 옮기면 이렇다.
lazy import json
lazy from pathlib import Path
print("Starting up...") # json과 pathlib은 아직 안 불러왔다
data = json.loads('{"key": "value"}') # json은 여기서 불러온다
p = Path(".") # pathlib은 여기서 불러온다
lazy를 붙인 모듈은 가벼운 대리 객체로 먼저 자리를 잡아 두고, 이름을 처음 쓰는 순간에 진짜로 불러온다. 모듈이 없어서 생기는 오류도 import 줄이 아니라 처음 쓰는 곳에서 나오며, 오류 추적 기록에 처음 쓴 위치와 원래 import 줄이 둘 다 들어간다.
소스를 안 고치고 전체를 lazy로 돌리는 스위치도 있다. -X lazy_imports=all 옵션이나 PYTHON_LAZY_IMPORTS=all 환경 변수다. sys.set_lazy_imports_filter()로 우리 앱 모듈만 lazy로 하고 외부 라이브러리는 바로 불러오게 고를 수도 있다. 3.15 이전 버전도 함께 지원해야 하는 라이브러리를 위해 파일 안에 __lazy_modules__ = ["json", "pathlib"]를 적는 방법도 있다.
제약도 분명하다. lazy는 모듈 맨 위에서만 쓸 수 있다. 함수, 클래스 본문, try/except/finally 안에서 쓰면 SyntaxError다. lazy from module import *도 안 된다.
효과는 PEP 810 본문이 이렇게 설명한다. 명령줄 도구처럼 짧게 도는 프로그램은 쓰는 경로만 불러오니 시작 시간이 실제로 50~70% 줄 수 있고, 큰 앱은 쓰지 않는 하위 시스템을 안 불러와서 메모리가 30~40% 줄어든 사례가 관찰됐다고 한다. 이 숫자는 PEP 작성자들이 적은 값이고 이 사이트가 재현한 것이 아니다. 같은 문서는 파이썬 표준 라이브러리의 테스트 밖 import 중 약 17%가 이미 함수 안에 들어가 있다고 분석했다. 개발자들이 지금까지 손으로 lazy import를 흉내 내 왔다는 증거로 든 값이다.
lazy import가 깨뜨리는 코드와, 메타가 공개한 점검 도구
import를 미루면 import하는 순간 실행되던 일이 같이 미뤄진다. 모듈을 불러오자마자 어딘가에 자기 이름을 등록하는 “레지스트리” 패턴이 대표적이다. 미룬 import가 끝내 안 불리면 등록은 조용히 안 일어난다.
메타(Meta)의 GitHub 조직 facebook 아래에 이런 사고를 미리 찾는 정적 분석기 Lifeguard가 올라왔다. 저장소 설명에 따르면 파이썬 코드를 읽어서 lazy import와 충돌할 만한 패턴을 찾는다. 조심스러운 쪽으로 판정해서, 안전하다고 증명 못 한 모듈은 전부 “위험”으로 표시한다. 찾는 패턴으로 적힌 것은 모듈 맨 위의 부수 효과, 레지스트리 패턴, sys.modules 직접 조작, 메타클래스와 __init_subclass__의 생성 시 부수 효과다.
상태는 베타다. 저장소가 밝힌 목표는 “파이썬 3.15 정식 릴리스 즈음에 일반 사용이 가능한 상태”이고, 파이썬 3.12 이상에서 pip install lifeguard-lazy-imports로 설치할 수 있다고 한다. 이 도구를 이 사이트가 직접 돌려 본 것은 없다.
frozendict와 sentinel: 새 내장 타입 두 개
딕셔너리는 {키: 값} 묶음이다. 3.15에는 만든 뒤 바꿀 수 없는 딕셔너리 frozendict가 내장 타입으로 들어왔다. What’s New 문서의 예제다.
>>> a = frozendict(x=1, y=2)
>>> a['z'] = 3
TypeError: 'frozendict' object does not support item assignment
>>> b = frozendict(y=2, x=1)
>>> hash(a) == hash(b)
True
세 가지를 알아 두면 된다. frozendict는 dict의 하위 타입이 아니라 object에서 바로 나온다. 키와 값이 전부 해시 가능하면 자기도 해시 가능하다. 순서는 넣은 순서를 기억하지만 비교할 때는 순서를 따지지 않는다. copy, decimal, json, marshal, pickle, pprint 같은 표준 라이브러리 모듈이 이미 받아 준다.
그래서 이런 코드가 영향을 받는다. isinstance(arg, dict)로 딕셔너리인지 검사하던 줄은 frozendict를 통과시키지 못한다. 문서는 isinstance(arg, (dict, frozendict))로 고치거나 collections.abc.Mapping으로 검사하라고 안내한다.
sentinel은 이름과 모양이 분명한 고유 표식 값을 만드는 내장 타입이다. 예를 들어 “인자를 안 넘겼다”와 “None을 넘겼다”를 구분하고 싶을 때 쓴다. 복사해도 같은 값으로 취급되고, 타입 표기에서 |로 묶을 수 있다.
별표 하나로 중첩 반복문을 줄이는 문법
리스트 안의 리스트를 한 줄로 합치려면 지금까지 반복문을 두 겹 써야 했다. 3.15의 PEP 798은 컴프리헨션(리스트를 한 줄로 만드는 문법) 안에서 *와 **로 펼치는 것을 허용한다.
>>> lists = [[1, 2], [3, 4], [5]]
>>> [*L for L in lists] # [x for L in lists for x in L] 와 같다
[1, 2, 3, 4, 5]
>>> dicts = [{'a': 1}, {'b': 2}, {'a': 3}]
>>> {**d for d in dicts}
{'a': 3, 'b': 2}
앞의 [*L for L in lists]를 우리 맥의 3.14.6에서 돌려 봤다. 결과는 SyntaxError: iterable unpacking cannot be used in comprehension이었다. 이 문법을 쓰는 코드는 3.14 이하에서 돌지 않으므로, 여러 버전을 지원하는 라이브러리는 한동안 못 쓴다. frozendict도 3.14.6에서 NameError가 났다.
에러 메시지가 자바스크립트 말버릇을 알아듣는다
초심자에게 가장 반가운 변화일 수 있다. 존재하지 않는 속성을 불렀을 때 파이썬이 힌트를 주는 범위가 넓어졌다. 공식 문서의 예제를 옮긴다.
>>> [1, 2, 3].push(4)
AttributeError: 'list' object has no attribute 'push'. Did you mean '.append'?
>>> 'hello'.toUpperCase()
AttributeError: 'str' object has no attribute 'toUpperCase'. Did you mean '.upper'?
>>> (1, 2, 3).append(4)
AttributeError: 'tuple' object has no attribute 'append'. Did you mean to use a 'list' object?
문서에 따르면 레벤슈타인 거리(철자가 비슷한 정도)로 비슷한 이름을 못 찾을 때 자바스크립트, 자바, 루비, C#에서 흔한 메서드 이름 표를 한 번 더 뒤져서 파이썬 대응물을 알려 준다. 딕셔너리에 put을 부르면 d[k] = v를 쓰라는 힌트가 나온다. 내부 객체에 원하는 속성이 있으면 .inner.area처럼 경로까지 제안하고, delattr()이 실패할 때도 비슷한 이름을 추천한다. 3.14.6에서 같은 push를 불러 보니 힌트 없이 no attribute 'push'만 나왔다.
Tachyon: 돌고 있는 프로그램에 붙어서 병목을 찾는 도구
프로파일러는 프로그램이 시간을 어디에 쓰는지 재는 도구다. 3.15에는 profiling이라는 새 패키지가 생겼고, 그 안에 Tachyon이라는 이름의 샘플링 프로파일러가 들어갔다. 함수 호출마다 기록하는 방식(트레이싱)이 아니라 일정 간격으로 “지금 어디를 실행 중인지” 사진을 찍는 방식이라 부담이 적다.
문서에 있는 사용법은 짧다.
python -m profiling.sampling run script.py # 스크립트를 처음부터 측정
python -m profiling.sampling attach 12345 # 이미 돌고 있는 프로세스(PID 12345)에 붙기
python -m profiling.sampling dump 12345 # 지금 스택을 한 번 찍어서 보기
python -m profiling.sampling run --flamegraph -o profile.html script.py
문서는 “재시작도 코드 수정도 필요 없고 거의 오버헤드가 없다”고 소개하며, 표본은 기본이 초당 1,000번(1 kHz), 최대 초당 1,000,000번이다. 결과는 표, 불꽃 그래프(HTML), 줄 단위 히트맵, 터미널에서 실시간으로 보는 화면(--live) 등으로 낼 수 있다.
문서가 뒤쪽에 적어 둔 조건은 읽어 둘 만하다. 다른 프로세스의 메모리를 읽는 방식이라 높은 권한이 필요하다. 리눅스는 root나 CAP_SYS_PTRACE 권한 또는 ptrace 설정 변경이, 맥은 root 또는 디버거 권한 부여가, 윈도우는 관리자 권한이 필요하다고 적혀 있다. 측정하는 쪽과 측정당하는 쪽의 파이썬 마이너 버전이 같아야 한다. 3.14에서 3.15 프로세스에 붙는 것은 지원하지 않는다. 기존 cProfile은 별칭으로 남고, profile 모듈은 3.17에서 제거될 예정이다.
속도: 공식 숫자와 한 개발자의 직접 측정이 갈린다
속도에 관한 숫자는 출처마다 조건이 달라서 한 표에 나란히 놓고 읽어야 한다.
| 무엇을 | 누가 | 조건 | 결과 |
|---|---|---|---|
| JIT 대 표준 인터프리터 | 공식 What’s New | x86-64 리눅스, pyperformance 기하평균 | 7~8% 빠름 |
| JIT 대 꼬리 호출 인터프리터 | 공식 What’s New | AArch64 맥 | 11~12% 빠름 |
| 윈도우 공식 바이너리의 꼬리 호출 인터프리터 | 공식 What’s New | MSVC 18, 라이젠 7 5800X, 기존 방식 대비 | 15~20% 빠름(14%~40% 범위) |
| 피보나치 40번째 수 계산, 스레드 1개 | 미겔 그린버그(비공식) | 3.15.0rc3, 인텔 i5 리눅스 노트북 | 3.14는 7.17초, 3.15는 6.94초 |
공식 문서의 JIT 수치는 문서 스스로 “실험적”이라고 부르는 기능에 대한 것이다. 같은 문서가 JIT 빌드와 JIT 없는 빌드를 비교하면 약 15% 느려지는 경우부터 100% 넘게 빨라지는 경우까지 범위가 넓다고 적었다.
그린버그는 매년 파이썬 새 버전을 자기 방식으로 재는 개발자다. 이번 글의 결론은 이렇다. 3.15는 많아야 3.14보다 작은 개선이고, 분명히 나아진 곳은 JIT뿐인데 그건 아직 실험 기능이라 운영에 쓰지 않겠다고 했다. 작은 변동 중에는 퇴보한 테스트도 있어서 실제 프로젝트에서 체감할 변화는 기대하지 않는다고 했다. 다만 컴프리헨션 펼치기와 lazy import를 쓰려고 평소 쓰는 인터프리터는 3.15로 바꿀 계획이라고 한다. 프로그램 두 개만 잰 “비공식” 측정이라는 점을 본인이 먼저 밝혔다.
두 쪽을 합치면 이렇게 읽힌다. 새 버전으로 옮긴다고 일반 코드가 눈에 띄게 빨라지지는 않는다. 윈도우 공식 설치 파일을 쓰는 사람은 공식 숫자대로 이득을 볼 수 있다. 이 사이트는 이 중 어느 것도 직접 재 보지 않았다.
업그레이드 전에 깨질 수 있는 것
What’s New 문서의 “3.15로 옮기기” 항목에서 일반 사용자와 라이브러리 작성자에게 닿을 만한 것만 뽑았다.
| 바뀐 곳 | 내용 | 조치 |
|---|---|---|
sqlite3.connect() |
database 외 인자가 전부 키워드 전용 |
위치 인자로 넘기던 곳 수정 |
argparse |
add_argument('-f', '-foo')의 dest가 'f'가 아니라 'foo'로 |
이전 동작이 필요하면 dest를 직접 적기 |
base64.urlsafe_b64decode() |
입력 끝 패딩이 더는 필수가 아님 | 패딩을 강제하려면 padded=True |
unittest |
assertWarns()가 조건에 안 맞는 경고를 더는 삼키지 않음 |
가려져 있던 경고가 테스트에 새어 나올 수 있다 |
| 제거된 모듈 | sre_compile, sre_constants, sre_parse 등 |
대신 re 사용 |
typing |
NamedTuple("Point", x=int, y=int) 형태 키워드 문법 제거 |
클래스 방식으로 |
-b, -bb 옵션 |
3.17에서 아무 일도 안 하게 될 예정(지금은 지원 중단 예고) | 파이썬 2에서 3으로 옮길 때 쓰던 도우미라 대부분 해당 없음 |
맥 사용자에게는 따로 붙은 경고가 있다. 릴리스 페이지에 따르면 macOS 27.0에서 IDLE이나 tkinter를 쓰는 프로그램은 메뉴가 대화 상자를 열 때 멈춰 보이는 문제가 있고, 이는 운영체제 쪽 변경 때문에 현재 모든 Tk 도구 모음에 해당한다고 한다. Tk 기반 프로그램에 의존한다면 해결책이 나올 때까지 macOS 27.0 설치를 미루거나 먼저 시험하라는 안내다.
.pth의 import 줄이 퇴장하고, 프레임 포인터가 기본으로 켜진다
패키지 도구나 C 확장을 만드는 사람에게 닿는 변화가 세 가지 있다. 일반 사용자는 이 절을 건너뛰어도 된다.
첫째, 파이썬은 시작할 때 .pth 파일의 import로 시작하는 줄을 실행해 왔다. 문서는 시작할 때 무엇이 실행되는지 정확히 알기 어렵다는 점을 문제로 든다. 3.15는 pkg.mod:callable 형식으로 시작 시 호출할 대상을 적는 .start 파일을 도입했다. 같은 이름의 .start 파일이 있으면 .pth의 import 줄은 무시되고, import 줄 자체는 조용히 지원 중단 상태가 됐다. 경로를 늘리는 줄은 그대로다. 패키지 저장소가 공격받은 사건은 루비젬스 공격 글에서 다뤘다. 시작할 때 실행되는 코드를 감사하기 쉽게 만들겠다는 방향은 같은 고민의 연장선이다.
둘째, CPython이 지원하는 플랫폼에서는 프레임 포인터를 켠 채 빌드된다(PEP 831). 시스템 프로파일러와 디버거가 스택을 읽기 쉬워진다. 켜고 싶지 않으면 빌드 때 --without-frame-pointers를 준다. 직접 네이티브 코드를 빌드하는 쪽은 같은 플래그를 유지해야 하고, 하나라도 빠지면 프로세스 전체의 스택 해석이 끊길 수 있다고 문서가 경고한다.
셋째, free-threaded(GIL 없는) 빌드를 위한 안정 ABI abi3t가 생겼다(PEP 803). 파이썬 버전이 바뀌어도 C 확장을 다시 빌드하지 않아도 되게 하는 안정 ABI의 약속을 free-threaded 빌드까지 넓힌 장치다. 이 ABI가 쓰일 수 있도록 생태계 쪽 준비를 해 왔다는 Hacker News 댓글 작성자(ngoldbaum)에 따르면 cryptography 프로젝트가 이미 플랫폼마다 abi3.abi3t 휠 하나씩만 배포한다고 한다. 댓글 내용이라 공식 확인은 거치지 않았다.
3.10 지원 종료와 이사 일정
3.15가 나오면 가장 오래된 지원 버전이 빠진다. 파이썬 개발진은 10월 1일 공지에서 3.10.22를 마지막 3.10 릴리스로 내고 5년 만에 지원을 끝냈다. 이 버전은 더는 보안 업데이트를 받지 않는다. 같은 공지에 적힌 일정은 이렇다.
| 버전 | 상태 |
|---|---|
| 3.10 | 지원 종료(3.10.22가 마지막) |
| 3.11 | 보안 수정만, 2027년 10월까지 |
| 3.12 | 보안 수정, 2028년 10월까지 |
| 3.13 | 3.13.16이 마지막 정규 유지보수 릴리스, 이후는 보안 수정만 |
| 3.14 | 정규 유지보수 중(3.14.8) |
Hacker News 댓글에서 여러 오픈소스 파이썬 라이브러리를 관리한다는 사용자 simonw는, 새 파이썬 릴리스의 가장 좋은 점은 오래된 버전의 지원이 끝난다는 것이라고 적었다. 3.10이 빠지니 이제 3.11의 기능을 라이브러리에 써도 된다는 뜻이다. 우리가 쓰는 파이썬이 3.10 이하라면 보안 패치를 받을 길이 없다. 런타임의 지원 종료 일정이 곧 사용자 일정이 되는 경험은 어제 Deno 합류 글에서도 다뤘다.
Hacker News에서는 환영이 먼저였다
릴리스 페이지가 Hacker News에 올라, 확인한 시점에 282점, 댓글 77개를 받았다. 눈에 띈 반응을 옮긴다.
- lazy import를 두고 “드디어”라는 댓글이 두 개 달렸다.
- PEP 686을 환영하는 댓글도 있었다. 반대로 한 댓글 작성자는
.pth의 import 줄에 코덱 “매크로”를 설치하는 방식을 쓰고 있었는데, PEP 829가 합쳐졌다는 걸 보고 아쉬움을 적었다. - 한 댓글은 압축한 소스 아카이브가 3.14보다 절반쯤 커졌다고 지적했고, 원인을 문서 폴더에 들어간 Tachyon 시연용 애니메이션 GIF 두 개(합계 10MB 이상)에서 찾았다. 댓글 작성자의 추정이다.
- 릴리스 페이지에는 배리 워소(Barry Warsaw)가 3.15 새 기능을 퍼즐로 풀며 도는 터미널 텍스트 어드벤처
whatsnewt를 만들었다고 적혀 있다. 이 사이트는 실행해 보지 않았고, 페이지에 적힌 실행 명령은uvx --python 3.15 whatsnewt다.
공식 문서에 적혀 있지 않은 것, 이 사이트가 확인하지 못한 것
- 3.15.0을 설치해 돌려 본 적이 없다. 3.15 새 문법과 에러 메시지는 문서 예제 그대로이고, 3.14.6에서는
SyntaxError와NameError, 힌트 없는 에러가 나는 것까지만 확인했다. - 한국어 윈도우에서
open()이 실제로 CP949로 열리다 UTF-8로 바뀌는 과정을 윈도우 PC에서 재현해 보지 않았다. CP949가 보통의 기본값이라는 점은 윈도우의 일반적인 동작에 대한 설명이다. - lazy import의 50
70%, 3040%는 PEP 작성자들이 적은 값이다. 우리 코드에서 얼마나 줄지는 모른다. - Tachyon의 “거의 오버헤드 없음”은 문서의 설명이다. 운영 서버에 붙이기 전에 권한과 버전 조건부터 확인해야 한다.
- 파이썬을 더 빠르게 만드는 다른 길로 가는 모조 컴파일러와 3.15의 속도 향상은 비교해 보지 않았다.
- 서드파티 라이브러리가 3.15를 지원하는지는 라이브러리마다 다르다. 이 글은 확인하지 않았다.
오늘 저녁 30분이면 끝나는 점검 순서
- 지금 쓰는 파이썬에서 인코딩 경고를 켜고 내 프로그램을 돌린다.
python -X warn_default_encoding 내스크립트.py또는PYTHONWARNDEFAULTENCODING=1. 경고가 나온 줄이 3.15에서 영향받는 줄이다. - 윈도우에서 쓰는 텍스트 파일이 있다면 UTF-8인지 먼저 확인한다. 옛 메모장이나 엑셀 CSV로 저장한 파일이 CP949일 수 있다.
- 경고가 나온 줄에
encoding=을 적는다. UTF-8 파일이면"utf-8", 옛 파일이면"cp949", 판단이 안 서면"locale". isinstance(x, dict)로 딕셔너리를 검사하는 곳을 검색한다.frozendict를 받아야 하는 코드라면collections.abc.Mapping으로 바꾼다.- 시작이 느린 명령줄 도구가 있다면
-X lazy_imports=all로 한 번 돌려 본다. 레지스트리 패턴이 깨지지 않는지 결과를 비교한다. 규모가 크면 Lifeguard(베타)를 먼저 돌려 본다. - 3.10 이하를 쓰고 있다면 이사 일정부터 잡는다. 3.11 이상을 고르면 된다. 맥에서 tkinter를 쓰는 앱이 있다면 macOS 27.0 업데이트를 미룰지 따져 본다.
속도를 기대하고 서둘러 옮길 이유는 아직 적다. 반대로 언제 옮기든 open() 점검은 지금 해 둘수록 싸다.