topos.functors.probes.mdg.coupling

Coupling Metrics

Quantifies the structural coupling of a module within the dependency graph.

Mathematical Inspiration:

Robert C. Martin’s package coupling metrics measure how tangled a module is with its neighbours:

  • Afferent coupling (Ca): number of external modules that depend on this module (incoming IMPORTS edges).

  • Efferent coupling (Ce): number of external modules this module depends on (outgoing IMPORTS edges).

  • Instability I = Ce / (Ca + Ce): ranges from 0 (maximally stable, everyone depends on you) to 1 (maximally unstable, you depend on everyone).

High total coupling (Ca + Ce) indicates a module that is hard to change in isolation. Extreme instability or stability combined with high coupling is a design-smell.

Dependency depth measures the longest chain of transitive IMPORTS reachable from the module – deep chains amplify the blast radius of changes.

class topos.functors.probes.mdg.coupling.CouplingResult(afferent, efferent)[source]

Bases: object

Coupling metrics for a single module.

afferent

Number of modules that depend on this one (Ca).

Type:

int

efferent

Number of modules this one depends on (Ce).

Type:

int

total

Ca + Ce.

afferent
efferent
property total
topos.functors.probes.mdg.coupling.calculate_coupling(graph, file_node_id, symbol_ids=None)[source]

Calculate afferent and efferent coupling for a file node.

Counts distinct source/target File nodes connected via IMPORTS relationships (directly or through contained symbols).

Parameters:
  • graph – The dependency graph.

  • file_node_id – The ID of the file node to analyse.

  • symbol_ids – Pre-computed set of all contained symbol IDs (including file_node_id itself). Computed from the graph when not provided.

Returns:

A CouplingResult with afferent and efferent counts.

topos.functors.probes.mdg.coupling.calculate_instability(graph, file_node_id)[source]

Calculate Martin’s Instability metric: I = Ce / (Ca + Ce).

Returns 0.5 when the module has zero coupling (no signal).

topos.functors.probes.mdg.coupling.calculate_instability_from_result(result)[source]

Calculate Martin’s Instability metric from a precomputed coupling result.

Useful when coupling has already been computed and we want to avoid traversing the graph twice.

topos.functors.probes.mdg.coupling.calculate_dependency_depth(graph, file_node_id)[source]

Longest chain of transitive IMPORTS from file_node_id.

Uses BFS to avoid cycles.