'직렬화 포맷 개량과 라이브러리 구현 - PyCon Korea 2020' 발표의 발표자료 입니다.
암호학적 해시나 디지털 서명 등의 입력으로 직렬화된 데이터를 쓰려면, 해당 입력 데이터는 같은 의미에 대해서는 일관된 표현을 가져야 합니다. 하지만 JSON 등 널리 쓰이는 직렬화 포맷은 "a"와 "\x61"과 같이 하나의 의미를 여러 방식으로 표현할 수 있기 때문에, 의미는 같은데 해시나 서명이 달라지는 일이 발생하게 됩니다. 이런 문제를 해결하기 위해 여러 직렬화 포맷을 서베이하고, 그 중에서 가장 적절한 것을 좀더 개량한 뒤 Pythonic하게 구현한 경험을 공유합니다.
23. 타입검사
from bencodex import dump
with open("file.dat", "wb") as f:
dump(f, "value") # 인자 순서 틀림
# error: Argument 2 to "dump" has incompatible type "str"; expected "BinaryIO"
25. bencodex/types.py @1.0.1
from typing import Any
__all__ = 'BValue',
BValue = Any
# Mypy currently does not support recursive types.
# https://github.com/python/mypy/issues/731
26. Mypy는현재재귀타입미지원
BValue 는 bool , int 같은스칼라값외에도목록이나사전처럼복잡한값을포함.
그러나이를타입으로표현하려면 Sequence[BValue] 나 Mapping[Union[str, bytes],
BValue] 와같이타입정의안에다시 BValue 라는이름이등장할수있어야함.
타입정의안에정의하려는타입( BValue )을쓸수있게해주는게recursivetypes
(예: BValue = Union[..., Sequence[BValue]] ).
Mypy는아직이기능을미지원해서일단 BValue = Any 로정의해둘수밖에없었다.
그러나mypy측에서해당문제해결가능성도보임!
<github.com/python/mypy/issues/731>
28. bencodex/writer.py @1.0.1
elif isinstance(value, collections.abc.Mapping):
…
items = [
(u, k.encode('utf-8') if u else k, v)
for k, v in value.items()
for u in [is_unicode(k)]
]
items.sort()
…