9강. 가상환경 구현: 외부 패키지 설치

0. 학습 목표
→ 가상환경 안에 외부 패키지를 설치하고, 설치 위치가 가상환경 내부인지 검증합니다.
이번 글은 구현 중심 강의입니다.
8강에서 호환성 문제의 해법은 "프로젝트별로 버전 조합을 고정하는 것"이라고 결론 내렸습니다.
이번 강의에서는 그 고정이 실제로 일어나는 순간을 만듭니다.
6강에서 만든 test_venv2(Python 3.13)에 GUI 패키지 PySide6를 설치합니다.
이 실습의 핵심은 설치 자체가 아닙니다.
pip install을 실행했을 때 패키지가 시스템 Python이 아니라 현재 활성화된 가상환경 내부에 설치되는지 확인하는 것입니다. 확인 도구는 pip show가 알려주는 Location 경로입니다.
test_venv2 활성화
↓
python -m pip install PySide6
↓
python -m pip show PySide6 로 Location 확인
↓
Location이 test_venv2 내부 경로로 출력됨 ← 이번 강의의 성공 지점
↓
import 테스트로 실제 동작 확인
| 구분 | 내용 |
| 이해할 것 | 가상환경 활성화 상태의 pip가 패키지를 어디에 설치하는지 |
| 만들 것 | PySide6가 설치된 test_venv2 — "Python 3.13 + PySide6" 조합의 완성 |
| 확인할 것 | pip show의 Location이 시스템 경로가 아닌 test_venv2/lib/.../site-packages인지 |
시작 전에 6강의 가상환경을 활성화합니다.
이 강의는 test_venv2가 만들어져 있다는 전제로 진행하므로, 없다면 6강을 먼저 진행하세요.
cd ~/Dev/Python2
source test_venv2/bin/activate # 6강에서 만든 가상환경 활성화
python --version # Python 3.13.x 확인 (6강의 확인 기준과 동일)
1. 가상환경에 PySide6 설치하기
→ 활성화된 가상환경 안에서 pip로 외부 패키지를 설치합니다.
프롬프트에 (test_venv2)가 표시된 상태에서 PySide6를 설치합니다.
PySide6는 Python으로 GUI 프로그램을 만들 때 사용하는 패키지로, 용량이 커서 설치에 1~2분 정도 걸릴 수 있습니다.


python -m pip install PySide6 # 현재 python(= test_venv2의 python)에 연결된 pip로 설치
여기서 pip install PySide6가 아니라 python -m pip install PySide6 형식을 사용한 이유는 3강에서 정한 그대로입니다 — 현재 실행 중인 python에 연결된 pip를 사용하기 위해서입니다. 지금 python은 test_venv2의 Python이므로(6강에서 which python으로 확인한 사실), 이 pip는 패키지를 시스템이 아니라 test_venv2 안에 설치합니다.
설치가 진행되면 다음과 비슷한 출력이 나타납니다.
Collecting PySide6
Downloading PySide6-6.x.x-...whl (...)
Installing collected packages: shiboken6, PySide6-Essentials, PySide6-Addons, PySide6
Successfully installed PySide6-6.x.x ...
PySide6 하나를 설치했는데 shiboken6 등 여러 패키지가 함께 설치되는 것이 보입니다.
PySide6가 동작하는 데 필요한 다른 패키지들, 즉 의존성(dependency)이 자동으로 함께 설치된 것입니다.
이 상태가 정상이며, 이 "함께 설치된 목록"은 10강에서 requirements.txt를 다룰 때 다시 중요해집니다.
2. 설치 위치 검증하기
→ pip show의 Location으로 패키지가 가상환경 내부에 격리되었는지 확인합니다.
2.1 pip show로 Location 확인하기
설치된 패키지의 정보를 확인합니다.

