Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.11/site-packages/gast/gast.py: 31%

Shortcuts on this page

r m x   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

156 statements  

1import sys as _sys 

2import ast as _ast 

3from ast import boolop, cmpop, excepthandler, expr, expr_context, operator 

4from ast import slice, stmt, unaryop, mod, AST 

5from ast import iter_child_nodes, walk 

6 

7try: 

8 from ast import TypeIgnore 

9except ImportError: 

10 class TypeIgnore(AST): 

11 pass 

12 

13try: 

14 from ast import pattern 

15except ImportError: 

16 class pattern(AST): 

17 pass 

18 

19 

20try: 

21 from ast import type_param 

22except ImportError: 

23 class type_param(AST): 

24 pass 

25 

26 

27def _make_node(Name, Fields, Attributes, Bases): 

28 

29 # This constructor is used a lot during conversion from ast to gast, 

30 # then as the primary way to build ast nodes. So we tried to optimized it 

31 # for speed and not for readability. 

32 def create_node(self, *args, **kwargs): 

33 if len(args) > len(Fields): 

34 raise TypeError( 

35 "{} constructor takes at most {} positional arguments". 

36 format(Name, len(Fields))) 

37 

38 # it's faster to iterate rather than zipping or enumerate 

39 for i in range(len(args)): 

40 setattr(self, Fields[i], args[i]) 

41 if kwargs: # cold branch 

42 self.__dict__.update(kwargs) 

43 

44 setattr(_sys.modules[__name__], 

45 Name, 

46 type(Name, 

47 Bases, 

48 {'__init__': create_node, 

49 '_fields': Fields, 

50 '_attributes': Attributes})) 

51 

52 

