가상환경 재설치 (uv)

한마디 요약

.venv를 통째로 날리고 uv venv로 다시 짓는 절차임. 클라우드 동기화 폴더(Google Drive/OneDrive)에서 uv sync 시 발생하는 os error 396 해결법까지 포함.

기본 재설치 (파이썬 3.12 기준)

rmdir /s /q .venv
uv venv --python 3.12 .venv
  • rmdir /s /q: 하위 파일까지 조용히 모두 지움 (/s 재귀, /q 확인 질문 생략)
  • uv venv --python 3.12 .venv: 파이썬 3.12 인터프리터로 .venv 재생성

직접 확인:

.venv\Scripts\python.exe --version

Python 3.12.x 가 찍혀야 함.

증상

warning: Failed to hardlink files; falling back to full copy.
error: Failed to install: jsonpointer-3.0.0-py2.py3-none-any.whl
  Caused by: failed to hardlink file from C:\Users\immor\AppData\Local\uv\cache\...
  to C:\1.Project\ALL_FOR_ONE\.venv\Lib\site-packages\...:
  클라우드 작업은 호환되지 않는 하드 링크가 있는 파일에서 수행할 수 없습니다. (os error 396)

원인 분석

1. uv의 작동 원리

uv가 다른 도구들보다 압도적으로 빠른 이유는, 패키지 파일을 매번 새로 다운로드/복사하지 않고 캐시 폴더(%USERPROFILE%\AppData\Local\uv\cache) 의 원본과 가상환경(.venv)을 하드 링크(hard link, 동일한 파일 데이터를 가리키는 두 개의 파일시스템 엔트리) 로 연결하기 때문임.

일상 비유: 중앙 창고(캐시)에 있는 상자를 지점 창고(.venv)로 “진짜 복사”하지 않고, “같은 상자에 라벨만 하나 더 붙이는” 방식. 디스크 용량도 아끼고 속도도 빠름.

2. 공식 문서 기준 기본 link-mode

OS기본값
macOS/Linuxclone (copy-on-write)
Windowshardlink

3. 충돌 원인

작업 폴더가 Google Drive 또는 OneDrive 같은 클라우드 동기화 폴더 안에 있으면, Windows는 해당 경로에서 하드 링크 생성을 엄격하게 차단함. 이유: 클라우드 동기화 서비스가 파일을 업로드 단위로 추적하는데, 하드 링크는 하나의 파일이 여러 경로에서 보이는 구조여서 동기화 상태를 계산할 수 없음.

결론: uv는 하드 링크를 만들려 하고, Windows(클라우드 동기화)는 이를 막음 → os error 396 발생.

1단계: uv 링크 모드를 copy로 강제 지정

존재 이유: 하드 링크가 막힌 환경에서 uv가 에러 없이 동작하도록, 파일을 실제로 복사(copy) 하는 방식으로 전환함.

변수 풀이:

요소역할
setWindows CMD에서 환경 변수를 현재 세션에 임시 생성/지정하는 내장 명령
UV_LINK_MODEuv가 패키지 설치 시 사용할 링크 방식을 결정하는 uv 전용 환경 변수
copy하드 링크 대신 실제 파일 데이터를 그대로 복사하라는 값

가능한 값 (공식 문서):

동작특징
clonecopy-on-write (APFS, Btrfs 등 지원 시)macOS/Linux 기본
copy파일 데이터를 그대로 복사가장 안전, 클라우드 폴더 호환
hardlink동일 inode 공유Windows 기본, 가장 빠름, 클라우드 폴더에서 차단됨
symlink심볼릭 링크캐시 삭제 시 환경 파괴 위험, 비권장

나중에 쓰이는 곳: 현재 CMD 창이 살아 있는 동안, uv가 sync/install 등으로 패키지를 설치할 때마다 이 값을 읽어 복사 방식을 적용함. 창을 닫으면 값이 사라짐.

set UV_LINK_MODE=copy

영구 적용이 필요하면 환경 변수를 시스템에 등록하거나, 프로젝트 pyproject.toml에 명시:

[tool.uv]
link-mode = "copy"

또는 uv.toml:

link-mode = "copy"

직접 확인:

echo %UV_LINK_MODE%

copy 가 찍혀야 함.

2단계: 패키지 동기화 재시도

존재 이유: 하드 링크 에러로 중단됐던 설치를, 방금 설정한 복사 방식으로 다시 돌림.

변수 풀이:

  • uv: Astral.sh의 파이썬 패키지 매니저 실행 명령
  • sync: pyproject.toml + uv.lock 을 기준으로 .venv를 일치시키는 하위 명령

나중에 쓰이는 곳: 이 명령이 완료되면 .venv\Lib\site-packages 에 deepeval을 포함한 모든 의존 패키지가 물리적으로 복사되어 저장됨. 이후 코드 실행이나 IDE의 Ctrl+Click(정의로 이동)의 근거 파일로 쓰임.

uv sync

전체 복구 스크립트 (원클릭)

클라우드 폴더에서 깨진 .venv를 전부 재구축:

rmdir /s /q .venv
set UV_LINK_MODE=copy
uv venv --python 3.12 .venv
.venv\Scripts\activate.bat
uv sync

copy 모드가 트레이드오프인가

관점hardlink (기본)copy
설치 속도매우 빠름상대적으로 느림 (실제 I/O 발생)
디스크 사용량적음 (캐시와 공유)많음 (파일 전체 복제)
클라우드 동기화 폴더 호환불가가능
캐시 삭제 시 영향없음 (하드 링크는 독립 inode)없음

결론: 클라우드 폴더에서 개발한다면 copy가 유일한 실사용 선택지. 속도가 아까우면 프로젝트 폴더를 C:\Dev 같은 비동기화 경로로 옮기는 것도 방법.

자주 마주치는 변형 에러

에러 메시지원인해결
os error 396클라우드 폴더 하드 링크 차단UV_LINK_MODE=copy
The system cannot find the path specified.venv 경로 깨짐재설치
ModuleNotFoundError after syncIDE가 다른 인터프리터 물고 있음IDE 가 가상환경의 파이썬 인식 못할때

포함 관계

  • 환경 변수 (Environment Variable) (프로세스에 주입되는 키-값 설정)
    • UV_LINK_MODE (uv 전용 링크 방식 결정)
      • copy / hardlink / clone / symlink
    • 기타 uv 관련 환경 변수: UV_CACHE_DIR, UV_PYTHON, UV_INDEX_URL

관련 노트