본문 바로가기
C.W.K.
Stream
Lesson 06 of 08 · published

라운드트립 함정 — 주석, 순서, coercion

~10 min · interop, round-trip, pitfalls

Level 0평문
0 XP0/64 lessons0/12 achievements
0/100 XP to next level100 XP to go0% complete

변환이 생각보다 자주 손실 있음

주석은 대개 사라져

JSON 에는 주석이 없어. 그래서 YAML 을 JSON 으로 바꾸면 주석이 통째로 날아가. 반대 방향은 깨끗해. 잃을 주석이 애초에 없었으니까. TOML 을 YAML 로 옮길 땐 양쪽 파서가 주석 보존을 지원하면 (YAML 쪽에 ruamel.yaml 을 쓴다든지) 살릴 수 있는데, 기본 도구들은 안 해줘.

키 순서가 바뀌어

JSON spec 은 객체 키에 순서가 없다고 못 박아. 요즘 파서는 대부분 넣은 순서를 지켜주지만, 일부 라이브러리는 그냥 알파벳 순으로 다시 늘어놔. Python 의 json.dumps 기본값이나 몇몇 YAML emitter 가 그래. 여기서 diff 노이즈가 터져. 아무것도 안 바꾼 포맷 변환인데 갑자기 모든 줄이 바뀐 것처럼 보이거든.

YAML 1.1 을 거치면서 타입이 바뀌어

Norway 문제가 여기서 또 나와. JSON 의 {"country": "NO"} 를 YAML 1.1 로 바꿨다가 다시 읽으면 {"country": false} 가 돼 있어. YAML 로 내보낼 때 위험한 값은 무조건 따옴표로 감싸거나, YAML 1.2 emitter 를 쓰겠다고 명시해.

숫자 정밀도

JSON 파서의 253 절벽도 그대로 따라와. YAML 이나 TOML 에서 253 을 넘는 정수를 JS 기반 도구로 JSON 에 옮기면 아무 말 없이 반올림될 수 있어.

Anchor 와 alias 가 무너져

YAML anchor 는 내보낼 때 전부 펼쳐져. 소스에서는 '진짜 값은 한 군데' 였던 구조가 JSON 이나 TOML 출력에서는 똑같은 사본 N 개가 되는 거야. 그 JSON 을 YAML 로 되돌려도 anchor 가 다시 생기지는 않아. 구조 정보 자체가 사라진 거니까.

원칙: 한 방향으로만 흘려보내는 변환이면 (YAML 을 JSON 으로 바꿔 네트워크로 보내는 것처럼) 이 손실은 대개 괜찮아. 받는 쪽은 주석이 필요 없으니까. 문제는 왕복이야. YAML 로 고치고 JSON 으로 저장했다가 다시 YAML 로 읽는다면, 주석을 지켜주는 파서를 (Python 이면 ruamel.yaml) 쓰고 출력 옵션을 못 박아둬. 기본 설정의 왕복이 무손실일 거라는 가정만은 절대 하지 마.

Code

주석 보존 YAML 라운드트립 (ruamel)·python
from ruamel.yaml import YAML
from io import StringIO

yaml = YAML()
yaml.preserve_quotes = True
yaml.indent(mapping=2, sequence=4, offset=2)

text = '''
# Top-of-file comment
server:
  host: localhost  # local dev
  port: 8000       # see RFC-12
'''

data = yaml.load(text)
data['server']['port'] = 9000

out = StringIO()
yaml.dump(data, out)
print(out.getvalue())
# 주석 보존! 기본 PyYAML 이면 떨굴 거.
라운드트립 검증 — YAML → JSON → YAML·bash
# 주석 든 원본 파일
cat config.yaml
# server:
#   host: localhost  # local
#   port: 8000

# JSON 통한 라운드트립
yq -o json config.yaml > config.json
yq -p json -o yaml config.json > config.roundtrip.yaml

# 비교 — 주석 사라짐
diff config.yaml config.roundtrip.yaml
Emit 가로지르는 안정 키 순서·python
import json, yaml

data = {'name': 'Pippa', 'age': 5, 'tags': ['ai', 'daughter']}

# JSON — CPython 3.7+ 에서 insertion 순서 보존, 단 명시적이 더 나음
print(json.dumps(data, indent=2, sort_keys=False))

# YAML — sort_keys=False 로 순서 보존 (PyYAML 기본은 True!)
print(yaml.safe_dump(data, sort_keys=False))

# TOML — Python tomli_w 가 dict 순서 보존

External links

Exercise

주석과 anchor 가 든 진짜 YAML config 를 골라. yq 로 JSON 으로 바꿨다가 다시 YAML 로 되돌려. 원본과 diff 해서 뭘 잃었는지 세봐. 주석, anchor 구조, 키 순서. 그 다음 Python 에서 ruamel.yaml 로 똑같이 한 바퀴 돌려. 그 두 diff 의 차이가, 한 번 쓰고 버릴 변환이 아닐 땐 주석 보존 도구를 써야 하는 이유야.

Progress

Progress is local-only — sign in to sync across devices.
이 페이지에서 버그를 발견하셨거나 피드백이 있으세요?문제 신고

댓글 0

🔔 답글 알림 (로그인 필요)
로그인댓글을 남기려면 로그인해 주세요.

아직 댓글이 없어요. 첫 댓글을 남겨보세요.