orchestrata_tools.parser.json_loader
Reference › orchestrata_tools › parser › json_loader
JSONASTLoader reads the JSON snapshot written by the AST serializer into the orchestrata_tools models of ast_models. The JSON format is defined by orchestrata_ast.models. The loader is used by the package CLI __main__, the backcompat wrappers and the script scripts.add_traces_from_evidence.
load opens a path, parses the JSON and calls load_from_dict, which is also usable on an already-parsed dictionary. Private helpers (_parse_module, _parse_class, _parse_method, _parse_function, _parse_import, _parse_param, _parse_class_var) convert each node. _parse_class also accepts a plain string for inner classes. Fields in the snapshot that the orchestrata_tools models do not have, such as body hashes, are not carried over. A missing or invalid file raises the underlying file or JSON error.
At a glance
| Source | src/orchestrata_tools/parser/json_loader.py |
| Lines of code | 154 |
| Classes | 1 |
| Functions | 0 |
| Imports (internal) | orchestrata_tools.models.ast_models |
| Imported by | orchestrata_tools, orchestrata_tools.parser, scripts.add_traces_from_evidence |
| Tests that import it | tests/test_orchestrata_ast_analyzer.py |
Class diagram
Dependency diagram
API
Classes
JSONASTLoader
Line 21
Load ASTCodebase from JSON produced by serialize_codebase_ast.py.
| Method | Signature | Summary |
|---|---|---|
load |
load(path: Path | str) -> ASTCodebase |
|
load_from_dict |
load_from_dict(data: dict[str, Any]) -> ASTCodebase |
|
_parse_module |
_parse_module(data: dict[str, Any]) -> ModuleInfo |
|
_parse_class |
_parse_class(data: dict[str, Any] | str, module_path: str = '', file_path: str = '') -> ClassInfo |
|
_parse_method |
_parse_method(data: dict[str, Any]) -> MethodInfo |
|
_parse_function |
_parse_function(data: dict[str, Any]) -> FunctionInfo |
|
_parse_import |
_parse_import(data: dict[str, Any]) -> ImportInfo |
|
_parse_param |
_parse_param(data: dict[str, Any]) -> ParamInfo |
|
_parse_class_var |
_parse_class_var(data: dict[str, Any]) -> ClassVarInfo |
Source
"""Load ASTCodebase from serialize_codebase_ast JSON output."""
from __future__ import annotations
import json
from pathlib import Path
from typing import Any
from orchestrata_tools.models.ast_models import (
ASTCodebase,
ClassInfo,
ClassVarInfo,
FunctionInfo,
ImportInfo,
MethodInfo,
ModuleInfo,
ParamInfo,
)
class JSONASTLoader:
"""Load ASTCodebase from JSON produced by serialize_codebase_ast.py."""
def load(self, path: Path | str) -> ASTCodebase:
with open(path) as f:
data = json.load(f)
return self.load_from_dict(data)
def load_from_dict(self, data: dict[str, Any]) -> ASTCodebase:
modules = [self._parse_module(m) for m in data.get("modules", [])]
return ASTCodebase(
name=data.get("name", ""),
root_path=data.get("root_path", ""),
modules=modules,
inheritance_graph=data.get("inheritance_graph", {}),
dependency_graph=data.get("dependency_graph", {}),
total_classes=data.get("total_classes", 0),
total_functions=data.get("total_functions", 0),
total_methods=data.get("total_methods", 0),
total_loc=data.get("total_loc", 0),
)
def _parse_module(self, data: dict[str, Any]) -> ModuleInfo:
return ModuleInfo(
path=data.get("path", ""),
file_path=data.get("file_path", ""),
line_count=data.get("line_count", 0),
classes=[
self._parse_class(c, data.get("path", ""), data.get("file_path", ""))
for c in data.get("classes", [])
],
functions=[self._parse_function(f) for f in data.get("functions", [])],
imports=[self._parse_import(i) for i in data.get("imports", [])],
module_vars=data.get("module_vars", []),
docstring=data.get("docstring"),
all_exports=data.get("all_exports", []),
)
def _parse_class(
self, data: dict[str, Any] | str, module_path: str = "", file_path: str = ""
) -> ClassInfo:
if isinstance(data, str):
return ClassInfo(
name=data,
qualified_name=f"{module_path}.{data}",
module_path=module_path,
file_path=file_path,
line=0,
)
return ClassInfo(
name=data.get("name", ""),
qualified_name=data.get("qualified_name", ""),
module_path=data.get("module_path", module_path),
file_path=data.get("file_path", file_path),
line=data.get("line", 0),
bases=data.get("bases", []),
decorators=data.get("decorators", []),
methods=[self._parse_method(m) for m in data.get("methods", [])],
class_vars=[self._parse_class_var(v) for v in data.get("class_vars", [])],
docstring=data.get("docstring"),
is_abstract=data.get("is_abstract", False),
is_dataclass=data.get("is_dataclass", False),
is_pydantic=data.get("is_pydantic", False),
is_protocol=data.get("is_protocol", False),
is_enum=data.get("is_enum", False),
inner_classes=[
self._parse_class(
c,
data.get("module_path", module_path),
data.get("file_path", file_path),
)
for c in data.get("inner_classes", [])
],
)
def _parse_method(self, data: dict[str, Any]) -> MethodInfo:
return MethodInfo(
name=data.get("name", ""),
qualified_name=data.get("qualified_name", ""),
module_path=data.get("module_path", ""),
file_path=data.get("file_path", ""),
line=data.get("line", 0),
is_async=data.get("is_async", False),
is_method=data.get("is_method", True),
is_classmethod=data.get("is_classmethod", False),
is_staticmethod=data.get("is_staticmethod", False),
is_property=data.get("is_property", False),
is_abstract=data.get("is_abstract", False),
decorators=data.get("decorators", []),
parameters=[self._parse_param(p) for p in data.get("parameters", [])],
return_type=data.get("return_type"),
docstring=data.get("docstring"),
class_name=data.get("class_name", ""),
calls=data.get("calls", []),
)
def _parse_function(self, data: dict[str, Any]) -> FunctionInfo:
return FunctionInfo(
name=data.get("name", ""),
qualified_name=data.get("qualified_name", ""),
module_path=data.get("module_path", ""),
file_path=data.get("file_path", ""),
line=data.get("line", 0),
is_async=data.get("is_async", False),
decorators=data.get("decorators", []),
parameters=[self._parse_param(p) for p in data.get("parameters", [])],
return_type=data.get("return_type"),
docstring=data.get("docstring"),
)
def _parse_import(self, data: dict[str, Any]) -> ImportInfo:
return ImportInfo(
module=data.get("module", ""),
names=data.get("names", []),
alias=data.get("alias"),
is_from=data.get("is_from", False),
is_relative=data.get("is_relative", False),
level=data.get("level", 0),
)
def _parse_param(self, data: dict[str, Any]) -> ParamInfo:
return ParamInfo(
name=data.get("name", ""),
type_annotation=data.get("type_annotation"),
default=data.get("default"),
kind=data.get("kind", "positional"),
)
def _parse_class_var(self, data: dict[str, Any]) -> ClassVarInfo:
return ClassVarInfo(
name=data.get("name", ""),
type_annotation=data.get("type_annotation"),
default=data.get("default"),
)