포터블 exe 를 실행하면 창 대신 오류창만 떴다. File "__main__.py", line 1, in <module> ImportError: attempted relative import with no known parent package PyInstaller 는 진입 스크립트를 **패키지 없이** 최상위로 실행한다 (__package__ 가 비어 있다). 그래서 src/livesub/__main__.py 첫 줄의 `from .app import main` 이 그 자리에서 죽는다. 절대 임포트로 바꾼다. `python -m livesub` 는 둘 다 동작하므로 잃는 것이 없다. 왜 못 잡았나 — exe 점검이 "8초 뒤에도 프로세스가 살아 있으면 통과" 였다. PyInstaller 오류창은 프로세스를 그대로 띄워둔 채 서 있으므로 통과로 보고됐다. 살아 있는 것은 떴다는 뜻이 아니다. 고친다: - 프로세스 생존이 아니라 **실제 창**을 본다. onefile 은 자식 프로세스가 창을 띄우므로 프로세스 트리 전체를 훑는다. - "Unhandled exception" / "Failed to execute script" 오류창을 보면 그 자리에서 실패로 판정한다. - APPDATA 를 빈 폴더로 돌려 첫 실행(저장 위치 화면)과 두 번째 실행 (본 화면)을 각각 확인한다. 둘 다 실제 창 제목으로 확인한다. - 같은 회귀를 리눅스에서도 잡도록 runpy 로 패키지 없는 실행을 재현하는 테스트를 추가한다. 되돌려보면 실제로 실패하는 것을 확인했다.
This commit is contained in:
@@ -190,3 +190,24 @@ def test_ct2_티어는_gpu_조회_없이도_통과한다():
|
||||
assert tier_availability(TIERS[key])[0]
|
||||
finally:
|
||||
mgr.detect_gpu = original
|
||||
|
||||
|
||||
def test_진입_스크립트는_패키지_없이도_임포트된다():
|
||||
"""PyInstaller 는 진입 스크립트를 **패키지 없이** 최상위로 실행한다.
|
||||
|
||||
그래서 그 파일에 상대 임포트가 하나라도 있으면 exe 가 켜지자마자
|
||||
`attempted relative import with no known parent package` 로 죽는다.
|
||||
실제로 그 상태의 exe 가 릴리스까지 나갔고, "8초 뒤에도 살아 있으면 통과"
|
||||
였던 점검은 오류창이 떠 있는 것을 정상으로 봤다.
|
||||
|
||||
`runpy.run_path` 가 바로 그 조건(패키지 문맥 없음)을 만들어준다.
|
||||
run_name 을 `__main__` 이 아닌 것으로 주면 GUI 는 뜨지 않고 임포트만 돈다.
|
||||
"""
|
||||
import runpy
|
||||
|
||||
root = SPEC.resolve().parents[1]
|
||||
entry = root / "src" / "livesub" / "__main__.py"
|
||||
# spec 이 실제로 이 파일을 진입점으로 쓰는지 확인한다. 아니면 엉뚱한 파일을
|
||||
# 지키고 있는 셈이 된다.
|
||||
assert '"livesub" / "__main__.py"' in SPEC.read_text(encoding="utf-8")
|
||||
runpy.run_path(str(entry), run_name="__livesub_frozen_probe__")
|
||||
|
||||
Reference in New Issue
Block a user