본문 바로가기
카테고리 없음

Python 3.14 달라진 점

by redcubes 2026. 1. 7.

1. 소개

Python 3.14가 2025년 10월 7일에 공식 출시되었습니다. 이번 버전은 언어, 구현, 표준 라이브러리에 걸쳐 다양한 변화를 가져왔으며, 특히 성능 향상과 개발자 경험 개선에 중점을 두었습니다.

주요 변경사항 요약:

  • 템플릿 문자열 리터럴 (t-strings) 도입
  • 어노테이션의 지연 평가
  • 표준 라이브러리에서 서브인터프리터 지원
  • Zstandard 압축 형식 지원
  • Free-threaded Python 공식 지원
  • REPL 문법 하이라이팅
  • JIT 컴파일러 (실험적)
  • 성능 개선 (3-5% 향상)

참고: 이 글은 Python 3.14 공식 문서를 기반으로 작성되었습니다. 최신 버전은 Python 3.14.2 (2025년 12월 5일)입니다.


2. 지연 평가 어노테이션 (PEP 649/749)

2.1 개념

Python 3.14부터 함수, 클래스, 모듈의 어노테이션(함수/변수/클래스 등에 붙이는 “추가 정보(메타데이터)” . 보통 타입 힌트로 씀.)이 더 이상 즉시 평가되지 않습니다. 대신, 어노테이션은 특수한 목적의 "annotate 함수"에 저장되며, 필요할 때만 평가됩니다.

2.2 이전 방식의 문제점

# Python 3.13 이하에서는 오류 발생
def func(arg: UndefinedType):  # NameError: name 'UndefinedType' is not defined
    pass

2.3 새로운 방식

from annotationlib import get_annotations, Format

def func(arg: Undefined):
    pass

# VALUE 형식: 런타임 값으로 평가 (이전 방식과 유사)
try:
    get_annotations(func, format=Format.VALUE)
except NameError:
    print("Undefined는 정의되지 않음")

# FORWARDREF 형식: 정의되지 않은 이름을 마커로 대체
result = get_annotations(func, format=Format.FORWARDREF)
print(result)  # {'arg': ForwardRef('Undefined', owner=...)}

# STRING 형식: 어노테이션을 문자열로 반환
result = get_annotations(func, format=Format.STRING)
print(result)  # {'arg': 'Undefined'}

2.4 장점

  • 성능 향상: 어노테이션 정의 시 런타임 비용 최소화
  • 순환 참조 해결: 문자열 인용 없이도 순방향 참조 가능
  • 유연한 검사: 필요한 형식으로만 어노테이션 평가

2.5 마이그레이션 가이드

대부분의 코드는 수정 없이 동작하지만, 다음 경우 주의가 필요합니다:

  • __annotations__를 직접 읽는 코드
  • 어노테이션이 즉시 평가되어야 하는 경우
  • from __future__ import annotations를 사용하는 경우

권장사항: annotationlib.get_annotations() 함수를 사용하여 어노테이션을 안전하게 검색하세요.


3. 템플릿 문자열 리터럴 (PEP 750)

3.1 개념

템플릿 문자열(t-strings)은 커스텀 문자열 처리를 위한 새로운 메커니즘입니다. f-string의 친숙한 문법을 공유하지만, 단순한 str 대신 정적 부분과 보간 부분을 나타내는 객체를 반환합니다.

3.2 기본 사용법

variety = 'Stilton'
template = t'Try some {variety} cheese!'

print(type(template))  # <class 'string.templatelib.Template'>

# 템플릿의 각 부분에 접근
for part in template:
    print(part)

# 출력:
# Try some 
# Interpolation('Stilton', 'variety', None, '')
#  cheese!

Interpolation('Stilton', 'variety', None, '')는 보간 조각 1개를 사람이 보기 좋게 출력한 표현이고, 의미는 다음과 같습니다.

  • 'Stilton': {variety}가 평가된 값(value)
  • 'variety': 보간에 사용된 표현식/이름(text) (여기서는 변수 이름)
  • None: 보간에 붙은 변환(conversion) 정보 (!r, !s, !a 같은 것). 없으면 None
    !r, !s, !a는 **f-string(그리고 str.format)에서 “값을 문자열로 만들기 전에 어떤 변환을 먼저 적용할지”**를 지정하는 conversion 플래그입니다.
    • !s : str(x)로 변환
    • !r : repr(x)로 변환
    • !a : ascii(x)로 변환 (비-ASCII 문자를 \uXXXX 같은 이스케이프로 바꾼 표현)
    변환은 포맷팅(format spec, :...)보다 먼저 적용됩니다. 아무것도 안 쓰면 기본은 str(x) 입니다.
    그래서 !s는 보통 “명시용”이고 실제로는 생략해도 같습니다.
  • '': 보간에 붙은 포맷 지정(format spec) (:>10, :.2f 같은 것). 없으면 빈 문자열

