메뉴 닫기

PySide Qt for Python 패키징 배포 onefile vs onedir PATH LD_LIBRARY_PATH 완벽 가이드

PySide Qt for Python 패키징 배포 onefile vs onedir PATH LD_LIBRARY_PATH 완벽 가이드

🚀 클릭 한 번으로 배포 끝내는 방법부터 동적 라이브러리 검색까지 실전 설정을 알기 쉽게 정리했습니다

프로젝트가 잘 돌아가는데도 exe나 앱 번들로 내보내는 순간 오류가 쏟아지는 경험, 한 번쯤 겪었을 겁니다.
특히 PySide(Qt for Python) 기반 앱은 Qt 플러그인과 동적 라이브러리 의존성이 얽혀 있어 빌드는 끝났는데 실행 시점에 파일을 못 찾는 문제가 자주 생깁니다.
혼자 끙끙거리는 대신, 배포 전략을 처음부터 깔끔하게 세우면 시간을 크게 줄일 수 있습니다.
onefile로 가볍게 묶을지, onedir로 투명하게 관리할지, 그리고 PATH나 LD_LIBRARY_PATH 같은 검색 경로를 어떻게 통제할지가 핵심입니다.
이번 글은 그런 갈림길에서 헷갈리지 않도록 실제 현장에서 통하는 기준과 체크포인트를 담았습니다.

여기서는 PySide6 애플리케이션을 중심으로 패키징과 배포의 전체 흐름을 구조적으로 정리합니다.
Qt의 플랫폼 플러그인, ICU, OpenSSL 같은 동적 의존성이 어떤 식으로 묶이고, 실행 시 로더가 어떤 경로를 우선 탐색하는지 원리를 먼저 짚습니다.
그다음 onefile과 onedir의 장단점을 실사용 관점에서 비교하고, PyInstaller·Nuitka·cx_Freeze 같은 도구에서 필요한 옵션만 골라 적용할 수 있게 정돈합니다.
운영체제별로 마주치는 오류 메시지를 유형화해 원인 추적 순서를 제안하고, 환경변수를 안전하게 설정하는 팁도 함께 묶었습니다.



🔎 onefile vs onedir 개념과 선택 기준

PySide(Qt for Python) 애플리케이션을 배포할 때 가장 먼저 결정해야 할 것은 onefile과 onedir 중 어떤 아티팩트를 만들지입니다.
두 방식 모두 최종 사용자가 실행 가능한 결과물을 제공하지만, 빌드 시간, 시작 속도, 업데이트 전략, 디버깅 난이도, 그리고 동적 라이브러리 로딩 방식에서 체감 차이가 큽니다.
핵심은 내 앱이 어떤 사용자 환경에서 쓰이며, 어떤 빈도로 업데이트되고, 실행 초기에 필요한 준비 작업이 무엇인지에 맞춰 선택하는 것입니다.

onefile은 모든 파일을 단일 실행 파일로 묶어 배포 단계를 단순화합니다.
대신 최초 실행 시 내부에 압축된 리소스를 임시 디렉터리로 풀어야 하므로 첫 실행 지연이 발생할 수 있고, 임시 경로가 보안 정책이나 백신에 의해 제약을 받을 여지도 있습니다.
반면 onedir은 실행 파일과 라이브러리, Qt 플러그인을 폴더 구조 그대로 배치합니다.
파일 수가 늘어나지만, 시작이 빠르고 문제 발생 시 특정 모듈만 교체하거나 로그로 위치를 추적하기가 수월합니다.

PySide 특성상 Qt 플랫폼 플러그인(platforms), 이미지 플러그인(imageformats), 네트워크·SSL 관련 라이브러리 등 동적 의존성이 많습니다.
onefile에서도 결국 런타임에는 이 파일들을 로더가 찾을 수 있어야 하므로, 내부 압축 해제 위치와 검색 경로 제어가 중요합니다.
onedir에서는 폴더 배치와 상대 경로 기준의 검색이 명확하게 드러나기 때문에 문제 재현과 수정이 용이합니다.
팀 협업이나 CI에서 캐시를 활용해 증분 배포를 하려면 onedir의 가시성이 이점이 됩니다.

🧭 선택 기준 요약

