mcpField
L
lazy-import-refactor

lazy-import-refactor

github.com/nextaltair開発053 回インストール4 週間前に更新
リポジトリ

lazy-import-refactor について

Pythonプロジェクトで torch や TensorFlow などの重いネイティブ依存を、モジュールレベルから関数内の遅延インポートへ移すスキルです。テストの修正、CI相当の検証、リポジトリ間のPR順序も扱います。

主な機能

  1. 01モジュールレベルの重い依存インポートを検出
  2. 02実行時インポートを関数内へ移動
  3. 03モジュール属性へのテストパッチに対応
  4. 04サブプロセスで遅延インポートを検証
  5. 05CIと同じ完全なフィルターでローカルテスト

活用シーン

  1. 01インポート時に発生する SIGSEGV の調査
  2. 02重い依存を必要としない利用者のインポート負担軽減
  3. 03遅延インポート変更の回帰テスト追加
  4. 04ライブラリと下流プロジェクトのPR順序調整

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/nextaltair/altairs-agent-dev-kit --skill lazy-import-refactor

インストール後、Claude Code で/lazy-import-refactorを入力して読み込まれたか確認します。

同梱ファイルtest-side-effects.md

詳細

プロジェクトの README より

Lazy Import Refactor

Module-level import torch / import tensorflow 等 heavy native dependency を function-internal lazy import に移行するための手順 + test 副作用予測 + CI-equivalent 検証要件。

When to Use

  • import <library> 単体で SIGSEGV (CUDA driver 不在 + triton C-ext segfault 等)
  • 起動時間短縮のため重い import を遅延させたい
  • WebAPI 専用利用者に heavy native dep を不要にしたい
  • 上流 lib の lazy import 化を下流プロジェクトから依頼する設計検討

該当した実例: Linux + triton + CUDA driver 不在で import <ML ライブラリ> が SIGSEGV → torch / transformers の module-level import 排除で恒久解消したケースがある

Step 1: Pre-flight grep — 影響範囲完全洗い出し

Module-level import 全件 (col 0 のみ):

find src -name "*.py" | while read f; do
  awk -v fn="$f" '/^(import torch|from torch|import torchvision|from torchvision|import tensorflow|from tensorflow)/{print fn":"NR":"$0}' "$f"
done

テスト側の module attribute patch 全件:

find tests -name "*.py" | while read f; do
  awk -v fn="$f" '/@patch.*\.(torch|tensorflow|jax)|patch\.object.*\.(torch|tensorflow|jax)/{print fn":"NR":"$0}' "$f"
done

Module-level import を関数内に移すと、その module の module.torch 属性が消滅する。test 側で @patch("path.to.module.torch") を使用している箇所は全件 AttributeError で壊れる ため、事前 grep が必須。

Step 2: Refactor パターン

# Before (module-level)
import torch

class Foo:
    def bar(self, x: torch.Tensor) -> torch.Tensor:
        with torch.no_grad():
            ...

# After (TYPE_CHECKING + function-internal)
from __future__ import annotations

from typing import TYPE_CHECKING

if TYPE_CHECKING:
    import torch


class Foo:
    def bar(self, x: torch.Tensor) -> torch.Tensor:
        import torch  # lazy load
        with torch.no_grad():
            ...

必須事項:

  • from __future__ import annotations を冒頭に追加 (型ヒントを文字列化、runtime evaluation 回避)
  • runtime で使う関数の冒頭で import torch を再宣言
  • module-level の bare import torch は削除

Step 3: Test 副作用対応

# Before
@patch("your_package.core.heavy_deps.torch")
def test_foo(mock_torch):
    ...

# After
def test_foo(monkeypatch):
    import sys
    from unittest.mock import MagicMock
    mock_torch = MagicMock()
    monkeypatch.setitem(sys.modules, "torch", mock_torch)
    ...

詳細パターン (context manager mock, cuda.is_available, getattr-based access 等) は test-side-effects.md 参照。

Step 4: Verification — CI-equivalent filter で必ず検証

プロジェクトの testing ルール(例: rules/testing.md の "CI-equivalent filter で local 検証する" セクション)を参照。

-m unit 等の短縮 filter では検証不充分 (本 SKILL の存在理由 — サブモジュール側の marker 差分が短縮 filter では再現できず下流 CI で初検出された実例がある)。CI workflow の filter を完全一致で local 実行する。

モノレポ内の独立パッケージ (submodule 等) の場合:

cd <package-path>
uv run pytest -m "not downloads_and_runs_model and not calls_real_webapi"

Step 5: Cross-repo PR 順序

submodule で利用される lib の場合:

  1. lib 側で fix + CI-equivalent test pass を確認
  2. lib 側 PR 起票 → merge 待ち
  3. merge 後、下流プロジェクトで submodule pin 更新 PR 起票

順序を逆にすると下流 CI で初検出され、hot-fix PR 連鎖が必要になる。

gh pr create 実行時、kit の submodule pre-PR check hook (hook_pre_pr_submodule_check.py) が導入されていれば、submodule 変更を含む PR で CI-equivalent test 実行確認を要求する (bypass は CI-EQUIV-TESTED marker comment)。

Anti-patterns

  • module-level の上位 lib import: from transformers.models.clip import CLIPProcessor は transformers が torch を eager load するため lazy 化が必要。直接 import torch でなくても heavy native dep を引き連れる import は全て対象
  • TYPE_CHECKING 内のみで対応: cast(<heavy_lib>.Type, ...) や isinstance(x, <heavy_lib>.Type) のような runtime 評価が必要な箇所では完全には escape できない → from __future__ import annotations で型ヒントの string 化と、関数内 import の両方を必須とする
  • subprocess regression test の欠落: lazy import 化が効いているか検証する test を同 PR で追加する。fresh interpreter での import <lib>; assert 'torch' not in sys.modules パターンを推奨 (subprocess 経由で session 汚染を回避)
  • -m unit での local 検証: CI が独立 marker (standard 等) を使う場合、必ず CI 設定の filter で検証する

コメント