メトリクス選択

メトリクススイートの一部だけを計算するには metrics=[…] を渡します。metrics=None(デフォルト)は「すべて計算する」挙動を維持します。要求されなかったメトリクスは結果の dict から 欠落 します(None のプレースホルダーとして存在するのではありません)。

def run(path: Path) -> FuncSpaceDict:
    """Compute only LoC + cyclomatic for ``path`` and return the result.

    ``bca.METRIC_NAMES`` is a ``tuple[MetricName, ...]`` of canonical
    names accepted by ``metrics=``; its ``StrEnum`` members are
    ``str``-comparable, so ``"halstead" in bca.METRIC_NAMES`` works — an
    ABI smoke check the catalog is populated, not a test of the selection.
    """
    if "halstead" not in bca.METRIC_NAMES:
        msg = "halstead is missing from METRIC_NAMES — bindings ABI drift"
        raise RuntimeError(msg)
    selected = bca.analyze(path, metrics=["loc", "cyclomatic"])
    if selected is None:
        msg = f"{path} was skipped (looks generated)"
        raise SystemExit(msg)

    metric_keys = sorted(selected["metrics"])
    print(f"computed only: {metric_keys}")
    return selected


def run_derived(path: Path) -> FuncSpaceDict:
    """Selecting ``mi`` auto-pulls in its three dependencies."""
    selected = bca.analyze(path, metrics=["mi"])
    if selected is None:
        msg = f"{path} was skipped (looks generated)"
        raise SystemExit(msg)

    pulled = sorted(selected["metrics"])
    print(f"mi pulled in: {pulled}")
    return selected

同じキーワード引数は bca.analyze_sourcebca.analyze_batch でも有効です — 後者はバッチ内のすべてのファイルに選択を一様に適用します。バリデーションはファイル I/O の 「前に」 実行されます。空のリストや未知の名前は即座に ValueError を送出し、実際には呼び出し側のバグであるものに対して AnalysisFailure スロットを返すことはありません。

正規名

全メトリクスの集合は MetricName メンバーのタプルとして利用できます。各メンバーは StrEnum なので、それ自体が str です — "halstead" in bca.METRIC_NAMES は動作し、bca.MetricName.HALSTEAD == "halstead"True になります。metrics= には素の文字列とメンバーのどちらも渡せます。

import big_code_analysis as bca
from big_code_analysis import MetricName

assert "halstead" in bca.METRIC_NAMES
assert bca.MetricName.HALSTEAD == "halstead"

# どちらの表記でも `metrics=` に渡せます:
selection = [MetricName.CYCLOMATIC, "cognitive"]

これらのメンバーは、CLI と JSON 出力が使うのと同じ Metric テーブルから生成されるため、その値が bca metrics --format json で目にするスラッグから乖離することはありません。

名前は小文字で、大文字小文字を区別します。未知の名前を渡すと、正規の一覧をメッセージに含む ValueError が送出されます。終了点メトリクスの正規表記は、あらゆる場所で "nexits" です(enum の DisplayMETRIC_NAMES、JSON 出力キー)。レガシーの "exit" エイリアスは 2.0 で廃止され、現在は他の未知の名前と同様に ValueError を送出します。重複は暗黙に畳み込まれます。

メトリクスJSON キー引き込まれる依存メトリクス
LoCloc
循環的複雑度cyclomatic
認知的複雑度cognitive
Halsteadhalstead
ABCabc
nargsnargs
nomnom
npanpa
npmnpm
nexitsnexits
tokenstokens
保守容易性指数miloc, cyclomatic, halstead
クラスごとの重み付きメソッド数(Weighted Methods per Class)wmccyclomatic, nom

パフォーマンスのトレードオフ

全メトリクスの計算がデフォルトなのは、それが CLI の動作と同じだからです。単一のメトリクスだけを選択すると、対応する compute パスがスキップされるため確実に速くなりますが、ほとんどの入力では tree-sitter のパースと AST の走査がコストの大半を占めるため、単一ファイルでの節約はわずかです。効果はバッチサイズに応じて大きくなります。analyze_batch を大規模なリポジトリ全体に対して実行する場合、不要かつ最も高価なメトリクス(深い呼び出しツリーでは多くの場合 Halstead)を外すことは測定可能な効果をもたらします。

要求しなかったメトリクスは結果に含まれません。無条件に result["metrics"]["mi"] へアクセスするコードは、mi を外した場合に KeyError になります。if "mi" in result["metrics"] でガードするか、.get("mi") を使ってください。

関連項目

  • バッチ処理metrics= はバッチ内のすべてのファイルに一律に適用されます。検証は入力の反復処理が始まる前に一度だけ実行されます。
  • SARIF 出力 — しきい値の名前は metrics= の選択とは独立しています。metrics=["loc"] を要求しつつ cyclomatic のしきい値でゲートすることもできますが、外したメトリクスについては SARIF に検出結果が含まれません。
  • フラットレコードの反復処理flatten_spaces は、元の dict に存在しないメトリクスのキーを黙って出力しないため、metrics= の選択はフラット化された列を自然に絞り込みます。