53_nodes = ( 

54 # mod 

55 ('Module', (('body', 'type_ignores'), (), (mod,))), 

56 ('Interactive', (('body',), (), (mod,))), 

57 ('Expression', (('body',), (), (mod,))), 

58 ('FunctionType', (('argtypes', 'returns'), (), (mod,))), 

59 ('Suite', (('body',), (), (mod,))), 

60 

61 # stmt 

62 ('FunctionDef', (('name', 'args', 'body', 'decorator_list', 'returns', 

63 'type_comment', 'type_params'), 

64 ('lineno', 'col_offset', 'end_lineno', 'end_col_offset',), 

65 (stmt,))), 

66 ('AsyncFunctionDef', (('name', 'args', 'body', 'decorator_list', 'returns', 

67 'type_comment', 'type_params',), 

68 ('lineno', 'col_offset', 

69 'end_lineno', 'end_col_offset',), 

70 (stmt,))), 

71 ('ClassDef', (('name', 'bases', 'keywords', 'body', 'decorator_list', 

72 'type_params',), 

73 ('lineno', 'col_offset', 'end_lineno', 'end_col_offset',), 

74 (stmt,))), 

75 ('Return', (('value',), 

76 ('lineno', 'col_offset', 'end_lineno', 'end_col_offset',), 

77 (stmt,))), 

78 ('Delete', (('targets',), 

79 ('lineno', 'col_offset', 'end_lineno', 'end_col_offset',), 

80 (stmt,))), 

81 ('Assign', (('targets', 'value', 'type_comment'), 

82 ('lineno', 'col_offset', 'end_lineno', 'end_col_offset',), 

83 (stmt,))), 

84 ('TypeAlias', (('name', 'type_params', 'value'), 

85 ('lineno', 'col_offset', 'end_lineno', 'end_col_offset',), 

86 (stmt,))), 

87 ('AugAssign', (('target', 'op', 'value',), 

88 ('lineno', 'col_offset', 'end_lineno', 'end_col_offset',), 

89 (stmt,))), 

90 ('AnnAssign', (('target', 'annotation', 'value', 'simple',), 

91 ('lineno', 'col_offset', 'end_lineno', 'end_col_offset',), 

92 (stmt,))), 

93 ('Print', (('dest', 'values', 'nl',), 

94 ('lineno', 'col_offset', 'end_lineno', 'end_col_offset',), 

95 (stmt,))), 

96 ('For', (('target', 'iter', 'body', 'orelse', 'type_comment'), 

97 ('lineno', 'col_offset', 'end_lineno', 'end_col_offset',), 

98 (stmt,))), 

99 ('AsyncFor', (('target', 'iter', 'body', 'orelse', 'type_comment'), 

100 ('lineno', 'col_offset', 'end_lineno', 'end_col_offset',), 

101 (stmt,))), 

102 ('While', (('test', 'body', 'orelse',), 

103 ('lineno', 'col_offset', 'end_lineno', 'end_col_offset',), 

104 (stmt,))), 

105 ('If', (('test', 'body', 'orelse',), 

106 ('lineno', 'col_offset', 'end_lineno', 'end_col_offset',), 

107 (stmt,))), 

108 ('With', (('items', 'body', 'type_comment'), 

109 ('lineno', 'col_offset', 'end_lineno', 'end_col_offset',), 

110 (stmt,))), 

111 ('AsyncWith', (('items', 'body', 'type_comment'), 

112 ('lineno', 'col_offset', 'end_lineno', 'end_col_offset',), 

113 (stmt,))), 

114 ('Match', (('subject', 'cases'), 

115 ('lineno', 'col_offset', 'end_lineno', 'end_col_offset',), 

116 (stmt,))), 

117 ('Raise', (('exc', 'cause',), 

118 ('lineno', 'col_offset', 'end_lineno', 'end_col_offset',), 

119 (stmt,))), 

120 ('Try', (('body', 'handlers', 'orelse', 'finalbody',), 

121 ('lineno', 'col_offset', 'end_lineno', 'end_col_offset',), 

122 (stmt,))), 

123 ('TryStar', (('body', 'handlers', 'orelse', 'finalbody',), 

124 ('lineno', 'col_offset', 'end_lineno', 'end_col_offset',), 

125 (stmt,))), 

126 ('Assert', (('test', 'msg',), 

127 ('lineno', 'col_offset', 'end_lineno', 'end_col_offset',), 

128 (stmt,))), 

129 ('Import', (('names',), 

130 ('lineno', 'col_offset', 'end_lineno', 'end_col_offset',), 

131 (stmt,))), 

132 ('ImportFrom', (('module', 'names', 'level',), 

133 ('lineno', 'col_offset', 'end_lineno', 'end_col_offset',), 

134 (stmt,))), 

135 ('Exec', (('body', 'globals', 'locals',), 

136 ('lineno', 'col_offset', 'end_lineno', 'end_col_offset',), 

137 (stmt,))), 

138 ('Global', (('names',), 

139 ('lineno', 'col_offset', 'end_lineno', 'end_col_offset',), 

140 (stmt,))), 

141 ('Nonlocal', (('names',), 

142 ('lineno', 'col_offset', 'end_lineno', 'end_col_offset',), 

143 (stmt,))), 

144 ('Expr', (('value',), 

145 ('lineno', 'col_offset', 'end_lineno', 'end_col_offset',), 

146 (stmt,))), 

147 ('Pass', ((), ('lineno', 'col_offset', 'end_lineno', 'end_col_offset',), 

148 (stmt,))), 

149 ('Break', ((), ('lineno', 'col_offset', 'end_lineno', 'end_col_offset',), 

150 (stmt,))), 

151 ('Continue', ((), 

152 ('lineno', 'col_offset', 'end_lineno', 'end_col_offset',), 

153 (stmt,))), 

154 

155 # expr 

156 

157 ('BoolOp', (('op', 'values',), 

158 ('lineno', 'col_offset', 'end_lineno', 'end_col_offset',), 

159 (expr,))), 

160 ('NamedExpr', (('target', 'value',), 

161 ('lineno', 'col_offset', 'end_lineno', 'end_col_offset',), 

162 (expr,))), 

163 ('BinOp', (('left', 'op', 'right',), 

164 ('lineno', 'col_offset', 'end_lineno', 'end_col_offset',), 

165 (expr,))), 

166 ('UnaryOp', (('op', 'operand',), 

167 ('lineno', 'col_offset', 'end_lineno', 'end_col_offset',), 

168 (expr,))), 

169 ('Lambda', (('args', 'body',), 

170 ('lineno', 'col_offset', 'end_lineno', 'end_col_offset',), 

171 (expr,))), 

172 ('IfExp', (('test', 'body', 'orelse',), 

173 ('lineno', 'col_offset', 'end_lineno', 'end_col_offset',), 

174 (expr,))), 

175 ('Dict', (('keys', 'values',), 

176 ('lineno', 'col_offset', 'end_lineno', 'end_col_offset',), 

177 (expr,))), 

178 ('Set', (('elts',), 

179 ('lineno', 'col_offset', 'end_lineno', 'end_col_offset',), 

180 (expr,))), 

181 ('ListComp', (('elt', 'generators',), 

182 ('lineno', 'col_offset', 'end_lineno', 'end_col_offset',), 

183 (expr,))), 

184 ('SetComp', (('elt', 'generators',), 

185 ('lineno', 'col_offset', 'end_lineno', 'end_col_offset',), 

186 (expr,))), 

187 ('DictComp', (('key', 'value', 'generators',), 

188 ('lineno', 'col_offset', 'end_lineno', 'end_col_offset',), 

189 (expr,))), 

190 ('GeneratorExp', (('elt', 'generators',), 

191 ('lineno', 'col_offset', 

192 'end_lineno', 'end_col_offset',), 

193 (expr,))), 

194 ('Await', (('value',), 

195 ('lineno', 'col_offset', 'end_lineno', 'end_col_offset',), 

196 (expr,))), 

197 ('Yield', (('value',), 

198 ('lineno', 'col_offset', 'end_lineno', 'end_col_offset',), 

199 (expr,))), 

200 ('YieldFrom', (('value',), 

201 ('lineno', 'col_offset', 'end_lineno', 'end_col_offset',), 

202 (expr,))), 

203 ('Compare', (('left', 'ops', 'comparators',), 

204 ('lineno', 'col_offset', 'end_lineno', 'end_col_offset',), 

205 (expr,))), 

206 ('Call', (('func', 'args', 'keywords',), 

207 ('lineno', 'col_offset', 'end_lineno', 'end_col_offset',), 

208 (expr,))), 

209 ('Repr', (('value',), 

210 ('lineno', 'col_offset', 'end_lineno', 'end_col_offset',), 

211 (expr,))), 

212 ('FormattedValue', (('value', 'conversion', 'format_spec',), 

213 ('lineno', 'col_offset', 

214 'end_lineno', 'end_col_offset',), 

215 (expr,))), 

216 ('JoinedStr', (('values',), 

217 ('lineno', 'col_offset', 'end_lineno', 'end_col_offset',), 

218 (expr,))), 

219 ('Constant', (('value', 'kind'), 

220 ('lineno', 'col_offset', 'end_lineno', 'end_col_offset',), 

221 (expr,))), 

222 ('Attribute', (('value', 'attr', 'ctx',), 

223 ('lineno', 'col_offset', 'end_lineno', 'end_col_offset',), 

224 (expr,))), 

225 ('Subscript', (('value', 'slice', 'ctx',), 

226 ('lineno', 'col_offset', 'end_lineno', 'end_col_offset',), 

227 (expr,))), 

228 ('Starred', (('value', 'ctx',), 

229 ('lineno', 'col_offset', 'end_lineno', 'end_col_offset',), 

230 (expr,))), 

231 ('Name', (('id', 'ctx', 'annotation', 'type_comment'), 

232 ('lineno', 'col_offset', 'end_lineno', 'end_col_offset',), 

233 (expr,))), 

234 ('List', (('elts', 'ctx',), 

235 ('lineno', 'col_offset', 'end_lineno', 'end_col_offset',), 

236 (expr,))), 

237 ('Tuple', (('elts', 'ctx',), 

238 ('lineno', 'col_offset', 'end_lineno', 'end_col_offset',), 

239 (expr,))), 

240 

241 # expr_context 

242 ('Load', ((), (), (expr_context,))), 

243 ('Store', ((), (), (expr_context,))), 

244 ('Del', ((), (), (expr_context,))), 

245 ('AugLoad', ((), (), (expr_context,))), 

246 ('AugStore', ((), (), (expr_context,))), 

247 ('Param', ((), (), (expr_context,))), 

248 

249 # slice 

250 ('Slice', (('lower', 'upper', 'step'), 

251 ('lineno', 'col_offset', 'end_lineno', 'end_col_offset',), 

252 (slice,))), 

253 

254 # boolop 

255 ('And', ((), (), (boolop,))), 

256 ('Or', ((), (), (boolop,))), 

257 

258 # operator 

259 ('Add', ((), (), (operator,))), 

260 ('Sub', ((), (), (operator,))), 

261 ('Mult', ((), (), (operator,))), 

262 ('MatMult', ((), (), (operator,))), 

263 ('Div', ((), (), (operator,))), 

264 ('Mod', ((), (), (operator,))), 

265 ('Pow', ((), (), (operator,))), 

266 ('LShift', ((), (), (operator,))), 

267 ('RShift', ((), (), (operator,))), 

268 ('BitOr', ((), (), (operator,))), 

269 ('BitXor', ((), (), (operator,))), 

270 ('BitAnd', ((), (), (operator,))), 

271 ('FloorDiv', ((), (), (operator,))), 

272 

273 # unaryop 

274 ('Invert', ((), (), (unaryop, AST,))), 

275 ('Not', ((), (), (unaryop, AST,))), 

276 ('UAdd', ((), (), (unaryop, AST,))), 

277 ('USub', ((), (), (unaryop, AST,))), 

278 

279 # cmpop 

280 ('Eq', ((), (), (cmpop,))), 

281 ('NotEq', ((), (), (cmpop,))), 

282 ('Lt', ((), (), (cmpop,))), 

283 ('LtE', ((), (), (cmpop,))), 

284 ('Gt', ((), (), (cmpop,))), 

285 ('GtE', ((), (), (cmpop,))), 

286 ('Is', ((), (), (cmpop,))), 

287 ('IsNot', ((), (), (cmpop,))), 

288 ('In', ((), (), (cmpop,))), 

289 ('NotIn', ((), (), (cmpop,))), 

290 

291 # comprehension 

292 ('comprehension', (('target', 'iter', 'ifs', 'is_async'), (), (AST,))), 

293 

294 # excepthandler 

295 ('ExceptHandler', (('type', 'name', 'body'), 

296 ('lineno', 'col_offset', 

297 'end_lineno', 'end_col_offset'), 

298 (excepthandler,))), 

299 

300 # arguments 

301 ('arguments', (('args', 'posonlyargs', 'vararg', 'kwonlyargs', 

302 'kw_defaults', 'kwarg', 'defaults'), (), (AST,))), 

303 

304 # keyword 

305 ('keyword', (('arg', 'value'), 

306 ('lineno', 'col_offset', 'end_lineno', 'end_col_offset'), 

307 (AST,))), 

308 

309 # alias 

310 ('alias', (('name', 'asname'), 

311 ('lineno', 'col_offset', 'end_lineno', 'end_col_offset'), 

312 (AST,))), 

313 

314 # withitem 

315 ('withitem', (('context_expr', 'optional_vars'), (), (AST,))), 

316 

317 # match_case 

318 ('match_case', (('pattern', 'guard', 'body'), (), (AST,))), 

319 

320 # pattern 

321 ('MatchValue', (('value',), 

322 ('lineno', 'col_offset', 'end_lineno', 'end_col_offset'), 

323 (pattern,))), 

324 ('MatchSingleton', (('value',), 

325 ('lineno', 'col_offset', 

326 'end_lineno', 'end_col_offset'), 

327 (pattern,))), 

328 ('MatchSequence', (('patterns',), 

329 ('lineno', 'col_offset', 

330 'end_lineno', 'end_col_offset'), 

331 (pattern,))), 

332 ('MatchMapping', (('keys', 'patterns', 'rest'), 

333 ('lineno', 'col_offset', 

334 'end_lineno', 'end_col_offset'), 

335 (pattern,))), 

336 ('MatchClass', (('cls', 'patterns', 'kwd_attrs', 'kwd_patterns'), 

337 ('lineno', 'col_offset', 

338 'end_lineno', 'end_col_offset'), 

339 (pattern,))), 

340 ('MatchStar', (('name',), 

341 ('lineno', 'col_offset', 

342 'end_lineno', 'end_col_offset'), 

343 (pattern,))), 

344 ('MatchAs', (('pattern', 'name'), 

345 ('lineno', 'col_offset', 

346 'end_lineno', 'end_col_offset'), 

347 (pattern,))), 

348 ('MatchOr', (('patterns',), 

349 ('lineno', 'col_offset', 

350 'end_lineno', 'end_col_offset'), 

351 (pattern,))), 

352 

353 # type_ignore 

354 ('type_ignore', ((), ('lineno', 'tag'), (TypeIgnore,))), 

355 

356 # type_param 

357 ('TypeVar', (('name', 'bound',), 

358 ('lineno', 'col_offset', 

359 'end_lineno', 'end_col_offset'), 

360 (type_param,))), 

361 ('ParamSpec', (('name',), 

362 ('lineno', 'col_offset', 

363 'end_lineno', 'end_col_offset'), 

364 (type_param,))), 

365 ('TypeVarTuple', (('name',), 

366 ('lineno', 'col_offset', 

367 'end_lineno', 'end_col_offset'), 

368 (type_param,))), 

369 ) 

