メトリクス選択
メトリクススイートの一部だけを計算するには 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_source と bca.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 の Display、METRIC_NAMES、JSON 出力キー)。レガシーの "exit" エイリアスは 2.0 で廃止され、現在は他の未知の名前と同様に ValueError を送出します。重複は暗黙に畳み込まれます。
| メトリクス | JSON キー | 引き込まれる依存メトリクス |
|---|---|---|
| LoC | loc | — |
| 循環的複雑度 | cyclomatic | — |
| 認知的複雑度 | cognitive | — |
| Halstead | halstead | — |
| ABC | abc | — |
nargs | nargs | — |
nom | nom | — |
npa | npa | — |
npm | npm | — |
nexits | nexits | — |
tokens | tokens | — |
| 保守容易性指数 | mi | loc, cyclomatic, halstead |
| クラスごとの重み付きメソッド数(Weighted Methods per Class) | wmc | cyclomatic, 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=の選択はフラット化された列を自然に絞り込みます。