onefile onedir
배포가 간단하고 단일 파일 전달이 용이 폴더 구조로 가시성이 높고 문제 추적이 쉬움
최초 실행 시 압축 해제로 지연 발생 가능 파일 수 증가로 설치·복사 단계가 다소 번거로움
임시 디렉터리 권한·백신과 충돌 이슈 가능 실행 속도가 안정적이고 업데이트가 유연
로그·크래시 덤프 위치가 다소 불명확할 수 있음 특정 DLL/so 교체만으로 핫픽스 가능

🧩 PySide와 동적 라이브러리 관점

onefile을 선택하더라도 Qt 플랫폼 플러그인과 각종 DLL/so는 실행 시점에 로더가 접근 가능한 실제 경로에 존재해야 합니다.
즉, 내부 번들에서 임시 폴더로 풀린 위치가 곧 검색 루트가 되며, 여기서 PATH(Windows)와 LD_LIBRARY_PATH(Linux, macOS의 DYLD_LIBRARY_PATH 포함)의 우선순위를 어떻게 설정하느냐가 안정성에 직접 영향을 줍니다.
onedir은 배치 경로가 고정적이므로, 실행 파일 기준 상대 경로로 플러그인 디렉터리를 가리키는 패턴이 관리 측면에서 유리합니다.

  • 📦내 앱의 업데이트 주기가 짧고 모듈 교체가 잦다면 onedir을 우선 검토
  • 설치·배포 경로가 제한되고 전달이 단순해야 한다면 onefile을 고려
  • 🔍Qt 플러그인(platforms, imageformats 등) 위치와 로더 검색 경로를 미리 점검
  • 🧪백신/EDR이 임시 폴더 실행을 차단하는 환경인지 사전 테스트
  • 🗺️배포 대상 OS별 PATH, LD_LIBRARY_PATH 우선순위를 문서화

💡 TIP: 대외 배포 전 내부 품질 점검에서는 onedir로 문제 지점을 먼저 식별하고, 안정화 후 최종 사용자용 onefile을 병행 제공하면 현장 이슈 대응과 배포 편의성을 모두 확보할 수 있습니다.

⚠️ 주의: onefile에서 임시 디렉터리 위치가 바뀌면 하드코딩한 상대 경로가 깨질 수 있습니다.
실행 시 계산되는 런타임 경로를 참조하거나, 환경변수를 통해 검색 루트를 명시적으로 지정해 예측 가능성을 확보하세요.

🧩 PySide6 배포 구조와 Qt 동적 라이브러리

PySide6 (Qt for Python)를 사용하는 앱은 내부적으로 Qt의 C++ 라이브러리, 플랫폼 플러그인, 이미지 포맷 플러그인, 네트워크/SSL 모듈 등 다수의 동적 라이브러리(예: DLL, so, dylib)를 필요로 합니다.
이러한 라이브러리들은 배포 시 단순히 파이썬 패키지처럼 복사하는 것만으로 동작 보장이 되지 않습니다.
실행 시점에 OS의 동적 링커가 라이브러리를 찾는 규칙에 맞게 배치해야만 애플리케이션이 정상적으로 로드됩니다.

일반적으로 Qt 라이브러리는 다음과 같은 구조를 가집니다 (onedir 예시):

CODE BLOCK
dist/
  myapp/
    myapp.exe (or binary)
    Qt5Core.dll / libQt6Core.so / libQt6Core.dylib
    platforms/
      qwindows.dll / libqxcb.so / libqcocoa.dylib
    imageformats/
      qjpeg.dll / libqjpeg.so
    network/
      libssl.so / libcrypto.so
    ...

onedir 환경에서는 위와 같이 디렉터리 구조를 명시적으로 유지하면서, 실행 파일이 “자신의 디렉터리”를 기준으로 상대 경로로 라이브러리를 참조하는 방식이 가장 안정적입니다.
예를 들어 실행 파일이 있는 폴더를 기준으로 `platforms` 디렉터리를 찾아 `qwindows.dll` 혹은 `libqxcb.so` 등을 로드하게 유도하는 구조입니다.

onefile 방식에서는 내부 번들이 압축되어 있고 실행 시 `_MEIPASS` 같은 임시 폴더로 풀리기 때문에, 그 임시 영역이 라이브러리 검색 루트가 됩니다.
PyInstaller 부트로더는 이 동작을 고려해 런타임에 `LD_LIBRARY_PATH` (리눅스), `DYLD_LIBRARY_PATH` (macOS), 또는 Windows의 DLL 검색 경로 설정을 조작합니다.

