Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

メトリクス選択

Pass metrics=[…] to compute only a subset of the metric suite. metrics=None (the default) computes everything. Unrequested metrics are absent from the result dict, not present with None placeholders. This page is for a caller who wants fewer metrics, either to save time on a large batch or to narrow the output.

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 and bca.analyze_batch honour the same kwarg; the batch applies the selection uniformly to every file. Validation runs before any file I/O: an empty list or unknown name raises ValueError immediately and never returns an AnalysisFailure slot for what is really a caller bug.

正規名

The full set is available as a tuple of MetricName members. Each member is a StrEnum, so it is a str: "halstead" in bca.METRIC_NAMES works, and bca.MetricName.HALSTEAD == "halstead" is True. Pass either a plain string or a member to 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 で目にするスラッグから乖離することはありません。

Accepted names

metrics= takes every name bca metrics --metrics takes, so a name copied from bca list-metrics or from a bca check --threshold limit works unchanged:

SpellingExampleSelects
Family name, from METRIC_NAMES"loc", "cyclomatic"that family
bca list-metrics row name"sloc", "dloc"the family that owns the row, loc
Dotted threshold id"cyclomatic.modified", "mi.original"that id’s family

Selection works per family, because the walk computes whole families: metrics=["dloc"] returns the full loc block, sloc and all, exactly as metrics=["loc"] does. METRIC_NAMES lists only the family names, which are also the JSON keys, so name in bca.METRIC_NAMES does not tell you whether metrics= accepts name.

Names are case-sensitive lowercase. An unknown name raises ValueError naming the closest accepted names, then listing every family and row name, as the CLI does:

ValueError: unknown metric: dlocc; did you mean `dloc`?; known metrics: abc, blank, cloc, …

The canonical spelling for the exit-point metric is "nexits" everywhere (the enum Display, METRIC_NAMES, and the JSON output key). The legacy "exit" alias was retired at 2.0 and now raises ValueError like any other unknown name. Duplicates are silently collapsed.

依存関係

Selecting a metric that reads another metric’s result computes that one too. cognitive, nargs and nexits each report a per-function average whose divisor is the function count nom supplies.

メトリクスJSON キー引き込まれる依存メトリクス
LoClocnone
循環的複雑度cyclomaticnone
認知的複雑度cognitivenom
Halsteadhalsteadnone
ABCabcnone
nargsnargsnom
nomnomnone
npanpanone
npmnpmnone
nexitsnexitsnom
tokenstokensnone
保守容易性指数miloc, cyclomatic, halstead
クラスごとの重み付きメソッド数(Weighted Methods per Class)wmccyclomatic, nom

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

Computing the full suite is the default because it is what the CLI does. Selecting fewer metric families skips their computations but still runs the tree-sitter parse and walks the AST. Benchmark a representative batch to measure the saving for your workload.

Unrequested metrics are absent from the result. Code that unconditionally indexes into result["metrics"]["mi"] raises KeyError if you opted out of mi; guard with if "mi" in result["metrics"] or use .get("mi").

関連項目

  • Batch processing: metrics= applies uniformly to every file in a batch; validation runs once, before the input is iterated.
  • SARIF output: threshold names are independent of the metrics= selection. You can request metrics=["loc"] and still gate on cyclomatic thresholds, but the SARIF has no findings for the dropped metrics.
  • Flat-record iteration: flatten_spaces emits no keys for metrics absent from the source dict, so a metrics= selection narrows the flattened columns.