즉, {variety} 하나가 “값은 Stilton이고, 원래 표현식은 variety였고, 변환/포맷은 없다”라는 메타정보로 분해되어 나온 것입니다.

예를 들어:

  • t'{variety!r}'면 conversion이 'r' 쪽으로 채워지고
  • t'{price:.2f}'면 마지막 format spec이 '.2f'로 채워집니다.

3.3 커스텀 처리 예제

from string.templatelib import Interpolation

def lower_upper(template):
    """정적 부분은 소문자로, 보간은 대문자로 렌더링"""
    parts = []
    for part in template:
        if isinstance(part, Interpolation):
            parts.append(str(part.value).upper())
        else:
            parts.append(part.lower())
    return ''.join(parts)

name = 'Wenslydale'
template = t'Mister {name}'
result = lower_upper(template)
print(result)  # 'mister WENSLYDALE'

3.4 실용적 활용 사례

1. HTML 이스케이프:

from string.templatelib import Template, Interpolation
import html as html_module

def html(template: Template) -> str:
    """사용자 입력을 안전하게 이스케이프"""
    parts = []
    for item in template:
        if isinstance(item, Interpolation):
            # 보간된 값은 HTML 이스케이프
            parts.append(html_module.escape(str(item.value)))
        else:
            # 정적 문자열은 그대로 사용
            parts.append(item)
    return ''.join(parts)

user_input = "<script>alert('xss')</script>"
safe_html = html(t'<div>{user_input}</div>')
print(safe_html)
# 출력: <div>&lt;script&gt;alert('xss')&lt;/script&gt;</div>

2. SQL 쿼리 안전화:

def safe_sql(template):
    """SQL 인젝션 방지"""
    # 파라미터화된 쿼리 생성
    pass

username = "admin' OR '1'='1"
query = safe_sql(t'SELECT * FROM users WHERE name = {username}')

3. 고급 HTML 속성 처리:

attributes = {'src': 'limburger.jpg', 'alt': 'lovely cheese'}
template = t'<img {attributes}>'
# html() 함수가 dict를 적절한 속성으로 변환
# 결과: <img src="limburger.jpg" alt="lovely cheese" />

3.5 장점

  • 보안: 사용자 입력 자동 이스케이프
  • 유연성: 커스텀 문자열 처리 로직 구현 가능
  • 친숙함: f-string과 동일한 문법
  • 확장성: 경량 DSL 구현 가능

4. 표준 라이브러리의 다중 인터프리터 (PEP 734)

4.1 개념

CPython 런타임은 20년 이상 동일한 프로세스 내에서 여러 Python 복사본을 동시에 실행할 수 있었지만, 이 기능은 C-API를 통해서만 사용 가능했습니다. Python 3.14에서는 새로운 concurrent.interpreters 모듈을 통해 이 제한이 제거되었습니다.

4.2 주요 장점

1. 새로운 동시성 모델:

  • CSP (Communicating Sequential Processes)
  • Actor 모델
  • 격리된 인터프리터를 사용한 옵트인 공유

2. 진정한 멀티코어 병렬성:

  • 각 인터프리터는 자체 GIL을 가짐
  • CPU 집약적 작업에 적합
  • 프로세스의 격리성 + 스레드의 효율성

4.3 기본 사용 예제

import concurrent.interpreters as interpreters

# 새 인터프리터 생성
interp = interpreters.create()

# 코드 실행
code = """
import sys
print(f"Hello from interpreter {sys.hexversion}")
"""

interpreters.run_string(interp, code)

# 인터프리터 종료
interpreters.destroy(interp)

4.4 multiprocessing과 비교

특성 multiprocessing multiple interpreters
격리성 높음 (별도 프로세스) 높음 (격리된 인터프리터)
메모리 사용 높음 낮음 (동일 프로세스)
시작 시간 느림 빠름
공유 기본값 없음 없음 (선택적)
GIL 프로세스당 1개 인터프리터당 1개

