Analyzer
analyzer
High-level package analysis engine.
This module builds on the tree-sitter parser to provide package-wide analysis: module discovery, dependency graphs, public API extraction, and semantic search.
Example
from pathlib import Path from axm_ast.core.analyzer import analyze_package pkg = analyze_package(Path("src/mylib")) [m.path.name for m in pkg.modules]
['__init__.py', 'core.py', 'utils.py']
analyze_package(path)
Analyze a Python package directory.
Discovers all .py files, parses them with tree-sitter, and
builds a complete PackageInfo with dependency edges.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
path
|
Path
|
Path to the package root directory. |
required |
Returns:
| Type | Description |
|---|---|
PackageInfo
|
PackageInfo with all modules and dependency edges. |
Raises:
| Type | Description |
|---|---|
ValueError
|
If path is not a directory. |
Example
pkg = analyze_package(Path("src/mylib")) pkg.name 'mylib'
Source code in packages/axm-ast/src/axm_ast/core/analyzer.py
| Python | |
|---|---|
72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 | |
build_import_graph(pkg)
Build an adjacency-list import graph from package info.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
pkg
|
PackageInfo
|
Analyzed package info. |
required |
Returns:
| Type | Description |
|---|---|
dict[str, list[str]]
|
Dict mapping module name to list of modules it imports. |
Example
graph = build_import_graph(pkg) graph["cli"]
['core', 'models']
Source code in packages/axm-ast/src/axm_ast/core/analyzer.py
classify_reference_placement(pkg, symbol)
Classify where a reference to symbol should be placed.
Grounds the decision in real symbol resolution over pkg rather than guesswork: a symbol that already exists can be imported at module top level, while a not-yet-created (future) symbol must be referenced at call time (in-body) so a RED test collects cleanly and fails inside the body instead of crashing at collection.
Resolution delegates to :func:find_module_for_symbol (and, as a
fallback, :func:search_symbols) — no lookup logic is duplicated here.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
pkg
|
PackageInfo
|
Analyzed package info. |
required |
symbol
|
str
|
The symbol name to classify. |
required |
Returns:
| Type | Description |
|---|---|
str
|
|
str
|
|
Source code in packages/axm-ast/src/axm_ast/core/analyzer.py
find_module_for_symbol(pkg, symbol)
Find the module containing a symbol.
Supports two lookup modes:
- Object (
FunctionInfo/ClassInfo): identity-first match, then name fallback. - String: name-based search across functions, methods, and classes.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
pkg
|
PackageInfo
|
Analyzed package info. |
required |
symbol
|
str | FunctionInfo | ClassInfo | VariableInfo
|
Symbol name or object to locate. |
required |
Returns:
| Type | Description |
|---|---|
ModuleInfo | None
|
The |
Source code in packages/axm-ast/src/axm_ast/core/analyzer.py
fingerprint_source_tree(root)
Return (path, mtime_ns) pairs for every source .py under root.
Used by the package cache to detect additions, deletions, and content
modifications cheaply. Unlike a bare rglob("*.py") it prunes the same
non-source directories as :func:_discover_py_files (_SKIP_DIRS and
*.egg-info), so it neither stats nor descends into .venv/.git/
__pycache__ trees — an os.scandir walk that is several times faster
and consistent with discovery. Gitignore rules are intentionally not
applied here (they require a subprocess per directory); an ignored .py
that escapes _SKIP_DIRS is simply tracked, erring toward extra
invalidation rather than staleness.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
root
|
Path
|
Directory to fingerprint (typically a package root). |
required |
Returns:
| Type | Description |
|---|---|
frozenset[tuple[str, int]]
|
Frozenset of |
Source code in packages/axm-ast/src/axm_ast/core/analyzer.py
module_dotted_name(mod_path, root)
Convert a module file path to a dotted name relative to root.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
mod_path
|
Path
|
Absolute path to a |
required |
root
|
Path
|
Package root directory. |
required |
Returns:
| Type | Description |
|---|---|
str
|
Dotted module name (e.g. |
Source code in packages/axm-ast/src/axm_ast/core/analyzer.py
search_symbols(pkg, *, name=None, returns=None, kind=None, inherits=None)
Search for symbols across a package with filters.
All filters are AND-combined. A symbol must match all provided filters to be included in results.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
pkg
|
PackageInfo
|
Analyzed package info. |
required |
name
|
str | None
|
Filter by symbol name (substring match). |
None
|
returns
|
str | None
|
Filter functions by return type (substring match). |
None
|
kind
|
SymbolKind | None
|
Filter by SymbolKind (function, method, property, classmethod, staticmethod, abstract, class, variable). |
None
|
inherits
|
str | None
|
Filter classes by base class name. |
None
|
Returns:
| Type | Description |
|---|---|
list[tuple[str, FunctionInfo | ClassInfo | VariableInfo]]
|
List of (module_name, symbol) tuples for matching symbols. |
Example
results = search_symbols(pkg, returns="str") [sym.name for _, sym in results]
['greet', 'version']