370 

371 

372 

373 

374for name, descr in _nodes: 

375 _make_node(name, *descr) 

376 

377if _sys.version_info.major == 2: 

378 from .ast2 import ast_to_gast, gast_to_ast 

379if _sys.version_info.major == 3: 

380 from .ast3 import ast_to_gast, gast_to_ast 

381 

382 

383def parse(*args, **kwargs): 

384 return ast_to_gast(_ast.parse(*args, **kwargs)) 

385 

386 

387def unparse(gast_obj): 

388 from .unparser import unparse 

389 return unparse(gast_obj) 

390 

391 

392def literal_eval(node_or_string): 

393 if isinstance(node_or_string, AST): 

394 node_or_string = gast_to_ast(node_or_string) 

395 return _ast.literal_eval(node_or_string) 

396 

397 

398def get_docstring(node, clean=True): 

399 if not isinstance(node, (AsyncFunctionDef, FunctionDef, ClassDef, Module)): 

400 raise TypeError("%r can't have docstrings" % node.__class__.__name__) 

401 if not(node.body and isinstance(node.body[0], Expr)): 

402 return None 

403 node = node.body[0].value 

404 if isinstance(node, Constant) and isinstance(node.value, str): 

405 text = node.value 

406 else: 

407 return None 

408 if clean: 