4.5 현재 제약사항

  • 인터프리터 시작이 아직 최적화되지 않음
  • 각 인터프리터가 필요 이상의 메모리 사용
  • 인터프리터 간 객체 공유 옵션이 제한적
  • 많은 서드파티 확장 모듈이 아직 호환되지 않음

참고: 표준 라이브러리의 모든 확장 모듈은 호환됩니다.

4.6 InterpreterPoolExecutor

from concurrent.futures import InterpreterPoolExecutor

def compute_heavy_task(n):
    """CPU 집약적 작업"""
    return sum(i * i for i in range(n))

with InterpreterPoolExecutor(max_workers=4) as executor:
    results = executor.map(compute_heavy_task, [10**6, 10**7, 10**8])
    for result in results:
        print(result)

5. Zstandard 압축 지원 (PEP 784)

5.1 개념

Python 3.14는 Meta의 Zstandard 압축 형식에 대한 공식 지원을 추가했습니다. Zstandard는 높은 효율성과 빠른 속도를 자랑하는 현대적인 압축 알고리즘입니다.

5.2 새로운 compression 패키지

기존 압축 모듈들이 compression 패키지로 재구성되었습니다:

  • compression.lzma (기존 lzma)
  • compression.bz2 (기존 bz2)
  • compression.gzip (기존 gzip)
  • compression.zlib (기존 zlib)
  • compression.zstd (새로운 모듈)

참고: 기존 모듈 이름은 deprecated되지 않았으며, 최소 5년 이상 유지됩니다.

5.3 기본 사용법

from compression import zstd
import math

# 데이터 압축
data = str(math.pi).encode() * 20
compressed = zstd.compress(data)

# 압축률 계산
ratio = len(compressed) / len(data)
print(f"압축률: {ratio:.2%}")

# 압축 해제
decompressed = zstd.decompress(compressed)
assert data == decompressed

5.4 레벨별 압축

# 빠른 압축 (레벨 1)
fast_compressed = zstd.compress(data, level=1)

# 높은 압축률 (레벨 19)
best_compressed = zstd.compress(data, level=19)

# 기본 압축 (레벨 3)
default_compressed = zstd.compress(data)

print(f"빠른 압축: {len(fast_compressed)} bytes")
print(f"최고 압축: {len(best_compressed)} bytes")
print(f"기본 압축: {len(default_compressed)} bytes")

5.5 파일 압축 예제

import zstd
import tarfile
import zipfile

# tarfile에서 Zstandard 지원
with tarfile.open('archive.tar.zst', 'w:zst') as tar:
    tar.add('myfile.txt')

# zipfile에서 Zstandard 지원
with zipfile.ZipFile('archive.zip', 'w', compression=zipfile.ZIP_ZSTANDARD) as zf:
    zf.write('myfile.txt')

5.6 성능 특징

알고리즘 압축 속도 압축률 압축 해제 속도
gzip 보통 양호 빠름
bz2 느림 우수 느림
lzma 매우 느림 최고 빠름
zstd 빠름 우수 매우 빠름

6. Free-threaded 모드 개선

6.1 개념

Python 3.13에서 실험적으로 도입된 Free-threaded 빌드(GIL 없음)가 Python 3.14에서 공식 지원되었습니다. 이는 진정한 멀티스레드 병렬성을 가능하게 합니다.

6.2 주요 개선사항

  • 성능 향상: 단일 스레드 코드의 성능 저하가 5-10%로 감소
  • PEP 659 지원: 특수화 적응형 인터프리터 활성화
  • C API 완성: PEP 703의 모든 C API 변경 완료
  • 안정성: 임시 해결책을 영구적 솔루션으로 교체

6.3 사용 방법

컴파일 시:

./configure --disable-gil
make

uv 사용 (권장):

# 't' 접미사로 free-threaded 빌드 사용
uvx [email protected]

# 출력: Python 3.14.0 free-threading build

6.4 멀티스레딩 예제

import threading
import time

def cpu_intensive_task(n):
    """CPU 집약적 작업"""
    result = 0
    for i in range(n):
        result += i ** 2
    return result

# GIL이 있는 경우: 순차 실행
# Free-threaded: 진정한 병렬 실행
start = time.time()
threads = []
for i in range(4):
    t = threading.Thread(target=cpu_intensive_task, args=(10**7,))
    threads.append(t)
    t.start()

