프로젝트 디렉토리 이동 후 Poetry Virtualenv 경로 문제 해결하기
문제 상황
Python 프로젝트를 다른 디렉토리로 이동한 후:
/Users/you/projects/my-python-app
→
/Users/you/new-projects/my-python-app
Poetry가 계속 이전 virtualenv 경로를 보여줬습니다:
❯ poetry env info
Virtualenv
Python: 3.11.11
Path: /Users/you/projects/my-python-app/.venv
Valid: False
poetry env remove, poetry env use를 실행하고 .venv를 완전히 삭제해도 이전 경로가 계속 표시되었습니다.
조사 과정
잘못된 단서들
여러 가지를 확인했지만 원인이 아니었습니다:
- Poetry 캐시 디렉토리 (
~/Library/Caches/pypoetry/) - 패키지 아티팩트만 있고 virtualenv 경로는 없음 - Poetry 설정 파일 (
~/Library/Application Support/pypoetry/config.toml) -virtualenvs.in-project = true올바르게 설정됨 - 프로젝트 파일 (
pyproject.toml,poetry.lock) - 하드코딩된 경로 없음 .venv/pyvenv.cfg- 이전 경로 포함하지 않음- Poetry 해시 기반 캐싱 - Poetry는 프로젝트 경로의 SHA256 해시를 사용하지만 캐시된 해시 파일이 발견되지 않음
진짜 원인
환경 변수를 확인하면서 문제를 발견했습니다:
❯ env | grep -i virtual
VIRTUAL_ENV=/Users/you/projects/my-python-app/.venv
VIRTUAL_ENV 환경 변수가 이전 경로로 설정되어 있었습니다!
근본 원인
프로젝트는 virtualenv를 소스하는 .envrc 파일과 함께 direnv를 사용하고 있었습니다:
# .envrc
dotenv
source .venv/bin/activate
프로젝트를 이동했을 때:
- 이전
.venv디렉토리가 프로젝트와 함께 이동됨 .venv/bin/activate스크립트에 이전 위치를 가리키는 하드코딩된VIRTUAL_ENV경로가 포함됨- direnv가 처음 디렉토리에 진입할 때 이 환경을 캐시함
.venv를 다시 생성한 후에도(activate 스크립트에 올바른 경로 포함) direnv는 캐시된 환경을 계속 사용
Poetry는 VIRTUAL_ENV 환경 변수를 읽어 현재 virtualenv를 결정하므로, 계속 이전의(이제는 유효하지 않은) 경로를 보여줬습니다.
해결 방법
.venv 디렉토리를 다시 생성한 후(Poetry가 올바르게 수행):
rm -rf .venv && poetry install
direnv를 다시 로드하여 새 activate 스크립트를 적용하면 됩니다:
direnv reload
또는 디렉토리를 나갔다가 다시 들어가면 됩니다:
cd .. && cd -
핵심 교훈
-
Poetry의
env info는VIRTUAL_ENV를 반영 - 이 환경 변수가 설정되어 있으면 Poetry는 virtualenv를 새로 찾지 않고 이 값을 보여줍니다. -
direnv는 환경 상태를 캐시 - direnv를 통해 스크립트를 소스하면 결과 환경이 캐시됩니다. 기본 스크립트의 변경은
direnv reload가 필요합니다. -
Virtualenv activate 스크립트에는 하드코딩된 경로가 포함 -
.venv/bin/activate의VIRTUAL_ENV변수는 생성 시점에 절대 경로로 설정됩니다. 디렉토리를 이동하면 이것이 깨집니다. -
해결책은 예상보다 간단한 경우가 많음 - Poetry 내부를 광범위하게 조사한 후, 해결책은 간단한
direnv reload였습니다.
예방법
Poetry + direnv를 사용하는 Python 프로젝트를 이동할 때:
- 이동 전후에 이전
.venv를 삭제 poetry install을 실행하여 새 virtualenv 생성direnv reload를 실행하여 캐시된 환경 갱신
또는 더 간단하게: direnv를 사용하는 프로젝트를 이동한 후에는 항상 direnv reload를 실행하세요.