409 import inspect 

410 text = inspect.cleandoc(text) 

411 return text 

412 

413 

414# the following are directly imported from python3.8's Lib/ast.py # 

415 

416def copy_location(new_node, old_node): 

417 """ 

418 Copy source location (`lineno`, `col_offset`, `end_lineno`, and 

419 `end_col_offset` attributes) from *old_node* to *new_node* if possible, 

420 and return *new_node*. 

421 """ 

422 for attr in 'lineno', 'col_offset', 'end_lineno', 'end_col_offset': 

423 if attr in old_node._attributes and attr in new_node._attributes \ 

424 and hasattr(old_node, attr): 

425 setattr(new_node, attr, getattr(old_node, attr)) 

426 return new_node 

427 

428 

429def fix_missing_locations(node): 

430 """ 

431 When you compile a node tree with compile(), the compiler expects lineno 

432 and col_offset attributes for every node that supports them. This is 

433 rather tedious to fill in for generated nodes, so this helper adds these 

434 attributes recursively where not already set, by setting them to the values 

435 of the parent node. It works recursively starting at *node*. 

436 """ 

437 def _fix(node, lineno, col_offset, end_lineno, end_col_offset): 

438 if 'lineno' in node._attributes: 

439 if not hasattr(node, 'lineno'): 