for t in threads:
    t.join()

elapsed = time.time() - start
print(f"실행 시간: {elapsed:.2f}초")

6.5 Context-aware Warnings

# Free-threaded 빌드에서 기본 활성화
python -X context_aware_warnings=1

# 스레드가 호출자의 Context를 상속
python -X thread_inherit_context=1

6.6 주의사항

  • 여전히 옵트인 방식 (기본적으로 GIL 활성화)
  • C 확장 모듈은 free-threaded 지원이 필요
  • 단일 스레드 성능이 약간 저하될 수 있음

7. 안전한 외부 디버거 인터페이스 (PEP 768)

7.1 개념

Python 3.14는 디버거와 프로파일러가 실행 중인 Python 프로세스에 안전하게 연결할 수 있는 제로 오버헤드 인터페이스를 도입했습니다. 프로세스를 중지하거나 재시작할 필요가 없습니다.

7.2 주요 특징

  • 제로 오버헤드: 일반 실행 경로에 영향 없음
  • 안전성: 안전한 실행 지점에서만 코드 실행
  • 실시간 검사: 운영 환경에서도 사용 가능

7.3 기본 사용법

import sys
import os
from tempfile import NamedTemporaryFile

# 디버거 스크립트 작성
with NamedTemporaryFile(mode='w', suffix='.py', delete=False) as f:
    script_path = f.name
    f.write(f'import my_debugger; my_debugger.connect({os.getpid()})')

# PID 1234인 프로세스에서 실행
print('디버거 연결 중...')
sys.remote_exec(1234, script_path)

7.4 pdb 원격 연결

# 실행 중인 프로세스에 pdb 연결
python -m pdb -p 1234

# 프로세스 1234의 디버깅 세션 시작
# 브레이크포인트 설정, 변수 검사 등 가능

7.5 보안 제어

3가지 방법으로 원격 디버깅을 제어할 수 있습니다:

# 1. 환경 변수
export PYTHON_DISABLE_REMOTE_DEBUG=1

# 2. 명령줄 옵션
python -X disable-remote-debug script.py

# 3. 빌드 시 완전히 비활성화
./configure --without-remote-debug

7.6 활용 사례

  • 프로덕션 디버깅: 운영 서버의 문제 실시간 진단
  • 성능 프로파일링: 실행 중인 애플리케이션 분석
  • 상태 검사: 장시간 실행 프로세스의 내부 상태 확인

8. 새로운 인터프리터 타입

8.1 개념

Python 3.14에 추가된 새로운 인터프리터는 tail call 기반 구현을 사용하여 성능을 크게 향상시킵니다. 개별 Python opcode를 구현하는 작은 C 함수들 간의 tail call을 사용합니다.

8.2 성능 특징

  • 벤치마크: pyperformance 벤치마크 스위트에서 3-5% 빠름
  • 기준: Clang 19로 빌드된 Python 3.14 (새 인터프리터 없음)
  • 컴파일러: Clang 19 이상 필요
  • 아키텍처: x86-64, AArch64 지원

8.3 활성화 방법

현재는 옵트인 방식입니다. Profile-guided optimization(PGO)과 함께 사용하는 것이 권장됩니다:

# 빌드 시 활성화
./configure --with-tail-call-interp
make

# PGO와 함께 사용 (권장)
./configure --with-tail-call-interp --enable-optimizations
make profile-opt

8.4 주의사항

  • 이것은 Python 함수의 tail call optimization이 아닙니다
  • 내부 구현 세부사항으로, 프로그램 동작에 영향 없음
  • 성능만 향상시킬 뿐 다른 변화 없음

8.5 성능 비교

import time

def fibonacci(n):
    if n <= 1:
        return n
    return fibonacci(n-1) + fibonacci(n-2)

start = time.time()
result = fibonacci(35)
elapsed = time.time() - start

print(f"결과: {result}")
print(f"실행 시간: {elapsed:.2f}초")

# 새 인터프리터: 약 3-5% 빠름

9. Asyncio 개선사항

9.1 작업 그래프 검사

실행 중인 asyncio 프로그램의 호출 그래프를 검사할 수 있는 새로운 CLI가 추가되었습니다:

# 작업 목록 보기
python -m asyncio ps <PID>

