uv 0.13.0이 UTC 기준 10월 9일, 한국 기준 10월 10일 나왔다. 버전을 요청하거나 고정하지 않았을 때 내려받는 기본 안정 Python이 3.14에서 3.15로 바뀌었다.
이미 설치된 호환 Python은 계속 쓰인다. 예를 들어 uv venv는 설치된 Python 3.14를 그대로 쓸 수 있다.
적합한 인터프리터가 없고 자동 다운로드가 켜져 있으면 uv venv나 uvx python 같은 명령이 이제 Python 3.15를 내려받을 수 있다. 릴리스 노트는 uv venv --python 3.14처럼 3.14를 명시적으로 요청하거나, 프로젝트에서 uv python pin 3.14로 버전을 기록하면 이 동작을 피할 수 있다고 설명한다.
Python 버전 요청과 자동 다운로드
uv의 Python 버전 문서에 따르면 --python 옵션은 필요한 버전을 요청하고, uv python pin은 현재 디렉터리에 .python-version 파일을 만든다. uv는 작업 디렉터리와 상위 디렉터리에서 이 파일을 찾아 기본 버전 요청으로 쓴다.
자동 다운로드는 python-downloads 설정으로 끄거나, 어떤 uv 명령에든 --no-python-downloads 플래그를 넘겨 끌 수 있다.
uv 실행 파일의 버전을 고정하는 것과 Python 버전을 고정하는 것은 별개다. 도구 버전은 어떤 선택 동작을 쓰는지를, Python 요청은 어떤 인터프리터로 작업할지를 정한다.
엄격해진 제약 파일 처리
이전에는 requirements 파일에서 -c로 포함한 제약 파일의 --require-hashes를 무시했다. 이제는 이 지시문을 따라 설치하는 모든 요구 사항에 해시를 요구하므로, 해시가 빠진 항목이 있으면 이전에 성공하던 설치가 실패할 수 있다.
지시문이 있는 동안에는 이 동작을 끌 수 없다. 빠진 해시를 채우거나, 해시 검사를 의도하지 않았다면 포함한 제약 파일에서 지시문을 지워야 한다.
포함한 제약 파일의 editable(-e) 요구 사항도 조용히 무시하는 대신 오류로 거부하며, pip의 동작과 맞춘 것이다. 해당 항목은 -r로 넘기는 requirements 파일로 옮기거나 --editable로 직접 넘긴다.
새 CI에서 드러나는 인터프리터 차이
개발 컴퓨터는 이미 설치된 3.14를 재사용해 성공하고, 깨끗한 CI 환경은 3.15를 내려받을 수 있다. 같은 uv 버전이라도 설치된 Python에 따라 결과가 갈리는 셈이다.
테스트 기록에 실제로 고른 인터프리터 버전을 남기면 두 환경의 차이를 바로 비교할 수 있다.
새 실패가 가리키는 것
해시 오류는 resolver 회귀가 아니라, 이전에 무시되던 무결성 정책이 처음 적용된 결과일 수 있다. 문제를 찾을 곳은 최상위 requirements 파일만이 아니라 -c로 연결된 파일 전체다.
editable 항목을 옮길 때는 제약 조건과 설치 요청의 역할이 다르므로, 옮긴 뒤 실제로 무엇이 설치되는지가 달라질 수 있다.
주의할 점: 두 변화가 한 번에 겹칠 때
인터프리터 선택과 제약 파일 처리가 같은 업그레이드에서 함께 바뀌면, 실패 원인이 두 갈래가 되고 성공해도 환경 차이가 가려질 수 있다. 이 글은 uv 설치, 환경 생성, 의존성 해석을 직접 실행하지 않았다.
10월 10일 호는 한국 날짜를 따른 것이며 릴리스 출처의 날짜는 10월 9일이다.
uv 0.13.0은 고정하지 않은 Python 다운로드를 3.15로 옮기고 포함한 제약 파일의 해시·editable 규칙을 강제하므로, 업그레이드 실패는 인터프리터 선택과 제약 파일 처리로 나눠 봐야 원인이 보인다.