예를 들어 리눅스에서는 부트로더가 기존 `LD_LIBRARY_PATH`를 `LD_LIBRARY_PATH_ORIG`에 보존한 뒤, 내부 풀린 폴더 경로를 `LD_LIBRARY_PATH` 앞부분에 덧붙이는 식으로 변경합니다. 이 과정으로 번들 내부에 포함된 라이브러리가 우선적으로 로드되게 할 수 있습니다.

🧱 플랫폼별 라이브러리 검색 요인 정리

  • 🪟Windows는 실행 파일 폴더 → PATH 환경변수 → SetDllDirectory 등 API 호출 순으로 DLL을 탐색합니다.
  • 🐧리눅스는 `LD_LIBRARY_PATH` → RPATH/RUNPATH → 시스템 기본 경로 순으로 .so 파일을 탐색합니다.
  • 🍎macOS는 `DYLD_LIBRARY_PATH`나 내부 번들 내부의 @rpath, @loader_path 같은 설정에 영향을 많이 받습니다.
  • 🧩Qt 플랫폼 플러그인 폴더 (platforms)이나 이미지 포맷 폴더 (imageformats)를 번들 내부에 정확히 위치시키지 않으면 `Could not find the Qt platform plugin` 등의 런타임 오류가 납니다.
  • 🔄다른 Qt DLL이 PATH 상에 존재할 경우, onefile 빌드에서 외부 DLL이 먼저 로드되는 현상이 발생할 수 있습니다.

💡 TIP: 빌드된 exe/바이너리를 실행하기 전, `ldd` (Linux) 또는 `otool -L` (macOS) 등을 이용해 동적 라이브러리 누락 여부를 사전에 점검해 두면 배포 후 헷갈리는 오류를 줄일 수 있습니다.

⚠️ 주의: onefile 모드로 묶은 실행 파일이 압축 해제되는 임시 디렉터리가 `noexec` 옵션이 설정되어 있는 파일시스템이면 라이브러리 로딩에 실패할 수 있습니다.



🧭 환경변수 PATH LD_LIBRARY_PATH 검색 순서

PySide(Qt for Python) 앱을 패키징할 때 가장 자주 마주치는 문제는 “라이브러리를 찾을 수 없습니다.”라는 런타임 오류입니다.
이는 실행 시점에 운영체제가 동적 라이브러리(DLL, SO, DYLIB)를 찾는 경로 규칙과 관련이 있습니다.
빌드 과정에서 모든 파일을 포함했더라도, OS가 올바른 순서로 해당 라이브러리를 검색하지 않으면 프로그램은 즉시 종료됩니다.

환경변수 PATH (Windows)와 LD_LIBRARY_PATH (Linux), DYLD_LIBRARY_PATH (macOS)는 이러한 검색 순서를 제어하는 핵심 요소입니다.
PyInstaller나 Nuitka 같은 빌드 도구는 내부적으로 이 값을 수정하거나, 부트로더를 통해 실행 시점에 일시적으로 우선순위를 변경해줍니다.

⚙️ 운영체제별 검색 경로 순서

운영체제 검색 순서
Windows 1. 실행 파일 디렉터리 → 2. 시스템 디렉터리 → 3. PATH 환경변수 → 4. 레지스트리
Linux 1. LD_LIBRARY_PATH → 2. RPATH/RUNPATH → 3. /lib, /usr/lib 등 시스템 디렉터리
macOS 1. DYLD_LIBRARY_PATH → 2. @rpath / @loader_path 설정 → 3. 시스템 기본 프레임워크

PySide 애플리케이션에서는 QtCore, QtGui, QtWidgets 등 핵심 DLL/so 외에도 Qt 플랫폼 플러그인이 올바른 경로에서 검색되어야 합니다.
예를 들어 Windows의 경우 platforms\qwindows.dll이, Linux의 경우 platforms/libqxcb.so가 PATH 내에서 우선적으로 탐색되지 않으면 “This application failed to start because no Qt platform plugin could be initialized” 오류가 발생합니다.

🔧 실행 시 경로 제어 방법