# 작업 트리 보기
python -m asyncio pstree <PID>

9.2 실제 예제

import asyncio

async def play_track(track):
    await asyncio.sleep(5)
    print(f'🎵 완료: {track}')

async def play_album(name, tracks):
    async with asyncio.TaskGroup() as tg:
        for track in tracks:
            tg.create_task(play_track(track), name=track)

async def main():
    async with asyncio.TaskGroup() as tg:
        tg.create_task(
            play_album('Sundowning', ['TNDNBTG', 'Levitate']),
            name='Sundowning')
        tg.create_task(
            play_album('TMBTE', ['DYWTYLM', 'Aqua Regia']),
            name='TMBTE')

if __name__ == '__main__':
    asyncio.run(main())

9.3 ps 명령 출력

tid        task id              task name            coroutine stack                                    awaiter chain
--------------------------------------------------------------------------------------------------------------------
1935500    0x7fc930c18050       Task-1               TaskGroup._aexit -> TaskGroup.__aexit__ -> main
1935500    0x7fc930c18230       Sundowning           TaskGroup._aexit -> TaskGroup.__aexit__ -> album
1935500    0x7fc93173fa50       TMBTE                TaskGroup._aexit -> TaskGroup.__aexit__ -> album
1935500    0x7fc93173fdf0       TNDNBTG              sleep -> play
1935500    0x7fc930d32510       Levitate             sleep -> play
1935500    0x7fc930d32890       DYWTYLM              sleep -> play
1935500    0x7fc93161ec30       Aqua Regia           sleep -> play

9.4 pstree 명령 출력

└── (T) Task-1
    └──  main example.py:13
        └──  TaskGroup.__aexit__
            └──  TaskGroup._aexit
                ├── (T) Sundowning
                │   └──  album example.py:8
                │       └──  TaskGroup.__aexit__
                │           └──  TaskGroup._aexit
                │               ├── (T) TNDNBTG
                │               │   └──  play example.py:4
                │               │       └──  sleep
                │               └── (T) Levitate
                │                   └──  play example.py:4
                │                       └──  sleep
                └── (T) TMBTE
                    └──  album example.py:8
                        └──  TaskGroup.__aexit__
                            └──  TaskGroup._aexit
                                ├── (T) DYWTYLM
                                │   └──  play example.py:4
                                │       └──  sleep
                                └── (T) Aqua Regia
                                    └──  play example.py:4
                                        └──  sleep

9.5 순환 감지

await 그래프에서 순환이 감지되면 오류를 발생시킵니다:

ERROR: await-graph contains cycles - cannot print a tree!

cycle: Task-2 → Task-3 → Task-2

9.6 create_task 개선

# 이제 임의의 키워드 인자 전달 가능
async def main():
    # 커스텀 팩토리로 전달
    task = asyncio.create_task(
        my_coroutine(),
        name="my-task",
        custom_param="value"
    )

10. REPL 개선사항

10.1 문법 하이라이팅

기본 인터랙티브 셸이 이제 Python 문법을 자동으로 하이라이트합니다:

>>> def fibonacci(n):
...     if n <= 1:
...         return n
...     return fibonacci(n-1) + fibonacci(n-2)

# 키워드는 파란색, 문자열은 초록색 등으로 표시

10.2 색상 제어

# 하이라이팅 비활성화
export PYTHON_BASIC_REPL=1

# 또는 NO_COLOR 환경 변수 사용
export NO_COLOR=1

10.3 커스텀 테마

# .pythonstartup 파일 또는 인터랙티브 세션에서
from _colorize import set_theme

# 커스텀 테마 설정 (실험적 API)
set_theme({
    'keyword': '\033[94m',  # 파란색
    'string': '\033[92m',   # 초록색
    'comment': '\033[90m',  # 회색
})

주의: _colorize.set_theme()는 실험적 API이며 안정성 보장이 없습니다.

10.4 Import 자동완성

REPL에서 import 문의 모듈 이름을 Tab으로 자동완성할 수 있습니다:

>>> import co<Tab>
collections  concurrent   configparser contextlib   copy

>>> from concurrent import i<Tab>
import  in

10.5 특별한 별칭

Python 3.14만의 특별한 기능:

(venv) $ 𝜋thon
Python 3.14.0 (main, Oct 7 2025, 17:32:06)
>>>

# π (파이) 기호로 Python 실행 가능! (3.14 버전만)