440 node.lineno = lineno 

441 else: 

442 lineno = node.lineno 

443 if 'end_lineno' in node._attributes: 

444 if not hasattr(node, 'end_lineno'): 

445 node.end_lineno = end_lineno 

446 else: 

447 end_lineno = node.end_lineno 

448 if 'col_offset' in node._attributes: 

449 if not hasattr(node, 'col_offset'): 

450 node.col_offset = col_offset 

451 else: 

452 col_offset = node.col_offset 

453 if 'end_col_offset' in node._attributes: 

454 if not hasattr(node, 'end_col_offset'): 

455 node.end_col_offset = end_col_offset 

456 else: 

457 end_col_offset = node.end_col_offset 

458 for child in iter_child_nodes(node): 

459 _fix(child, lineno, col_offset, end_lineno, end_col_offset) 

460 _fix(node, 1, 0, 1, 0) 

461 return node 

462 

463 

464if _sys.version_info.major == 3 and _sys.version_info.minor >= 8: 

465 get_source_segment = _ast.get_source_segment 

466else: 

467 # No end_lineno no end_col_offset info set for those version, so always 

468 # return None 

469 def get_source_segment(source, node, padded=False): 

470 return None 

471 

472 

473def increment_lineno(node, n=1): 

474 """ 

475 Increment the line number and end line number of each node in the tree 

476 starting at *node* by *n*. This is useful to "move code" to a different 

477 location in a file. 

478 """ 