PyInstaller 기반 onefile 실행 환경에서는 내부 압축 해제 경로가 `_MEIPASS`라는 변수에 담기며, 다음과 같이 런타임 경로를 제어할 수 있습니다.

CODE BLOCK
import sys, os
if hasattr(sys, "_MEIPASS"):
    os.environ["QT_PLUGIN_PATH"] = os.path.join(sys._MEIPASS, "platforms")
    os.environ["PATH"] = sys._MEIPASS + ";" + os.environ["PATH"]

이렇게 하면 내부에 포함된 Qt 플러그인이 항상 우선 검색됩니다.
리눅스의 경우는 아래처럼 LD_LIBRARY_PATH를 덧붙여줄 수 있습니다.

CODE BLOCK
if "_MEIPASS" in sys.__dict__:
    os.environ["LD_LIBRARY_PATH"] = (
        sys._MEIPASS + ":" + os.environ.get("LD_LIBRARY_PATH", "")
    )

💎 핵심 포인트:
Qt 플러그인 경로를 하드코딩하지 말고, 런타임에서 실행 위치를 동적으로 계산해 환경변수를 지정하면 배포 환경이 바뀌어도 안정적으로 구동됩니다.

⚠️ 주의: Linux에서 LD_LIBRARY_PATH를 잘못 설정하면 시스템 전역 라이브러리가 오염되어 다른 프로그램 실행에 영향을 줄 수 있습니다.
앱 실행 스크립트 내부에서만 임시로 덮어쓰고, 세션이 끝나면 원래 값으로 복구하는 방식을 권장합니다.

🧰 PyInstaller Nuitka cx_Freeze 설정 비교

PySide(Qt for Python) 앱을 배포할 때 가장 널리 쓰이는 도구는 PyInstaller, Nuitka, 그리고 cx_Freeze입니다.
모두 파이썬 스크립트를 실행 가능한 바이너리로 변환해 주지만, 내부 작동 방식과 결과물의 구조, 실행 효율성, 빌드 옵션 지원 범위가 다릅니다.
특히 PySide를 사용할 경우 Qt의 복잡한 동적 링크 구조를 지원하는 세부 설정이 중요합니다.

🧩 PyInstaller

PyInstaller는 가장 직관적이고 범용적으로 쓰이는 빌드 도구입니다.
PySide6 공식 문서에서도 기본 예제로 PyInstaller를 권장합니다.
다음은 대표적인 onedir/onefile 설정 예시입니다.

CODE BLOCK
pyinstaller main.py --noconfirm --noconsole ^
    --name MyApp ^
    --add-data "C:\Python\Lib\site-packages\PySide6\plugins;PySide6\plugins" ^
    --onefile

PyInstaller의 강점은 hook 시스템을 통해 Qt 플러그인 경로를 자동 감지해 포함할 수 있다는 점입니다.
단점은 부트로더 기반 압축으로 인해 onefile 모드에서 초기 실행이 다소 느리고, 안티바이러스 오탐지 확률이 높다는 것입니다.

⚡ Nuitka

Nuitka는 파이썬 코드를 C/C++로 변환해 컴파일하는 방식으로 동작합니다.
PySide6의 복잡한 바이너리 의존성에도 불구하고, Nuitka는 실제 C 코드로 변환된 결과를 통해 성능 향상과 메모리 관리 최적화를 제공합니다.
빌드 시 –standalone 옵션을 사용하면 onedir 구조로 생성됩니다.

CODE BLOCK
python -m nuitka --standalone --enable-plugin=pyside6 ^
    --include-qt-plugins=sensible,qml,platforms ^
    --output-dir=build main.py

Nuitka는 런타임 부트로더를 사용하지 않기 때문에 실행 속도가 빠르며, 외부 백신 오탐 문제도 적습니다.
다만 빌드 시간이 길고, 일부 경로 관련 환경변수 설정은 수동으로 해주어야 할 수 있습니다.

🧮 cx_Freeze

cx_Freeze는 비교적 단순하지만 안정적인 구조의 빌드 도구입니다.
PySide6와도 호환성이 개선되었으며, setup.py를 기반으로 파이썬 배포자 관점에서 직관적인 빌드 구성을 제공합니다.

CODE BLOCK
from cx_Freeze import setup, Executable

