Skip to content

TeacherChae/GHtoPython

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

13 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

GHtoPython

sitecustomize.py

워크스페이스에서 커스텀으로 정의한 모듈들을 라이노 파이썬 전역 런타임에 로드시켜서

from src.utility import core

와 같이 스크립트에서 직접 불러올 수 있게 해줌.

  • 파일 삽입 위치 : C:\Users\UserName\.rhinocode\py39-rh8\Lib
  • Rhino8부터 가능...
"""
Dev auto-reloader for your in-tree packages on Rhino's shared Python.
- Watches given package prefixes and forces reload if sources changed.
- No change needed in GH scripts: keep 'from src.utility.mapper import ...'.

If 필요 패키지명/경로를 바꾸려면 PACKAGES / ROOTS 를 수정하세요.
"""
import builtins, importlib, importlib.util, os, sys
from pathlib import Path

# === 설정 ===
# 작업 트리의 루트/패키지 목록
ROOTS = [
    Path(r"C:\Users\admin\Desktop\KH\work\GHtoPython"),  # <-- src 루트
]
PACKAGES = ("src",)  # prefix 매칭

# 루트 경로를 sys.path 최우선에 올림
for root in ROOTS:
    p = str(root)
    if root.exists() and p not in sys.path:
        sys.path.insert(0, p)

# === 오토리로드 구현 ===
_mtime_cache = {}  # module_name -> last_mtime
_original_import = builtins.__import__

def _module_files_under(prefix: str):
    """sys.modules 중 prefix로 시작하는 모듈의 .__file__ 경로들을 나열."""
    for name, mod in list(sys.modules.items()):
        if not (name == prefix or name.startswith(prefix + ".")):
            continue
        path = getattr(mod, "__file__", None)
        if path and os.path.exists(path):
            yield name, path

def _package_changed(prefix: str) -> bool:
    """패키지 트리 내부에서 더 최신 mtime이 발견되면 True."""
    changed = False
    for name, path in _module_files_under(prefix):
        try:
            mtime = os.path.getmtime(path)
        except OSError:
            continue
        old = _mtime_cache.get(name)
        if old is None or mtime > old + 1e-6:  # NTFS timestamp 여유
            _mtime_cache[name] = mtime
            changed = True
    return changed

def _purge(prefix: str):
    """해당 패키지/하위 모듈을 sys.modules에서 제거(깊은 것부터)."""
    victims = [n for n in sys.modules if n == prefix or n.startswith(prefix + ".")]
    for n in sorted(victims, key=lambda s: s.count("."), reverse=True):
        sys.modules.pop(n, None)

def _dev_import(name, globals=None, locals=None, fromlist=(), level=0):
    # 원래 동작 전에 지정한 패키지들만 검사
    full = name
    if level and globals and "__package__" in globals:
        # 상대 import는 절대경로로 해석
        pkg = globals.get("__package__") or ""
        full = importlib.util.resolve_name(name, pkg)

    for prefix in PACKAGES:
        if full == prefix or full.startswith(prefix + "."):
            # 파일이 바뀌었으면 캐시 삭제 → 이후 import가 새로 로드
            if _package_changed(prefix):
                _purge(prefix)
            break

    return _original_import(name, globals, locals, fromlist, level)

# 한 번만 설치
if not getattr(sys, "_dev_autoreload_installed", False):
    builtins.__import__ = _dev_import
    sys._dev_autoreload_installed = True

About

Repository for study of converting GH components into Python scripts

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages