CPN 한국어 자습서 · 외부 문서 한국어 미러
UV 문서 · Reference
Resolver · 원문: docs.astral.sh/uv/reference/internals/resolver/
아래는 원문을 한국어로 옮긴 미러입니다. 코드·명령은 원문 그대로이며, 가장 최신 정보는 하단 원문 링크에서 확인하세요.
이 문서는 uv 리졸버의 내부 동작 방식을 설명합니다. 리졸버(resolver)는 주어진 요구 사항 집합으로부터 설치할 패키지(package) 버전을 결정합니다.
uv는 pubgrub-rs를 사용합니다. 이는 PubGrub의 Rust 구현체로, 점진적 버전 솔버입니다. 리졸버는 다음 단계를 거칩니다.
모든 패키지에 호환 버전이 확정되거나, 루트 패키지를 포함하는 비호환성이 발견되어 해결 불가능하다고 판단될 때까지 이 과정을 반복합니다.
핵심 인사이트: "uv에서 해석이 가장 느린 부분은 캐시(cache)에 저장된 경우에도 패키지 및 버전 메타데이터(metadata)를 로드하는 작업입니다."
Python 패키지는 환경에 따라 서로 상충하는 요구 사항을 갖는 경우가 많습니다. 예를 들면 다음과 같습니다.
numpy>=2,<3 ; python_version >= "3.11" numpy>=1.16,<2 ; python_version < "3.11"
uv는 Poetry에서 영감을 받은 포킹(forking) 리졸버를 사용합니다. 마커(marker)가 서로 다른 요구 사항이 여러 개 존재하면, 해석이 별도 분기로 나뉩니다. 각 포크(fork)는 특정 마커 조건을 처리하며, 동일한 패키지를 가진 포크는 병합되어 오버헤드를 최소화합니다.
포크는 락파일(lockfile)의 resolution-markers에 기록되어, 여러 번 실행해도 안정적이고 재현 가능한 해석을 보장합니다.
휠 태그(wheel tag)는 Python 버전, 구현체, OS, 아키텍처 제약을 인코딩합니다. uv의 해석은 환경 마커에 대해 범용적이지만, 휠 태그 호환성은 더 엄격합니다. PyTorch 같은 일부 패키지는 특정 플랫폼용 휠만 배포하기 때문에, 지원하지 않는 아키텍처나 Python 버전에서는 설치에 실패할 수 있습니다.
각 포크 내에서 uv는 알려진 마커 값에 따라 요구 사항을 필터링합니다. 리졸버는 중복된 마커 표현식을 표준 표현으로 정규화하여 서로 비교할 수 있도록 합니다.
로컬 태그가 있는 버전(예: 1.2.3+localtag)이 특정 플랫폼에서 휠을 지원하지 않지만, 더 광범위한 지원을 제공하는 기본 버전이 존재하는 경우, uv는 플랫폼에 따라 두 버전 모두를 잠재적으로 사용할 수 있도록 포킹합니다.
uv는 인덱스(index)의 단일 패키지 버전에 속한 모든 휠이 동일한 의존성(dependency)을 가져야 한다고 요구합니다. 이 가정 덕분에 다음이 가능합니다.
소스 배포본(source distribution)은 공개된 휠과 동일한 메타데이터를 가진 휠을 생성해야 하며, 빌드할 때마다 동일한 메타데이터를 생성해야 합니다. 이를 어기면 재현성과 잠금 보장이 깨집니다.
uv는 모든 의존성이 프로젝트와 동일한 최소 Python 버전을 공유하도록 강제합니다. 의존성이 더 새로운 Python 버전을 요구하면 거부되어, 기존 패키지를 레거시 Python 버전에서도 계속 설치할 수 있도록 합니다.
uv는 requires-python의 상한 버전을 무시합니다. 이로써 사용자가 더 새로운 Python 버전을 테스트하는 것을 막지 않으며, 상한 제약이 없는 구버전이 선택되는 우회 상황을 방지합니다.
더 높은 Python 최솟값을 요구하는 버전을 만나면, uv는 Python 버전별로 해석을 포킹합니다.
numpy==2.0.0; python_version >= "3.9" and python_version < "3.10" numpy==2.1.0; python_version >= "3.10"
URL로 지정된 의존성(예: package @ url, git, path, workspace)은 URL 의존성입니다. uv는 패키지를 선언된 URL과 그에 내포된 버전에 고정합니다. 동일 패키지에 충돌하는 URL이 존재하면 해석 오류가 발생합니다.
uv는 해석 시작 전에 모든 URL 의존성과 그 전이적(transitive) URL 의존성을 탐색합니다. 인덱스 패키지에는 URL이 허용되지 않습니다. 이는 비레지스트리(non-registry) 배포본이 예기치 않게 도입되는 것을 막고, 보안성과 감사 가능성을 유지합니다.
우선순위는 성능과 해결책 품질 모두에 영향을 미칩니다. uv의 우선순위는 다음과 같습니다.
== 연산자를 사용한 단일 요구 사항(singleton requirement)각 범주 내에서 패키지는 발견 순서로 정렬되어, 직접 의존성을 우선시하는 너비 우선 탐색(breadth-first search)을 형성합니다.
패키지가 더 높은 우선순위 패키지와 빈번한 충돌을 보이면, uv는 해당 패키지를 고충돌(high-conflict) 상태로 격상하고 충돌 패키지보다 먼저 결정하도록 수동 역추적을 수행합니다. 이로써 낮은 우선순위 패키지의 모든 버전을 불필요하게 소진하지 않아도 됩니다.
원문(영어): https://docs.astral.sh/uv/reference/internals/resolver/ · 본 문서는 학습용 한국어 번역이며 원본의 권리는 원저작자(Astral)에게 있습니다.
원문(영어): https://docs.astral.sh/uv/reference/internals/resolver/