setup(
    name="MyApp",
    version="1.0",
    options={
        "build_exe": {
            "packages": ["PySide6"],
            "include_files": ["./PySide6/plugins/platforms/"]
        }
    },
    executables=[Executable("main.py")]
)

cx_Freeze는 onedir 형태의 결과물을 기본적으로 생성하며, 단일 실행 파일(onefile) 압축 기능은 지원하지 않습니다.
그러나 디버깅이 간단하고, Python 3.12 이후 버전과의 호환성도 빠르게 개선되고 있어 유지보수 중심의 프로젝트에 적합합니다.

💎 핵심 포인트:
PyInstaller는 간편한 통합 빌드, Nuitka는 성능 중심, cx_Freeze는 안정적 유지보수에 적합합니다. 프로젝트의 우선순위(속도·편의·안정성)에 따라 선택을 달리해야 합니다.

⚠️ 주의: 빌드 후 결과물에서 Qt 라이브러리가 누락되면 대부분의 경우 “platform plugin not found” 오류가 납니다. 빌드 로그에서 플러그인 경로가 올바르게 포함되었는지 반드시 확인하세요.



🛡️ 플랫폼별 오류 해결 체크리스트

PySide(Qt for Python) 앱을 패키징하고 실행할 때 가장 흔하게 나타나는 문제는 “Qt 플랫폼 플러그인을 찾을 수 없습니다” 오류와 “DLL/so 파일을 로드할 수 없습니다” 같은 라이브러리 관련 오류입니다.
이러한 문제는 대부분 빌드가 아닌 실행 환경의 경로 설정 문제이며, OS별 진단 순서와 해결 방법을 알고 있으면 빠르게 복구할 수 있습니다.

🪟 Windows 환경

  • 🔍빌드 후 실행 시 platforms\qwindows.dll이 존재하는지 확인
  • 🧩환경변수 PATH에 Qt DLL이 포함된 디렉터리가 누락되지 않았는지 확인
  • 💡Dependency Walker 또는 lucasg/Dependencies 도구로 누락된 DLL 확인
  • ⚙️PyInstaller onefile 모드에서는 _MEIPASS 내부 경로를 로그로 출력해 확인

🐧 Linux 환경

  • 🧭 실행 파일이 참조하는 라이브러리를 ldd ./MyApp 명령으로 점검
  • 🔒 LD_LIBRARY_PATH 설정 시 시스템 라이브러리를 덮어쓰지 않도록 주의
  • 🧱 Qt 플랫폼 플러그인 경로를 수동으로 지정할 때는 다음처럼 설정
    CODE BLOCK
    export QT_QPA_PLATFORM_PLUGIN_PATH=$PWD/platforms
    

  • 📦 배포 시 AppImageFlatpak으로 감싸면 의존성 충돌 위험을 줄일 수 있음

🍎 macOS 환경

  • 🔍 otool -L MyApp.app/Contents/MacOS/MyApp으로 동적 링크 확인
  • 🧭 install_name_tool -add_rpath 명령으로 @rpath 경로 수정 가능
  • ⚙️ 앱 번들 내부의 Contents/FrameworksContents/PlugIns 구조를 정확히 유지
  • 🔐 macOS 14 이상에서는 서명되지 않은 dylib이 로드되지 않을 수 있으므로 codesign --deep --force --sign - MyApp.app 명령으로 임시 서명 필요

💎 핵심 포인트:
플랫폼별 오류의 대부분은 “경로 문제”에서 시작됩니다. 빌드 이전에 플러그인 폴더 구조와 환경변수의 우선순위를 명확히 점검하면 문제의 80%는 예방할 수 있습니다.

⚠️ 주의: PATH 또는 LD_LIBRARY_PATH를 전역으로 수정한 상태에서 테스트하면 다른 Python 환경까지 영향을 줄 수 있습니다. 항상 가상환경(venv)에서 빌드와 테스트를 진행하세요.

자주 묻는 질문 (FAQ)