11. 에러 메시지 개선

11.1 키워드 오타 제안

>>> whille True:
...     pass
  File "<stdin>", line 1
    whille True:
    ^^^^^^
SyntaxError: invalid syntax. Did you mean 'while'?

>>> improt math
  File "<stdin>", line 1
    improt math
    ^^^^^^
SyntaxError: invalid syntax. Did you mean 'import'?

11.2 elif 블록 오류

>>> if who == "me":
...     print("It's me!")
... else:
...     print("It's not me!")
... elif who is None:
...     print("Who is it?")
  File "<stdin>", line 5
    elif who is None:
    ^^^^
SyntaxError: 'elif' block follows an 'else' block

11.3 조건 표현식 오류

>>> x = 1 if True else pass
  File "<string>", line 1
    x = 1 if True else pass
                       ^^^^
SyntaxError: expected expression after 'else', but statement is given

>>> x = continue if True else break
  File "<string>", line 1
    x = continue if True else break
        ^^^^^^^^
SyntaxError: expected expression before 'if', but statement is given

11.4 문자열 오류

>>> "The interesting object "The important object" is very important"
  File "<stdin>", line 1
SyntaxError: invalid syntax. Is this intended to be part of the string?

>>> ub'abc'
  File "<stdin>", line 1
    ub'abc'
    ^^
SyntaxError: 'u' and 'b' prefixes are incompatible

11.5 Unhashable 타입 오류

>>> s = set()
>>> s.add({'pages': 12, 'grade': 'A'})
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: cannot use 'dict' as a set element (unhashable type: 'dict')

>>> d = {}
>>> l = [1, 2, 3]
>>> d[l] = 12
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: cannot use 'list' as a dict key (unhashable type: 'list')

11.6 컨텍스트 관리자 오류

class SyncContext:
    def __enter__(self): return self
    def __exit__(self, *args): pass

async def main():
    # 동기 컨텍스트를 async with로 사용
    async with SyncContext():
        pass

# 오류: SyncContext는 동기 컨텍스트 관리자입니다.
# 'with' 대신 'async with'를 사용하세요.

12. 구문 변경사항

12.1 괄호 없는 except (PEP 758)

여러 예외 타입을 지정할 때 as 절이 없으면 괄호를 생략할 수 있습니다:

# Python 3.13 이하
try:
    connect_to_server()
except (TimeoutError, ConnectionRefusedError):
    print('네트워크 연결 실패!')

# Python 3.14
try:
    connect_to_server()
except TimeoutError, ConnectionRefusedError:
    print('네트워크 연결 실패!')

# except* 구문도 동일
try:
    await multiple_operations()
except* ValueError, TypeError:
    print('여러 오류 발생')

12.2 finally 블록의 제어 흐름 (PEP 765)

finally 블록을 빠져나가는 return, break, continue 문에 대해 SyntaxWarning을 발생시킵니다:

def problematic_function():
    try:
        risky_operation()
    finally:
        return "cleanup done"  # SyntaxWarning!

# 경고: 'return'이 'finally' 블록을 빠져나갑니다.
# 이는 예외를 억제할 수 있습니다.

경고 제어:

# 문법 경고 무시
python -Wignore::SyntaxWarning script.py

# 또는 환경 변수
export PYTHONWARNINGS=ignore::SyntaxWarning

# 다른 경고는 에러로, 문법 경고만 무시
python -Werror -Wignore::SyntaxWarning script.py

12.3 증분 가비지 컬렉션

순환 가비지 컬렉터가 이제 증분입니다. 이는 더 큰 힙에서 최대 정지 시간을 크게 줄입니다:

  • 이제 두 세대만 존재: young과 old
  • GC 호출 빈도가 약간 감소
  • 호출 시 young 세대와 old 세대의 일부만 수집
import gc

# gc.collect() 동작 변경
gc.collect(1)  # 이제 GC의 증분 수행

# 다른 호출은 변경 없음
gc.collect()   # 전체 수집
gc.collect(0)  # generation 0 수집

13. 표준 라이브러리 개선

13.1 pathlib 개선

파일/디렉토리 복사 및 이동:

from pathlib import Path

source = Path('source_dir')
dest = Path('dest_dir')

# 복사
source.copy(dest)           # 목적지로 복사
source.copy_into(dest)      # 목적지 안으로 복사

