R&D
개발현황
레거시 프로젝트 환경 복구 : 정혜성 연구원
- 관리자
- 2025.07.14
레거시 프로젝트 환경 복구 #pyenv #uv
작성일시 : 2025년 5월 29일 목요일
작성자 : 정혜성
들어가며
얼마전 고객사로부터 급한 요청이 들어왔습니다.
“새로운 타입을 검사 로직에 반영해달라.”
무려 7년 전에 납품했던 검사장비에서 신규 제품 타입이 추가되었는데,
검사 프로그램이 이를 계속 NG 판정을 내리고 있다는 것이었습니다.
요청은 단순했지만 실제로는 생각보다 손이 많이 가는 작업이었습니다.
UI 화면도 수정해야 했고, 무엇보다도 프로그램을 실행해보기 위한 환경부터 다시 세팅해야 했습니다.
이 프로그램은 제가 입사 후 처음 개발했던 검사장비 프로젝트였습니다.
그 사이 회사의 Git 저장소는 GitLab에서 GitHub로 이전되었고, 당시 사용하던 제 맥북도 이미 교체된 상태였습니다.
작업을 하려면 결국 파이썬 버전부터 의존성 패키지까지 당시 작업했던 환경을 다시 구성해야 했습니다.
사실 오늘 이야기하고 싶은 포인트가 바로 파이썬 버전 관리
와 의존성 패키지 관리
에 대한 내용입니다.
예전에는 pyenv
로 Python 버전을, virtualenv
로 가상 환경을 관리했지만,
최근에는 설치 속도가 빠르고 pyproject.toml
기반의 통합 구성이 가능한 uv
를 주로 사용하고 있습니다.
pyenv
와 uv
는 언젠가 한 번쯤 기술 노트에서 다뤄보고 싶었던 주제였는데, 이번 기회에 간단히 소개해보려 합니다.
1. Kivy와 OpenCV로 만든 첫 검사 프로그램
이 프로그램은 Python 기반의 비전 검사 GUI 애플리케이션으로,
Kivy 프레임워크를 사용해 UI를 구성하고 OpenCV로 실시간 영상 처리 및 검사 기능을 구현했습니다.
Kivy는 그 당시에도 생소한 프레임워크였고, 문서나 참고 자료가 부족해 개발 난이도가 꽤 높았습니다.
비록 이 프로젝트 이후로 Kivy를 다시 사용할 일은 없었지만,
첫 프로젝트였던 만큼 고생도 많았고, 그만큼 애정도 많이 남아 있는 프로그램입니다.
장비 구조는 단순합니다.
제품을 올려놓으면 카메라로부터 이미지를 수신하고,
특정 영역에 대해 전처리 및 조건 판별을 수행한 뒤,
검사 결과에 따라 장비를 제어하거나 로그를 기록하는 방식입니다.
2. 프로젝트 원격 저장소 행방불명
코드 작업에 앞서 Git 원격저장소 상태를 확인하던 중, 해당 프로젝트가 GitHub에 존재하지 않는다는 사실을 발견했습니다.
작년 말, 사내 Git 저장소를 온프레미스 GitLab에서 GitHub로 이전하는 과정에서 이 프로젝트가 누락된 것이었습니다.
다행히 제 맥북에는 해당 프로젝트의 코드가 그대로 남아 있었습니다.
문제는 .git
폴더의 용량이 무려 2.1GB에 달해, GitHub의 단일 파일 최대 용량 제한(2GB) 때문에 push
가 불가능한 상황이었습니다.
(아마 예전에도 같은 이유로 업로드에 실패했고, 결국 작업을 미루다가 방치되었을 가능성이 높습니다.)
git gc
, git filter-branch
등 다양한 방법으로 .git
폴더 용량을 줄여보려 했지만 실패했습니다.
더는 시간을 미룰 수 없는 상황이었기에, .git 폴더를 과감히 삭제하고 새 GitHub 저장소를 생성한 뒤, 원격 저장소를 다시 연결하여 프로젝트를 Push했습니다.
이로써 원격 저장소를 통한 코드 관리는 가능해졌지만, 기존 커밋 히스토리를 보존하지 못한 점은 아쉬움으로 남았습니다.
이미지나 로그처럼 대용량 파일을 실수로 커밋하면, .git 폴더가 비정상적으로 커질 수 있습니다.
초기에 .gitignore를 잘 설정하는 것이 중요합니다.
3. 파이썬과 의존성 패키지 설치
이 프로젝트는 Python 3.6.7 환경에서 개발되었기 때문에, 먼저 해당 버전에 맞추는 작업이 필요했습니다.
하지만 uv
는 Python 3.8 이상부터 지원되므로, pyenv
를 이용해 Python 3.6.15를 설치했습니다.
하지만 시작부터 Kivy 설치가 안되는 문제가 했습니다.
찾아보니 Apple Silicon 기반의 Mac에서 Python 3.6.x를 사용할 때, macOS SDK 및 Xcode 버전과의 호환성 문제로 인해 Kivy 설치에 어려움을 겪는 사례가 있었습니다.
결국 Python 3.8 이상으로 버전을 올려 uv
를 사용하는 쪽으로 방향을 전환했습니다.
이후 requirements.txt
를 참고해서 패키지를 설치하고, 누락된 것들을 하나씩 수동으로 추가해 나갔습니다.
4. 추가로 발생하는 에러 해결
패키지 설치가 끝난 후에도 여러가지 문제들이 발생했습니다.
1) numpy
Type Deprecated
numpy
의 최신 버전에서는 np.float
, np.int
등의 타입이 deprecated 처리되었습니다.
이에 따라 기존 코드에 사용된 타입 선언을 모두 np.float32
, np.int32
등으로 명시적으로 수정해야 했습니다.
# 기존
a = np.zeros(10, dtype=np.float)
# 수정
a = np.zeros(10, dtype=np.float32)
2) pyzbar
ImportError
바코드 인식을 위해 사용하던 pyzbar
라이브러리에서 다음과 같은 에러가 발생했습니다:
ImportError: Unable to find zbar shared library
brew install zbar
로 관련 라이브러리를 설치해봤지만, 오류는 해결되지 않았습니다.
결국 pyzbar
대신 OpenCV의 바코드 디코딩 기능을 활용하는 방식으로 우회하여 테스트를 진행했습니다.
3) 검사 결과 이상
사이클 검사가 실행되는 환경까지는 구축했지만, 검사 결과가 전혀 예상과 다르게 나타났습니다.
오랜 시간 코드를 디버깅한 끝에, 문제의 원인이 코드가 아닌 settings.json
파일의 ROI 설정값에 있었음을 확인했습니다.
비정상적인 설정으로 인해 결과가 왜곡되었던 것입니다.
우여곡절 끝에 개발 환경 세팅도 마치고, 코드 작업도 완료하고, 마지막으로 현장에서 테스트를 진행했는데
카메라 DLL 파일이 로컬에 설치된 파이썬 3.6.7 환경에서만 정상 동작하는 문제가 발생해서
결국 uv 환경을 다시 제거하고 로컬에 원래 설치되어 있었던 파이썬을 사용해야 했습니다..ㅜ
5. 파이썬 버전 관리와 의존성 관리
파이썬 버전 관리의 필요성
보통은 하나의 로컬 환경에서 여러 프로젝트를 병행하게 되고,
이번처럼 아주 오래된 프로젝트를 다시 꺼내봐야하는 경우도 발생합니다.
이럴때 만약 파이썬 버전 관리나 의존성 격리 도구조차 없었다면?
로컬에 파이썬을 설치했다 삭제했다 반복하면서 엄청난 시간을 낭비했을 것입니다.
파이썬은 하위 호환성이 완벽하지 않은 언어입니다.
Python 2에서 3으로 넘어올 때가 특히 심했지만, 3.x 대 버전에서도 일부 기능들의 사용법이 변경되거나 사라지는 등 호환성 이슈들이 발생합니다.
그래서 여러 프로젝트를 동시에 진행할 때는 각 프로젝트에 맞는 파이썬 버전을 분리해서 관리하는 것이 필수입니다.
이를 가능하게 해주는 도구가 바로 pyenv와 uv입니다.
의존성 관리의 필요성
예를 들어,
- A 프로젝트는 numpy==1.18
- B 프로젝트는 numpy==1.26
한 대의 PC에서 두 프로젝트를 함께 개발하려면
각각의 의존성을 완전히 분리된 환경에서 관리해야 합니다.
이걸 가능하게 해주는 것이 virtualenv입니다.
6. pyenv에서 uv로: 환경 관리 도구의 진화
사실 pyenv, virtualenv, conda, poetry, pipenv, uv 등,
파이썬에서 버전 관리, 가상환경 생성, 의존성 관리를 위한 도구는 정말 다양합니다.
이 글에서 특히 pyenv와 uv에 집중하려는 이유는,
제가 지난 5년간 pyenv를 꾸준히 사용해오다가 최근에서야 uv로 옮겨가게 되었기 때문입니다.
직접 사용하며 느낀 점들, 그리고 두 도구가 지향하는 방향과 작동 방식의 차이를 정리해보려 합니다.
pyenv란?
pyenv는 원하는 Python 버전을 여러 개 설치하고, 디렉터리별로 사용할 버전을 지정해주는 도구입니다.
예를 들어,
pyenv install 3.6.15
pyenv install 3.10.0
이렇게 여러 버전을 설치해두고,
pyenv global 3.10.0 # 전체 시스템 기본 파이썬 버전
pyenv local 3.6.15 # 특정 디렉토리 내 파이썬 버전 지정
처럼 상황에 따라 유연하게 버전을 전환할 수 있습니다.
디렉토리마다 .python-version 파일이 생성되기 때문에, 프로젝트 단위로 버전을 자동 적용할 수 있다는 점도 아주 편리합니다.
pyenv 단독으로는 파이썬 버전만 관리할 수 있기 때문에, 가상환경까지 같이 쓰려면 pyenv-virtualenv를 함께 설치해서 사용합니다.
pyenv virtualenv 3.6.15 my-legacy-project
pyenv activate my-legacy-project
이렇게 버전과 환경을 동시에 지정할 수 있어서, 오래된 프로젝트를 유지보수하거나 다양한 환경을 실험할 때 정말 유용합니다.
지금 제가 사용중인 pyenv 버전들 입니다.
pyenv를 설치하면 상대경로 밑에 .pyenv
폴더가 생성됩니다.
그리고 그 바로 밑에 vesions 폴더가 생성되고,
모든 파이썬 버전과 가상환경이 이 곳에서 관리됩니다.
pyenv는 파이썬 버전과 가상환경을 관리하고 사용하기에 매우 편리하고 유용한 도구입니다.
저 역시 지난 몇 년 동안 다양한 프로젝트에서 잘 써왔고, 지금도 계속 사용하고 있습니다.
장점을 정리해보면,
- 원하는 파이썬 버전을 자유롭게 설치/전환 가능
- 프로젝트별로 파이썬 버전 고정 가능 (.python-version)
- pyenv-virtualenv와 조합하면 버전 + 가상환경을 동시에 관리 가능
- 하나의 가상환경을 여러 프로젝트에서 공유 가능
반대로 단점을 정리해보면,
- 상대적으로 설치 속도가 느림
- 초기 설치 및 세팅이 까다로울 수 있음
- 의존성 패키지 관리는 따로 pip, requirements.txt 등으로 수동 관리해야 함
uv 란?
uv는 최근 빠르게 주목받고 있는 올인원 Python 패키지/환경 관리 도구입니다. Rust로 개발되어 속도가 매우 빠르고, pip, venv, pip-tools 같은 기존 도구들의 기능을 통합해 파이썬 프로젝트의 환경 구성을 더 단순하게 만들어줍니다.
간단히 말하면,
uv 하나로 가상환경 생성부터 패키지 설치, 잠금(lock) 파일 관리까지 한 번에 처리할 수 있습니다.
설치는 간단하게 한 줄이면 끝납니다.
# Windows
powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"
# macOS and Linux
curl -LsSf https://astral.sh/uv/install.sh | sh
uv는 기본적으로 모든 명령을 uv
로 시작합니다.
uv python list # 설치된/설치가능한 파이썬 목록 조회
uv python install 3.8.15 # 파이썬 버전 설치
uv venv -p 3.8.15 # 가상환경 생성
uv pip install numpy # 패키지 설치
uv init
명령어를 통해 pyproject.toml
파일을 생성합니다.
반대로 pyproject.toml
파일만 있으면, uv sync
명령어를 통해 Python 버전과 .venv
가 자동으로 맞춰집니다.
또한 python
명령어 대신 uv run
을 사용하는데,
만약 가상환경이 없다면 자동으로 생성하고 환경까지 맞춰서 파이썬 스크립트를 실행해줍니다.
다만 uv는 프로젝트마다 .venv를 생성해 공통 패키지도 매번 새로 설치해야 하며,
이부분이 pyenv 에서 uv 로 넘어올때 특히 불편하게 느껴졌던 부분이기도 합니다.
또한 이로 인해 디스크 사용량이 늘고 반복 작업처럼 느껴질 수 있다는 단점이 있습니다.
하지만 이는 프로젝트마다 독립적인 환경을 구성함으로써 재현성과 안정성을 높이려는 설계 의도가 반영된 것으로 보입니다.
장점을 정리해보면,
- 패키지 설치가 상당히 빠름 (체감상 pip install 보다 두 배 이상)
- PEP 621을 따르는 pyproject.toml 기반 프로젝트를 지원, 개발환경 통합관리 가능
- poetry 없이도 pyproject.toml 기반으로 관리 가능
- .venv 폴더 자동 관리 → 깔끔한 프로젝트 구조 유지 가능
반대로 단점을 정리해보면,
- Python 3.8 이상만 지원 (레거시 프로젝트에는 사용 불가)
- 프로젝트 간 가상환경 공유 불가, 디스크 사용량 증가
환경 관리 도구의 진화
과거에는 pyenv
, virtualenv
, requirements.txt
조합이 사실상 표준처럼 쓰였습니다.
이 방식은 유연하긴 하지만,
버전과 의존성 정보가 분산되어 있어 협업 시 관리 포인트가 많고 실수도 잦았습니다.
반면 uv
는 이 모든 정보를 pyproject.toml
하나로 통합합니다.
파이썬 버전 + 의존성 패키지 + 가상환경 위치 및 실행 방식
모두 명시적으로 관리되기 때문에,
팀원 간 환경 불일치나 설치 누락 문제를 최소화할 수 있습니다.
게다가 pyproject.toml
은 이미 poetry, black, ruff, pytest 등
여러 Python 생태계 도구들이 채택한 사실상 표준 포맷입니다.
이런 흐름 속에서 uv는 빠르고, 단순하며, 표준을 따르는 도구로 주목받고 있으며,
개인의 설정을 넘어서 팀의 합의된 개발 환경을 만드는 데 적합한 도구로 자리잡고 있습니다.
7. 마치며
이번 작업을 통해 다시금 확인한 사실은 다음과 같습니다.
- Python 프로젝트는 버전과 의존성 관리가 중요하다.
- 가상환경은 선택이 아니라 필수다.
- .gitignore, pyproject.toml, README는 반드시 남기자.
환경 문서 작성이 번거롭고 귀찮게 느껴질할 수 있지만
오늘 이야기하고 싶은 부분은,
요즘은 uv 같은 도구를 활용하면 문서화 없이도 pyproject.toml 하나로 환경 구성과 의존성 관리가 자동으로 된다는 점입니다.
솔직히, 개발 환경 관리만 놓고 보면 pyenv만으로도 충분했습니다.
오히려 상황에 따라서는 pyenv가 더 편하게 느껴질 때도 있고,
현재도 일부 프로젝트에서는 병행해서 사용하고 있습니다.
그럼에도 불구하고, 새로운 도구가 등장했을 때 그 장점이 명확하다면 직접 사용해보는 것이 좋다고 생각합니다.
저 역시 uv의 빠른 설치 속도와 통합된 관리 방식이 확실히 도움이 된다고 느끼고 있고,
팀 차원에서도 파이썬 환경 관리 도구를 일관되게 사용한다면 협업 효율과 재현성이 크게 개선될 것으로 기대하고 있습니다.