python -m pip show PySide6 # 패키지 이름, 버전, 설치 위치 출력
Name: PySide6
Version: 6.x.x
Location: /home/사용자명/Dev/Python2/test_venv2/lib/python3.13/site-packages
Requires: shiboken6, PySide6-Essentials, PySide6-Addons
가장 중요한 줄은 Location입니다. 경로를 뜯어보면 이번 강의의 결론이 그대로 들어 있습니다.
/home/사용자명/Dev/Python2/test_venv2/lib/python3.13/site-packages
───────── ─────────
가상환경 내부 Python 3.13 기준 ← 시스템 경로가 아니다!
시스템 패키지 위치(/usr/lib/python3/dist-packages)가 아니라 프로젝트 폴더 안의 가상환경 경로입니다.
즉 PySide6는 test_venv2 안에만 존재하고, 시스템 Python과 4강의 test_venv는 전혀 영향을 받지 않았습니다.
Thunar로 이 경로를 직접 열어보면 PySide6, shiboken6 폴더가 실제로 들어 있는 것을 확인할 수 있습니다 — 7강에서 배운 대로, 패키지 설치의 정체는 이 폴더에 패키지 폴더가 복사되는 것입니다.
2.2 격리 확인 — 가상환경 밖에서는 없어야 정상
격리가 정말 되었는지 반대 방향으로도 확인해 봅니다.
가상환경을 빠져나가 시스템 Python에게 PySide6가 있는지 물어봅니다.
deactivate # 가상환경 비활성화
python3 -m pip show PySide6 # 시스템 Python 기준으로 조회
WARNING: Package(s) not found: PySide6 ← 이 "실패"가 성공입니다
시스템 Python에는 PySide6가 없다고 나옵니다. 이 메시지는 오류가 아니라 격리가 성공했다는 증거입니다. 패키지는 test_venv2 안에만 설치되었고 시스템은 깨끗합니다 — 2강에서 세운 "시스템 Python은 건드리지 않는다"는 원칙이 지켜진 것입니다. 확인이 끝나면 다시 활성화해 둡니다.
source test_venv2/bin/activate # 다음 섹션을 위해 다시 활성화
✔ 확인 기준: 활성화 상태의 pip show는 test_venv2 내부 Location을 출력하고, 비활성화 상태의 pip show는 not found를 출력하면 격리 검증 완료입니다. 활성화 상태에서도 Location이 /usr/lib로 나온다면 프롬프트에 (test_venv2)가 있는지 확인하세요 — 활성화 없이 설치했다면 시스템에 설치된 것이므로 python3 -m pip uninstall PySide6로 제거 후 활성화하고 다시 설치합니다.
3. 설치한 패키지 동작 확인하기
→ import 테스트로 PySide6가 실제로 사용 가능한 상태인지 확인합니다.
설치 위치 확인까지 끝났으니 마지막으로 실제 동작을 확인합니다.
7강에서 배운 from-import로 PySide6의 핵심 요소를 가져와 봅니다.
python -c는 파일을 만들지 않고 코드 한 줄을 바로 실행하는 옵션입니다.
python -c "from PySide6.QtWidgets import QApplication; print('PySide6 동작 확인 완료')"
PySide6 동작 확인 완료
오류 없이 메시지가 출력되면 "Python 3.13 + PySide6" 조합이 test_venv2 안에 완성된 것입니다. 8강의 표현으로 말하면, 이 프로젝트의 버전 조합이 가상환경 안에 고정되었습니다.
| 환경 | Python | PySide6 |
| 시스템 Python | 기본 버전 (예: 3.12) | 없음 — 깨끗하게 유지 |
| test_venv (4강) | 기본 버전 기반 | 없음 — 영향받지 않음 |
| test_venv2 (6·9강) | 3.13 | 설치됨 — 이 프로젝트 전용 |
이 표가 시리즈 전반부의 결과물입니다. 한 컴퓨터 안에서 환경마다 서로 다른 조합이 서로 간섭 없이 공존하고 있습니다.
✔ 확인 기준: import 테스트가 "PySide6 동작 확인 완료"를 출력하면 이번 강의 완료입니다. ModuleNotFoundError: No module named 'PySide6'가 나오면 가상환경이 비활성 상태일 가능성이 큽니다 — 프롬프트의 (test_venv2)를 확인하고 다시 실행하세요.
→ 다음 강의 (10강): 이번에 완성한 조합을 다른 컴퓨터로 가져가야 한다면 어떻게 해야 할까요? test_venv2 폴더를 통째로 복사하면 될 것 같지만, 그 방식이 왜 실패하는지 — 그리고 설치된 패키지 목록만 기록하는 requirements.txt가 왜 올바른 방법인지 확인합니다.
4. 가상환경 Python 에 라이브러리를 설치하는 이유
4.1 왜 공용 Python 환경에 직접 설치하면 위험할까?

4.2 프로젝트 간 충돌이 생길 수 있음
공용 Python 환경에 이미 `특정 버전의 Python`과 `특정 버전의 PySide6` 설치된 상태에
A 프로젝트는 PySide6 6.5가 필요하고, B 프로젝트는 PySide6 6.7이 필요하다고 가정합니다.
그런데 가상환경을 사용하지 않고 공용 Python 환경에 `PySide6 6.5` 하나만 설치하면, 모든 프로젝트가 같은 `PySide6 6.3` 버전을 사용하게 됩니다.
공용 Python → PySide6 6.5 설치
A 프로젝트 → 공용 PySide6 6.5 버전 사용 (✅ 정상)
B 프로젝트 → 공용 PySide6 6.5 버전 사용 (⚠️ 6.7 버전 필요)
C 프로젝트 → 공용 PySide6 6.5 버전 사용 (⚠️ 6.6 버전 필요)
이 상태에서 B 프로젝트 때문에 PySide6 버전을 6.7 로 업그레이드하면, A 프로젝트가 갑자기 실행되지 않을 수 있습니다.
즉, 한 프로젝트의 변경이 다른 프로젝트에 영향을 주게 됩니다.
4.3 특정 버전 Python도 같은 문제 발생
추가로 설치한 python3.13이 있다고 가정해 봅시다.
하지만 가상환경 없이 아래처럼 직접 라이브러리를 설치할수는 있습니다.
python3.13 -m pip install PySide6
하지막 위 공용 Python 환경 문제와 동일하게
python3.13을 사용하는 여러 프로젝트가 같은 라이브러리를 공유하게 됩니다.
Python 3.13 → PySide6 6.5 설치
A 프로젝트 → Python 3.13의 PySide6 6.5 버전 사용 (✅ 정상)
B 프로젝트 → Python 3.13의 PySide6 6.5 버전 사용 (⚠️ 6.7 버전 필요)
C 프로젝트 → Python 3.13의 PySide6 6.5 버전 사용 (⚠️ 6.6 버전 필요)
따라서 python3.13이 기본 시스템 Python이 아니더라도, 프로젝트별 독립 관리 관점에서는 직접 설치를 권장하지 않습니다.
4.4 삭제할 때도 복잡해질 수 있음
공용 Python 환경에 설치한 패키지를 삭제하려고 다음 명령을 실행할 수 있습니다.
sudo python3.13 -m pip uninstall PySide6
하지만 시스템 경로에 여러 패키지가 섞이면, 어떤 패키지가 apt로 설치된 것인지, 어떤 패키지가 pip로 설치된 것인지 구분하기 어려워질 수 있습니다.
그래서 나중에 환경을 정리하거나 문제를 해결할 때 더 복잡해질 수 있습니다.