or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

ast-to-source.mdfile-operations.mdindex.mdoperator-utilities.mdtree-manipulation.md

tree-manipulation.mddocs/

0

# Tree Manipulation

1

2

Tools and utilities for walking, inspecting, dumping, and modifying AST structures. This module provides comprehensive functionality for AST traversal, node comparison, pretty-printing, and tree transformation operations.

3

4

## Capabilities

5

6

### AST Pretty Printing

7

8

Dump AST structures in a human-readable format with customizable indentation and formatting options for debugging and analysis.

9

10

```python { .api }

11

def dump_tree(node, name=None, initial_indent='', indentation=' ',

12

maxline=120, maxmerged=80):

13

"""

14

Dump AST in pretty-printed format with indentation.

15

16

Parameters:

17

- node: AST node to dump

18

- name: str, optional name for the node

19

- initial_indent: str, initial indentation string (default: '')

20

- indentation: str, indentation string per level (default: 4 spaces)

21

- maxline: int, maximum line length (default: 120)

22

- maxmerged: int, maximum merged line length (default: 80)

23

24

Returns:

25

str: String representation of the AST

26

"""

27

```

28

29

**Usage Example:**

30

31

```python

32

import ast

33

import astor

34

35

code = """

36

def factorial(n):

37

if n <= 1:

38

return 1

39

return n * factorial(n - 1)

40

"""

41

42

tree = ast.parse(code)

43

print(astor.dump_tree(tree))

44

45

# With custom formatting

46

formatted_dump = astor.dump_tree(tree,

47

name="factorial_function",

48

initial_indent=">> ",

49

indentation=" ",

50

maxline=80)

51

print(formatted_dump)

52

```

53

54

### Node Iteration

55

56

Iterate over AST node attributes and list items for systematic node processing and analysis.

57

58

```python { .api }

59

def iter_node(node, name='', unknown=None):

60

"""

61

Iterate over AST node attributes or list items.

62

63

Parameters:

64

- node: AST node or list to iterate over

65

- name: str, name prefix for list items (default: '')

66

- unknown: set, set to collect unknown attributes (default: None)

67

68

Returns:

69

Iterator yielding (value, name) pairs

70

"""

71

```

72

73

**Usage Example:**

74

75

```python

76

import ast

77

import astor

78

79

code = "x = [1, 2, 3]"

80

tree = ast.parse(code)

81

82

# Iterate over all nodes and their attributes

83

for node in ast.walk(tree):

84

print(f"Node: {type(node).__name__}")

85

for value, name in astor.iter_node(node):

86

print(f" {name}: {value}")

87

```

88

89

### Tree Stripping

90

91

Remove all attributes from AST nodes that are not in the standard _fields specification.

92

93

```python { .api }

94

def strip_tree(node):

95

"""

96

Strip AST by removing all attributes not in _fields.

97

98

Parameters:

99

- node: AST node to strip

100

101

Returns:

102

set: Set of names of all stripped attributes

103

"""

104

```

105

106

**Usage Example:**

107

108

```python

109

import ast

110

import astor

111

112

code = "def func(): pass"

113

tree = ast.parse(code)

114

115

# Add some custom attributes

116

for node in ast.walk(tree):

117

node.custom_attr = "custom_value"

118

node.debug_info = {"line": 1}

119

120

# Strip non-standard attributes

121

stripped_attrs = astor.strip_tree(tree)

122

print(f"Stripped attributes: {stripped_attrs}")

123

```

124

125

### Advanced Tree Walking

126

127

The TreeWalk class provides sophisticated tree traversal capabilities with support for both recursive and non-recursive walking patterns.

128

129

```python { .api }

130

class TreeWalk:

131

"""

132

Tree walker that can traverse AST recursively or non-recursively.

133

134

Uses MetaFlatten metaclass for advanced traversal patterns.

135

"""

136

137

def __init__(self, node=None):

138

"""

139

Initialize walker and optionally start walking.

140

141

Parameters:

142

- node: AST node to start walking from (optional)

143

"""

144

145

def setup(self):

146

"""Set up node-specific handlers."""

147

148

def walk(self, node, name=''):

149

"""

150

Walk the tree starting at given node.

151

152

Parameters:

153

- node: AST node to start walking from

154

- name: str, name for the starting node (default: '')

155

"""

156

157

def replace(self, new_node):

158

"""

159

Replace current node with new node.

160

161

Parameters:

162

- new_node: AST node to replace current node with

163

"""

164

165

@property

166

def parent(self):

167

"""

168

Return parent node of current node.

169

170

Returns:

171

AST node that is the parent of the current node

172

"""

173

174

@property

175

def parent_name(self):

176

"""

177

Return parent node and name tuple.

178

179

Returns:

180

tuple: (parent_node, name) pair

181

"""

182

```

183

184

**Usage Example:**

185

186

```python

187

import ast

188

import astor

189

190

class VariableRenamer(astor.TreeWalk):

191

def __init__(self, old_name, new_name):

192

self.old_name = old_name

193

self.new_name = new_name

194

super().__init__()

195

196

def visit_Name(self, node):

197

if node.id == self.old_name:

198

node.id = self.new_name

199

200

code = "def func(x): return x + 1"

201

tree = ast.parse(code)

202

203

# Rename variable 'x' to 'value'

204

renamer = VariableRenamer('x', 'value')

205

renamer.walk(tree)

206

207

print(astor.to_source(tree))

208

```

209

210

### Explicit Node Visitor

211

212

Base class for AST visitors that require explicit handling of all node types, preventing silent failures for unhandled nodes.

213

214

```python { .api }

215

class ExplicitNodeVisitor(ast.NodeVisitor):

216

"""

217

NodeVisitor that removes implicit visits and requires explicit handlers.

218

219

Inherits from ast.NodeVisitor but raises errors for unhandled node types.

220

"""

221

222

def visit(self, node):

223

"""

224

Visit a node with explicit handler requirement.

225

226

Parameters:

227

- node: AST node to visit

228

229

Raises:

230

AttributeError: If no explicit handler exists for the node type

231

"""

232

233

def abort_visit(self, node):

234

"""

235

Default handler that raises AttributeError for unhandled nodes.

236

237

Parameters:

238

- node: AST node that has no explicit handler

239

240

Raises:

241

AttributeError: Always, to indicate missing handler

242

"""

243

```

244

245

### AST Comparison Utilities

246

247

Tools for comparing AST structures and enabling equality operations on AST nodes.

248

249

```python { .api }

250

def allow_ast_comparison():

251

"""

252

Monkey-patch AST nodes to enable equality comparison.

253

254

Modifies AST classes in-place to support == and != operations.

255

"""

256

257

def fast_compare(tree1, tree2):

258

"""

259

Optimized comparison of two AST trees for equality.

260

261

Parameters:

262

- tree1: First AST tree to compare

263

- tree2: Second AST tree to compare

264

265

Returns:

266

bool: True if trees are structurally equal, False otherwise

267

"""

268

```

269

270

**Usage Example:**

271

272

```python

273

import ast

274

import astor

275

276

# Enable AST comparison

277

astor.allow_ast_comparison()

278

279

code1 = "x = 1"

280

code2 = "x = 1"

281

code3 = "y = 1"

282

283

tree1 = ast.parse(code1)

284

tree2 = ast.parse(code2)

285

tree3 = ast.parse(code3)

286

287

# Now AST nodes support equality comparison

288

print(tree1 == tree2) # True

289

print(tree1 == tree3) # False

290

291

# Fast comparison for performance-critical code

292

print(astor.fast_compare(tree1, tree2)) # True

293

print(astor.fast_compare(tree1, tree3)) # False

294

```