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:
99
fix_bpy_import.py
Normal file
99
fix_bpy_import.py
Normal file
@@ -0,0 +1,99 @@
|
||||
"""fix_bpy_import.py — scanvas_maker.py 의 bpy import 오류 핫픽스.
|
||||
|
||||
증상:
|
||||
[모듈 없음] Blender 렌더 모듈을 찾을 수 없습니다: No module named 'bpy'
|
||||
|
||||
원인:
|
||||
apply_blender_patch.py v1 의 P1 콜백 안에서 dump_params_to_json 을
|
||||
gate_3d_builder_bpy 에서 import 하도록 되어 있는데, 이 모듈은 첫 줄에
|
||||
`import bpy` 가 있어 S-CANVAS conda env(GUI 측)에서는 import 불가.
|
||||
|
||||
수정:
|
||||
동일 함수의 bpy-무의존 버전인 params_to_json.dump_dataclass_to_json 으로 교체.
|
||||
(params_to_json.py 는 이미 D:\\에 있음)
|
||||
|
||||
이 스크립트는 idempotent: 이미 수정돼있으면 변경 없음.
|
||||
백업: 실행 전 scanvas_maker.py.bak_bpyfix 자동 생성.
|
||||
|
||||
사용법:
|
||||
cd D:\\2026\\PROGRAM\\1_S-CANVAS
|
||||
python fix_bpy_import.py
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import ast
|
||||
import shutil
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
TARGET = Path("scanvas_maker.py")
|
||||
BACKUP = Path("scanvas_maker.py.bak_bpyfix")
|
||||
|
||||
|
||||
# 정확한 한 줄을 교체 (CRLF/LF 무관 — bytes로 처리)
|
||||
OLD_LINE = b"from gate_3d_builder_bpy import dump_params_to_json as _dump_gate"
|
||||
NEW_LINE = b"from params_to_json import dump_dataclass_to_json as _dump_gate"
|
||||
|
||||
|
||||
def main():
|
||||
if not TARGET.is_file():
|
||||
sys.exit(f"[ERR] {TARGET} 가 현재 폴더에 없습니다. "
|
||||
f"D:\\2026\\PROGRAM\\1_S-CANVAS 에서 실행하세요.")
|
||||
|
||||
raw = TARGET.read_bytes()
|
||||
print(f"파일: {TARGET} ({len(raw):,} bytes)")
|
||||
|
||||
if NEW_LINE in raw:
|
||||
print("\n→ 이미 수정됨. 추가 작업 없음.")
|
||||
# 그래도 import 실제로 동작하는지 확인
|
||||
if not Path("params_to_json.py").is_file():
|
||||
print("\n ⚠ 경고: params_to_json.py 가 현재 폴더에 없습니다.")
|
||||
print(" S-CANVAS 폴더에 이 모듈이 있어야 import 가 성공합니다.")
|
||||
return 0
|
||||
|
||||
if OLD_LINE not in raw:
|
||||
print("\n[INFO] OLD 패턴을 찾지 못했습니다.")
|
||||
print(" apply_blender_patch.py 를 먼저 실행했는지 확인하세요.")
|
||||
# 진단 — 어떤 import가 있는지
|
||||
for keyword in [b"gate_3d_builder_bpy", b"_dump_gate", b"dump_params_to_json"]:
|
||||
n = raw.count(keyword)
|
||||
print(f" '{keyword.decode()}' 발생: {n}회")
|
||||
sys.exit(1)
|
||||
|
||||
# params_to_json.py 가 실제로 있는지 미리 확인
|
||||
if not Path("params_to_json.py").is_file():
|
||||
sys.exit("[ERR] params_to_json.py 가 현재 폴더에 없습니다. "
|
||||
"이 모듈이 import 대상입니다.")
|
||||
|
||||
# 단일 라인 치환
|
||||
new_raw = raw.replace(OLD_LINE, NEW_LINE, 1)
|
||||
n_replaced = raw.count(OLD_LINE) - new_raw.count(OLD_LINE)
|
||||
print(f" 교체 라인 수: {n_replaced}")
|
||||
|
||||
# AST parse 검증 (utf-8 디코드 후)
|
||||
try:
|
||||
text = new_raw.decode("utf-8")
|
||||
# CRLF면 그대로, AST는 양쪽 다 받음
|
||||
ast.parse(text)
|
||||
print(f" AST parse: OK ({len(text.splitlines()):,} lines)")
|
||||
except SyntaxError as e:
|
||||
sys.exit(f"\n[ERR] 수정 후 syntax error: {e}\n파일 변경 안 함.")
|
||||
|
||||
# 백업
|
||||
shutil.copy2(TARGET, BACKUP)
|
||||
print(f"\n 백업: {BACKUP}")
|
||||
|
||||
# 저장
|
||||
TARGET.write_bytes(new_raw)
|
||||
print(f"\n✓ 핫픽스 적용 완료: {TARGET} ({len(new_raw):,} bytes)")
|
||||
print("\n변경 내용:")
|
||||
print(f" - {OLD_LINE.decode()}")
|
||||
print(f" + {NEW_LINE.decode()}")
|
||||
print("\n다음 단계:")
|
||||
print(" 1) S-CANVAS 재시작 (또는 그냥 다이얼로그를 다시 열어 다시 시도)")
|
||||
print(" 2) '🎨 Blender 렌더' 버튼 클릭")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(main() or 0)
|
||||
Reference in New Issue
Block a user