# 이동
source.move(dest)           # 목적지로 이동
source.move_into(dest)      # 목적지 안으로 이동

파일 정보 캐싱:

path = Path('myfile.txt')

# info 속성으로 파일 타입 쿼리
if path.info.is_file():
    print("일반 파일")
elif path.info.is_dir():
    print("디렉토리")

# iterdir()가 파일 타입 정보와 함께 경로 생성
for item in Path('.').iterdir():
    # stat() 호출 없이 파일 타입 확인
    if item.info.is_file():
        print(f"파일: {item}")

13.2 heapq 개선

Max-heap 지원:

import heapq

# Max-heap 생성
data = [3, 1, 4, 1, 5, 9, 2, 6]
heapq.heapify_max(data)
print(data)  # [9, 6, 4, 3, 5, 1, 2, 1]

# Max-heap 연산
heapq.heappush_max(data, 7)        # 푸시
max_val = heapq.heappop_max(data)   # 팝
print(max_val)  # 9

# 교체 연산
heapq.heapreplace_max(data, 8)     # 팝 후 푸시
heapq.heappushpop_max(data, 10)    # 푸시 후 팝

13.3 operator 개선

import operator

# None 검사 함수
is_none = operator.is_none
is_not_none = operator.is_not_none

values = [1, None, 2, None, 3]
filtered = list(filter(is_not_none, values))
print(filtered)  # [1, 2, 3]

# functools.partial과 함께 사용
from functools import partial

# None이 아닌 값만 필터링
filter_none = partial(filter, is_not_none)
result = list(filter_none([1, None, 2]))

13.4 uuid 개선

import uuid

# UUID 버전 6-8 지원
uuid6 = uuid.uuid6()
uuid7 = uuid.uuid7()
uuid8 = uuid.uuid8()

print(uuid6)  # 시간 기반 UUID (순서 보장)
print(uuid7)  # 시간 기반 UUID (Unix epoch)
print(uuid8)  # 커스텀 UUID

# 기존 버전 3-5 생성 속도가 최대 40% 향상
uuid3 = uuid.uuid3(uuid.NAMESPACE_DNS, 'example.com')
uuid4 = uuid.uuid4()
uuid5 = uuid.uuid5(uuid.NAMESPACE_DNS, 'example.com')

13.5 functools.Placeholder

from functools import partial, Placeholder as _

def greet(greeting, name, punctuation):
    return f"{greeting}, {name}{punctuation}"

# 중간 인자를 Placeholder로 예약
greet_with_name = partial(greet, "Hello", _, "!")

# 나중에 이름만 제공
print(greet_with_name("World"))  # "Hello, World!"
print(greet_with_name("Alice"))  # "Hello, Alice!"

# 여러 Placeholder 사용
format_number = partial(int, _, base=_)
parse_hex = format_number(base=16)
print(parse_hex("FF"))  # 255

13.6 map() strict 모드

# 길이가 다른 이터러블 검사
numbers = [1, 2, 3]
letters = ['a', 'b']

# strict=True: 길이가 다르면 ValueError 발생
try:
    result = list(map(lambda x, y: (x, y), numbers, letters, strict=True))
except ValueError as e:
    print(f"오류: {e}")

# strict=False (기본): 짧은 이터러블에서 종료
result = list(map(lambda x, y: (x, y), numbers, letters))
print(result)  # [(1, 'a'), (2, 'b')]

13.7 concurrent.futures 개선

from concurrent.futures import ProcessPoolExecutor

with ProcessPoolExecutor() as executor:
    # 작업자 프로세스 종료
    executor.terminate_workers()  # SIGTERM 전송
    
    # 또는 강제 종료
    executor.kill_workers()       # SIGKILL 전송

# Executor.map에 buffersize 추가
executor = ProcessPoolExecutor()
results = executor.map(
    heavy_task,
    range(1000),
    buffersize=10  # 최대 10개 작업만 버퍼에 유지
)

# 버퍼가 가득 차면 이터레이션이 일시 중지됨

13.8 json 명령줄 인터페이스

# 새로운 방식 (권장)
python -m json input.json

# 이전 방식 (소프트 deprecated)
python -m json.tool input.json

# 색상 출력 (기본 활성화)
python -m json input.json

# 색상 비활성화
NO_COLOR=1 python -m json input.json

13.9 http.server HTTPS 지원

