오늘은 서비스 배포중 발생한 굉장히 있으면 안될 이슈에 대해 작성해보고자한다.
문제상황
빌드가 잘되던 도커에서 pip 가 requirements.txt 설치하는 과정에서 문제가 발생한 것이다.
#11 68.49 Traceback (most recent call last):
#11 68.49 File "/usr/local/lib/python3.9/py_compile.py", line 144, in compile
#11 68.49 code = loader.source_to_code(source_bytes, dfile or file,
#11 68.49 File "<frozen importlib._bootstrap_external>", line 913, in source_to_code
#11 68.49 File "<frozen importlib._bootstrap>", line 228, in _call_with_frames_removed
#11 68.49 File "/usr/local/lib/python3.9/site-packages/asyncio/base_events.py", line 296
#11 68.49 future = tasks.async(future, loop=self)
#11 68.49 ^
#11 68.49 SyntaxError: invalid syntax
#11 68.49
#11 68.49 During handling of the above exception, another exception occurred:
#11 68.49
#11 68.49 Traceback (most recent call last):
#11 68.49 File "/usr/local/lib/python3.9/compileall.py", line 238, in compile_file
#11 68.49 ok = py_compile.compile(fullname, cfile, dfile, True,
#11 68.49 File "/usr/local/lib/python3.9/py_compile.py", line 150, in compile
#11 68.49 raise py_exc
#11 68.49 py_compile.PyCompileError: File "/usr/local/lib/python3.9/site-packages/asyncio/base_events.py", line 296
#11 68.49 future = tasks.async(future, loop=self)
#11 68.49 ^
#11 68.49 SyntaxError: invalid syntax
어 이게 무슨???? 보이는 바와 같이 asyncio패키지에서 문제가 생겼다는 것이다.
자 여기서 의문 발생.
asyncio는 표준라이브러리 -> 표준라이브러리가 requirements.txt 로 설치를 한다 ??
확인을해보니 진짜로 asyncio가 입력되어있었다.
asyncio==3.4.3 ; python_version >= "3.9" and python_version < "4.0"
문제 해결은 당연하게도 아주간단하다.
이 부분을 지우면 문제가 해결이 된다.
근데 왜 지금까지 문제가 발생하지않다가 갑자기 문제가 발생했을까?
여러상황을 유추해볼수있다.
- Python의 변경
- Asyncio의 변경
- Docker python:3.9.6 이미지의 변경
- pip의 변경
1. Python 버전은 고정이기때문에 변하지않는다 X
2. Asyncio 역시 표준라이브러리이고 버전이 고정이기때문에 변하지않는다 X
3. Docker python:3.9.6 이미지역시 immutable 한 이미지이다 X
4. pip 의 변경
맞습니다. 정확히 문제가 터진 28일 이틀전인 25년 4월 26일에 업데이트버전이 올라왔다.
그러면 왜 지금까지 발생하지않던 문제가 해당버전에서 발생했는지 알아보기로했다.
PIP Changlog
https://pip.pypa.io/en/stable/news/
결과적으로 이번에 바뀐 pip 25.1은 "문제를 만든" 버전은 아니였다
하지만 pip 25.0에서 이미 도입된 sdist 강제 빌드 + py_compile 강제 실패 중단 정책이 있었고,
25.1에 추가된 레거시 wheel 엄격 검사 로 인해 해당 문제가 실제로 발생되었습니다.
(#13319) setup.py bdist_wheel 방식 deprecation warning.
https://github.com/pypa/pip/pull/13319
Deprecate the `setup.py bdist_wheel` code path by sbidoul · Pull Request #13319 · pypa/pip
Towards #6334 Towards #9175 Towards #11859
github.com
(#13229) Wheel 파일 이름·메타데이터를 PEP 규격대로 엄격 파싱.
https://github.com/pypa/pip/pull/13229
Use `parse_wheel_filename` to parse wheel filename, with fallback by notatallshaw · Pull Request #13229 · pypa/pip
This expands and extends the deprecation warning from #12918 by first parsing with parse_wheel_filename and then falling back to the legacy regex if it fails. In particular I found a real world exa...
github.com
결과적인 문제의 흐름
wheel이 있어도 신뢰 불가 로 판단 → sdist 빌드를 시도 → 오래된 asyncio 소스가 Python 3.9 예약어(async)와 충돌 → py_compile 실패 → Docker 빌드 에러
Wheel이란?
“빌드 결과물까지 포함된, 즉시 설치 가능한 패키지”
큰 ---- 교훈
1. 표준 라이브러리는 절대 pip로 설치하지 말 것.
2. pip 정책 변화는 캐시·환경이 변한 순간에 터집니당..
'Python' 카테고리의 다른 글
[Python] Map (2) | 2022.09.01 |
---|---|
Immutable, Mutable (0) | 2022.06.07 |
Class 예제(3) - 원통의 표면적, 부피 (0) | 2022.05.17 |
Class 예제(2) - 두 점 사이의 거리, 기울기 (0) | 2022.05.17 |
Class 예제 (1) - 은행 계정 클래스 (0) | 2022.05.17 |