479 for child in walk(node): 

480 if 'lineno' in child._attributes: 

481 child.lineno = (getattr(child, 'lineno', 0) or 0) + n 

482 if 'end_lineno' in child._attributes: 

483 child.end_lineno = (getattr(child, 'end_lineno', 0) or 0) + n 

484 return node 

485 

486if _sys.version_info.major == 3 and _sys.version_info.minor >= 13: 

487 dump = _ast.dump 

488else: 

489 # Code import from Lib/ast.py 

490 # 

491 # minor changes: getattr(x, y, ...) is None => getattr(x, y, 42) is None 

492 # 

493 def dump( 

494 node, annotate_fields=True, include_attributes=False, 

495 # *, # removed for compatibility with python2 :-/ 

496 indent=None, show_empty=False, 

497 ): 

498 """ 

499 Return a formatted dump of the tree in node. This is mainly useful for 

500 debugging purposes. If annotate_fields is true (by default), 

501 the returned string will show the names and the values for fields. 

502 If annotate_fields is false, the result string will be more compact by 

503 omitting unambiguous field names. Attributes such as line 

504 numbers and column offsets are not dumped by default. If this is wanted, 

505 include_attributes can be set to true. If indent is a non-negative 

506 integer or string, then the tree will be pretty-printed with that indent 

507 level. None (the default) selects the single line representation. 

508 If show_empty is False, then empty lists and fields that are None 

509 will be omitted from the output for better readability. 

510 """ 

511 def _format(node, level=0): 

512 if indent is not None: 

513 level += 1 

514 prefix = '\n' + indent * level 

515 sep = ',\n' + indent * level 

516 else: 

517 prefix = '' 

518 sep = ', ' 

519 if isinstance(node, AST): 

520 cls = type(node) 

521 args = [] 

522 args_buffer = [] 

523 allsimple = True 

524 keywords = annotate_fields 

525 for name in node._fields: 

526 try: 

527 value = getattr(node, name) 

528 except AttributeError: 

529 keywords = True 

530 continue 

531 if value is None and getattr(cls, name, 42) is None: 

532 keywords = True 

533 continue 

534 if ( 

535 not show_empty 

536 and (value is None or value == []) 

537 # Special cases: 

538 # `Constant(value=None)` and `MatchSingleton(value=None)` 

539 and not isinstance(node, (Constant, MatchSingleton)) 

540 ): 

541 args_buffer.append(repr(value)) 

542 continue 

543 elif not keywords: 

544 args.extend(args_buffer) 

545 args_buffer = [] 

546 value, simple = _format(value, level) 

547 allsimple = allsimple and simple 

548 if keywords: 

549 args.append('%s=%s' % (name, value)) 

550 else: 

551 args.append(value) 

552 if include_attributes and node._attributes: 

553 for name in node._attributes: 

554 try: 

555 value = getattr(node, name) 

556 except AttributeError: 

557 continue 

558 if value is None and getattr(cls, name, 42) is None: 

559 continue 

560 value, simple = _format(value, level) 

561 allsimple = allsimple and simple 

562 args.append('%s=%s' % (name, value)) 

563 if allsimple and len(args) <= 3: 

564 return '%s(%s)' % (node.__class__.__name__, ', '.join(args)), not args 

565 return '%s(%s%s)' % (node.__class__.__name__, prefix, sep.join(args)), False 

566 elif isinstance(node, list): 

567 if not node: 

568 return '[]', True 

569 return '[%s%s]' % (prefix, sep.join(_format(x, level)[0] for x in node)), False 

570 return repr(node), True 

571 

572 if not isinstance(node, AST): 

573 raise TypeError('expected AST, got %r' % node.__class__.__name__) 

574 if indent is not None and not isinstance(indent, str): 

575 indent = ' ' * indent 

576 return _format(node)[0]