Dead code
dead_code
Dead code detection via AST caller analysis.
Enumerates all symbols in a package and flags those with zero callers
after applying smart exemptions (dunders, tests, decorators, protocols,
overrides, __all__ exports).
Example::
>>> from axm_ast.core.analyzer import analyze_package
>>> from axm_ast.core.dead_code import find_dead_code, format_dead_code
>>> pkg = analyze_package(Path("src/mylib"))
>>> dead = find_dead_code(pkg)
>>> print(format_dead_code(dead))
DeadSymbol
dataclass
An unreferenced symbol detected by dead code analysis.
Source code in packages/axm-ast/src/axm_ast/core/dead_code.py
find_dead_code(pkg, *, include_tests=False)
Detect unreferenced symbols across a package.
Algorithm
- Enumerate all functions and classes across all modules.
- For each symbol, check if it has any callers or references.
- Apply exemptions (dunders, tests, exports, decorators, entry points, etc.).
- For methods, check override chains.
- Also scan a sibling
tests/directory for callers. - Detect lazy imports inside function bodies.
.. warning:: Reference matching is by name only. Liveness is decided
against a single global set[str] of referenced names, so a dead
symbol that shares its name with a live, distinct symbol elsewhere is
wrongly considered referenced and omitted from the result (a false
negative). This is an intrinsic tree-sitter limitation — no type or
scope inference is performed — and mirrors the homonym ambiguity
documented on :func:~axm_ast.core.callers.find_callers. Symbols
reported as dead are therefore high-confidence; truly-dead symbols that
are homonymous with a live one may be silently missed.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
pkg
|
PackageInfo
|
Analyzed package from |
required |
include_tests
|
bool
|
If |
False
|
Returns:
| Type | Description |
|---|---|
list[DeadSymbol]
|
List of dead symbols, sorted by module path then line number. |
Source code in packages/axm-ast/src/axm_ast/core/dead_code.py
find_namespace_modules(pkg)
Find modules that are imported as namespace objects somewhere in pkg.
A module is considered a "namespace import" when it appears as:
- from pkg import mod where mod resolves to a module file
- import pkg.mod (bare module import)
Public symbols in such modules may be accessed via attribute access
(mod.func()) and would not show up in a direct caller search.
Source code in packages/axm-ast/src/axm_ast/core/dead_code.py
format_dead_code(results)
Format dead code results as human-readable grouped output.
Groups results by module path, then lists each dead symbol with its line number and kind.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
results
|
list[DeadSymbol]
|
List of dead symbols from |
required |
Returns:
| Type | Description |
|---|---|
str
|
Formatted string suitable for terminal display. |