# HTTPS 서버 실행
python -m http.server 8000 \
    --tls-cert cert.pem \
    --tls-key key.pem \
    --tls-password-file password.txt

# Python 코드에서
from http.server import HTTPSServer, SimpleHTTPRequestHandler
import ssl

context = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER)
context.load_cert_chain('cert.pem', 'key.pem')

server = HTTPSServer(('localhost', 8000), SimpleHTTPRequestHandler)
server.socket = context.wrap_socket(server.socket, server_side=True)
server.serve_forever()

14. 성능 최적화

14.1 전체 성능 향상

  • 인터프리터: 3-5% 향상 (tail call 기반)
  • Free-threading: 단일 스레드 오버헤드 5-10%로 감소
  • JIT: 실험적 지원 (가변적 성능)

14.2 개별 모듈 최적화

모듈 최적화 내용 성능 향상
uuid 버전 3-5 생성 알고리즘 최대 40%
base64 인코딩/디코딩 루프 15-20%
pathlib stat() 캐싱 파일 작업 2배
asyncio 작업 생성 및 스케줄링 10-15%

14.3 벤치마크 예제

import time
import uuid

# UUID 생성 벤치마크
start = time.time()
for _ in range(100000):
    uuid.uuid4()
elapsed = time.time() - start
print(f"UUID 생성 시간: {elapsed:.2f}초")

# Python 3.13: ~0.45초
# Python 3.14: ~0.42초 (약 7% 향상)

14.4 JIT 컴파일러 (실험적)

# 환경 변수로 활성화
export PYTHON_JIT=1
python script.py

# 또는 명령줄 플래그
python -X jit=1 script.py

주의사항:

  • Windows와 macOS 바이너리에만 포함
  • 기본적으로 비활성화
  • 성능이 향상될 수도, 저하될 수도 있음 (워크로드 의존적)
  • 실험적 기능이므로 프로덕션에서 주의 필요

14.5 성능 측정 도구

# 모듈 import 시간 추적
python -X importtime=2 script.py

# 출력:
# import time: 1234 | 5678 | module_name
# import time: cached | cached | already_loaded

# 프로파일링
python -m cProfile -s cumulative script.py

# 메모리 프로파일링
python -m tracemalloc script.py

15. 결론

15.1 주요 하이라이트 요약

Python 3.14는 다음과 같은 중요한 개선사항을 제공합니다:

  1. 언어 기능: 템플릿 문자열(t-strings), 지연 어노테이션
  2. 동시성: 다중 인터프리터, Free-threaded 공식 지원
  3. 압축: Zstandard 지원
  4. 개발자 경험: REPL 하이라이팅, 개선된 에러 메시지
  5. 성능: 3-5% 전반적 향상, 특정 작업에서 더 큰 개선
  6. 디버깅: 안전한 외부 디버거, asyncio 검사 도구

15.2 업그레이드 고려사항

즉시 업그레이드를 권장하는 경우:

  • 새로운 프로젝트 시작
  • 동시성 실험
  • 개발 생산성이 최우선
  • 최신 기능이 필요한 경우

신중한 접근이 필요한 경우:

  • 프로덕션 환경 (3.14.1+ 대기 권장)
  • C 확장 모듈에 크게 의존
  • 레거시 코드베이스
  • 기업 환경

15.3 마이그레이션 체크리스트

# 1. 가상환경에서 테스트
python3.14 -m venv test_env
source test_env/bin/activate

# 2. 의존성 설치 확인
pip install -r requirements.txt

# 3. 테스트 실행
pytest tests/

# 4. 경고 확인
python -W default -m pytest tests/

# 5. 타입 체크
mypy src/

# 6. 성능 테스트
python -m pytest --benchmark-only

15.4 유용한 리소스

15.5 향후 전망

Python 3.14는 다음과 같은 미래 개선의 기반을 마련합니다:

  • Free-threading: Phase 3 진입 가능성 (기본 활성화)
  • JIT: 안정화 및 성능 최적화
  • 다중 인터프리터: 더 많은 고수준 추상화
  • 성능: 지속적인 최적화

15.6 피드백

Python 3.14를 사용하면서 발견한 버그나 개선 사항은 CPython 이슈 트래커에 보고해주세요.


이 글은 Python 3.14 공식 문서를 기반으로 작성되었습니다.
최신 정보는 Python 3.14 공식 문서를 참고하세요.

Happy Coding with Python 3.14! 🐍