Path: blob/main/Tools/peg_generator/pegen/ast_dump.py
12 views
"""1Copy-parse of ast.dump, removing the `isinstance` checks. This is needed,2because testing pegen requires generating a C extension module, which contains3a copy of the symbols defined in Python-ast.c. Thus, the isinstance check would4always fail. We rely on string comparison of the base classes instead.5TODO: Remove the above-described hack.6"""78from typing import Any, Optional, Tuple91011def ast_dump(12node: Any,13annotate_fields: bool = True,14include_attributes: bool = False,15*,16indent: Optional[str] = None,17) -> str:18def _format(node: Any, level: int = 0) -> Tuple[str, bool]:19if indent is not None:20level += 121prefix = "\n" + indent * level22sep = ",\n" + indent * level23else:24prefix = ""25sep = ", "26if any(cls.__name__ == "AST" for cls in node.__class__.__mro__):27cls = type(node)28args = []29allsimple = True30keywords = annotate_fields31for name in node._fields:32try:33value = getattr(node, name)34except AttributeError:35keywords = True36continue37if value is None and getattr(cls, name, ...) is None:38keywords = True39continue40value, simple = _format(value, level)41allsimple = allsimple and simple42if keywords:43args.append("%s=%s" % (name, value))44else:45args.append(value)46if include_attributes and node._attributes:47for name in node._attributes:48try:49value = getattr(node, name)50except AttributeError:51continue52if value is None and getattr(cls, name, ...) is None:53continue54value, simple = _format(value, level)55allsimple = allsimple and simple56args.append("%s=%s" % (name, value))57if allsimple and len(args) <= 3:58return "%s(%s)" % (node.__class__.__name__, ", ".join(args)), not args59return "%s(%s%s)" % (node.__class__.__name__, prefix, sep.join(args)), False60elif isinstance(node, list):61if not node:62return "[]", True63return "[%s%s]" % (prefix, sep.join(_format(x, level)[0] for x in node)), False64return repr(node), True6566if all(cls.__name__ != "AST" for cls in node.__class__.__mro__):67raise TypeError("expected AST, got %r" % node.__class__.__name__)68if indent is not None and not isinstance(indent, str):69indent = " " * indent70return _format(node)[0]717273