PyInstaller로 만든 onefile이 실행되지 않습니다. 왜 그런가요?
첫 실행 시 내부 압축 파일이 임시 폴더로 풀리는데, 해당 경로에 실행 권한이 없거나 보안 소프트웨어가 차단하는 경우 실행이 실패할 수 있습니다.
임시 경로가 noexec 옵션으로 마운트되어 있는지도 확인하세요.
onedir로 빌드했는데 다른 PC에서 실행 시 DLL 오류가 납니다.
Qt 라이브러리와 플랫폼 플러그인 폴더가 누락된 경우입니다.
특히 platforms/qwindows.dll 또는 libqxcb.so 파일이 함께 배포되어야 합니다.
LD_LIBRARY_PATH를 설정했는데도 라이브러리를 못 찾습니다.
런타임 환경에서 PyInstaller 부트로더가 LD_LIBRARY_PATH를 덮어쓸 수 있습니다.
실행 스크립트에서 export LD_LIBRARY_PATH=$PWD:$LD_LIBRARY_PATH 형태로 재정의해 주세요.
Qt 플랫폼 플러그인 오류가 반복적으로 발생합니다.
QT_QPA_PLATFORM_PLUGIN_PATH 환경변수가 올바르게 설정되지 않은 경우입니다.
PyInstaller에서는 sys._MEIPASS 기준으로 plugins 경로를 지정해주는 것이 가장 확실합니다.
PySide6 앱을 Nuitka로 빌드하면 플러그인이 누락됩니다.
Nuitka에서는 --include-qt-plugins=all 또는 필요한 플러그인만 명시해야 합니다.
자동 탐지는 한정적이므로 platforms, imageformats 등은 직접 지정하는 것이 좋습니다.
Windows에서 onedir 배포 시 PATH 충돌이 납니다.
동일한 Qt DLL이 다른 앱 또는 시스템 PATH 상에 존재하면 충돌할 수 있습니다.
실행 스크립트에서 PATH를 일시적으로 조정하거나 독립 폴더에서 실행하는 것이 안전합니다.
macOS에서 .app 번들이 열리지 않습니다.
macOS는 서명되지 않은 실행 파일이나 dylib 로드를 차단합니다.
codesign --deep --force --sign - MyApp.app 명령으로 임시 서명 후 테스트하세요.
onefile과 onedir 중 어떤 방식을 최종 배포에 추천하나요?
일반 사용자에게 단일 파일 전달이 목적이라면 onefile이 편리합니다.
그러나 유지보수와 디버깅이 필요한 내부 배포용이라면 onedir이 훨씬 안정적입니다.
실제 프로젝트에서는 두 가지를 병행해 제공하는 사례가 많습니다.

📦 PySide 배포의 핵심 요약과 실무 팁

PySide(Qt for Python) 애플리케이션을 실제 환경에 배포할 때는 단순히 빌드 명령을 실행하는 것보다, 실행 시점의 라이브러리 검색 구조를 이해하는 것이 훨씬 중요합니다.
onefile과 onedir은 단순한 포맷 차이가 아니라, 동적 라이브러리의 로딩 방식과 오류 복구 절차에 실질적인 영향을 줍니다.
특히 Qt 플랫폼 플러그인(platforms)과 환경변수(PATH, LD_LIBRARY_PATH)는 실행 성공 여부를 결정짓는 핵심 변수입니다.

요약하자면, 빌드 도구는 PyInstaller, Nuitka, cx_Freeze 중 어떤 것을 선택해도 무방하나, 배포 대상과 운영체제, 업데이트 빈도에 따라 전략이 달라져야 합니다.
개발 및 디버깅 단계에서는 onedir로 구조를 투명하게 유지하고, 사용자 배포 시에는 onefile을 병행 제공하면 이상적인 밸런스를 얻을 수 있습니다.
또한 실행 전 환경변수를 동적으로 설정하도록 코드를 삽입하면, 시스템 PATH 충돌 문제를 예방할 수 있습니다.

마지막으로, 배포 후 발생하는 대부분의 오류는 빌드 자체의 문제보다는 실행 환경의 차이에서 비롯됩니다.
동적 로딩 경로, OS별 라이브러리 캐시, 권한 제한 등을 꼼꼼히 점검하면 “Qt platform plugin not found” 같은 악명 높은 오류를 손쉽게 방지할 수 있습니다.
이 글을 참고해 한 번만 구조를 제대로 잡아두면, 이후 프로젝트에서도 동일한 빌드 템플릿을 재활용할 수 있을 것입니다.


🏷️ 관련 태그 : PySide6, Qt for Python, PyInstaller, Nuitka, cx_Freeze, onefile, onedir, LD_LIBRARY_PATH, PATH, Qt플러그인오류, 파이썬배포