Import S-CANVAS source + iter=1~7 lint cleanup
S-CANVAS (Saman Corp.) — DXF + DEM + AI 기반 3D 조감도 생성 엔진. ~24k LOC Python (scanvas_maker.py 7072 LOC GUI + 구조물 파서/빌더 다수). 이 커밋은 7-iter cleanup이 적용된 상태로 import: - F821 8 + B023 6: 비동기 lambda + except/loop 변수 캡처 NameError (Py3.13에서 reproduce 확인된 진짜 버그) - RUF012 4 + RUF013 1: ClassVar / implicit Optional 명시화 - F811/B905/B904/F401/F841/W293/F541/UP/SIM/RUF/PLR 700+ cleanup/modernization 신규 파일: - ruff.toml: target=py313, Korean unicode/저자 스타일/도메인 복잡도 무력화 - requirements-py313.txt: pyproj>=3.7, scipy>=1.14, numpy>=2.0.2 (Py3.13 wheel) - .gitignore: gcp-key.json, 캐시, 백업, 생성 이미지 제외 검증: ruff 0 errors, py_compile 0 errors, import 33/33 OK on Py3.13.13. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
137
scanvas_maker.spec
Normal file
137
scanvas_maker.spec
Normal file
@@ -0,0 +1,137 @@
|
||||
# -*- mode: python ; coding: utf-8 -*-
|
||||
"""S-CANVAS PyInstaller spec — onedir 배포 빌드 설정.
|
||||
|
||||
빌드:
|
||||
pyinstaller --clean scanvas_maker.spec
|
||||
|
||||
결과:
|
||||
dist/S-CANVAS/ ← 통째로 zip 해서 배포
|
||||
S-CANVAS.exe ← 더블클릭 진입점
|
||||
Design/, prompt_templates/, structure_types/
|
||||
_internal/ ← Python 런타임 + 의존 라이브러리
|
||||
...
|
||||
|
||||
런타임 데이터(DB·로그·캐시):
|
||||
%LOCALAPPDATA%\\S-CANVAS\\ ← 사용자별 분리, 설치 폴더 쓰기 권한 불필요
|
||||
"""
|
||||
from PyInstaller.utils.hooks import collect_all, collect_submodules
|
||||
from pathlib import Path
|
||||
|
||||
block_cipher = None
|
||||
PROJECT_DIR = Path(SPECPATH).resolve()
|
||||
|
||||
|
||||
# ────────────────────── 자산 번들링 ──────────────────────
|
||||
# (소스경로, 번들 내 상대경로) — 런타임에서 sys._MEIPASS 아래에 같은 트리로 추출됨.
|
||||
datas = [
|
||||
(str(PROJECT_DIR / "Design"), "Design"),
|
||||
(str(PROJECT_DIR / "prompt_templates"), "prompt_templates"),
|
||||
(str(PROJECT_DIR / "structure_types"), "structure_types"),
|
||||
]
|
||||
|
||||
# ────────────────────── 거대 패키지 collect_all ──────────────────────
|
||||
# pyvista/vtk: PyInstaller 자동 감지 부분이 거나 → 명시적 collect_all 로 누락 방지.
|
||||
# pyproj: PROJ 데이터(proj.db) 자동 누락 빈번 → collect_all 로 datas/binaries 모두 집어 옴.
|
||||
binaries = []
|
||||
hiddenimports = []
|
||||
for pkg in [
|
||||
"pyvista",
|
||||
"vtkmodules",
|
||||
"pyproj",
|
||||
"ezdxf",
|
||||
"tkintermapview",
|
||||
"structlog",
|
||||
"customtkinter",
|
||||
"PIL",
|
||||
]:
|
||||
try:
|
||||
_d, _b, _h = collect_all(pkg)
|
||||
datas += _d
|
||||
binaries += _b
|
||||
hiddenimports += _h
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
# google-genai 의 서브모듈은 collect_all 로 충분히 커버되지 않을 때가 있어 별도 추가
|
||||
hiddenimports += collect_submodules("google.genai")
|
||||
hiddenimports += [
|
||||
"sqlalchemy.dialects.sqlite",
|
||||
"sqlalchemy.dialects.sqlite.pysqlite",
|
||||
"sqlalchemy.ext.declarative",
|
||||
"scipy.spatial.transform._rotation_groups",
|
||||
"scipy.special.cython_special",
|
||||
"encodings.idna",
|
||||
]
|
||||
|
||||
# ────────────────────── 분석 단계 ──────────────────────
|
||||
a = Analysis(
|
||||
["scanvas_maker.py"],
|
||||
pathex=[str(PROJECT_DIR)],
|
||||
binaries=binaries,
|
||||
datas=datas,
|
||||
hiddenimports=hiddenimports,
|
||||
hookspath=[],
|
||||
hooksconfig={},
|
||||
runtime_hooks=[],
|
||||
# 번들 크기 절감: 불필요한 거대 패키지 제외
|
||||
excludes=[
|
||||
"pytest",
|
||||
"IPython",
|
||||
"jupyter",
|
||||
"notebook",
|
||||
"tornado",
|
||||
"zmq",
|
||||
"matplotlib.tests",
|
||||
"numpy.tests",
|
||||
"scipy.tests",
|
||||
"pyvista.examples", # 거대 샘플 데이터 제외
|
||||
"vtkmodules.test",
|
||||
],
|
||||
win_no_prefer_redirects=False,
|
||||
win_private_assemblies=False,
|
||||
cipher=block_cipher,
|
||||
noarchive=False,
|
||||
)
|
||||
pyz = PYZ(a.pure, a.zipped_data, cipher=block_cipher)
|
||||
|
||||
# ────────────────────── 실행파일 ──────────────────────
|
||||
# 아이콘: 빌드 전 build.bat 가 cache/icons/scanvas_S.ico 를 생성. 없으면 None 폴백.
|
||||
_icon_path = PROJECT_DIR / "cache" / "icons" / "scanvas_S.ico"
|
||||
_exe_icon = str(_icon_path) if _icon_path.exists() else None
|
||||
|
||||
exe = EXE(
|
||||
pyz,
|
||||
a.scripts,
|
||||
[],
|
||||
exclude_binaries=True,
|
||||
name="S-CANVAS",
|
||||
debug=False,
|
||||
bootloader_ignore_signals=False,
|
||||
strip=False,
|
||||
upx=True, # UPX 가 PATH 에 있으면 압축. 없어도 빌드 진행.
|
||||
upx_exclude=[
|
||||
"vcruntime140.dll",
|
||||
"python311.dll",
|
||||
"python312.dll",
|
||||
"VCRUNTIME140.dll",
|
||||
],
|
||||
console=False, # GUI 앱 — 콘솔 창 안 띄움
|
||||
disable_windowed_traceback=False,
|
||||
argv_emulation=False,
|
||||
target_arch=None,
|
||||
codesign_identity=None,
|
||||
entitlements_file=None,
|
||||
icon=_exe_icon,
|
||||
)
|
||||
|
||||
# ────────────────────── onedir 패키지 ──────────────────────
|
||||
coll = COLLECT(
|
||||
exe,
|
||||
a.binaries,
|
||||
a.zipfiles,
|
||||
a.datas,
|
||||
strip=False,
|
||||
upx=True,
|
||||
upx_exclude=[],
|
||||
name="S-CANVAS",
|
||||
)
|
||||
Reference in New Issue
Block a user