17db96d56Sopenharmony_ci""" 27db96d56Sopenharmony_ciCopy-parse of ast.dump, removing the `isinstance` checks. This is needed, 37db96d56Sopenharmony_cibecause testing pegen requires generating a C extension module, which contains 47db96d56Sopenharmony_cia copy of the symbols defined in Python-ast.c. Thus, the isinstance check would 57db96d56Sopenharmony_cialways fail. We rely on string comparison of the base classes instead. 67db96d56Sopenharmony_ciTODO: Remove the above-described hack. 77db96d56Sopenharmony_ci""" 87db96d56Sopenharmony_ci 97db96d56Sopenharmony_cifrom typing import Any, Optional, Tuple 107db96d56Sopenharmony_ci 117db96d56Sopenharmony_ci 127db96d56Sopenharmony_cidef ast_dump( 137db96d56Sopenharmony_ci node: Any, 147db96d56Sopenharmony_ci annotate_fields: bool = True, 157db96d56Sopenharmony_ci include_attributes: bool = False, 167db96d56Sopenharmony_ci *, 177db96d56Sopenharmony_ci indent: Optional[str] = None, 187db96d56Sopenharmony_ci) -> str: 197db96d56Sopenharmony_ci def _format(node: Any, level: int = 0) -> Tuple[str, bool]: 207db96d56Sopenharmony_ci if indent is not None: 217db96d56Sopenharmony_ci level += 1 227db96d56Sopenharmony_ci prefix = "\n" + indent * level 237db96d56Sopenharmony_ci sep = ",\n" + indent * level 247db96d56Sopenharmony_ci else: 257db96d56Sopenharmony_ci prefix = "" 267db96d56Sopenharmony_ci sep = ", " 277db96d56Sopenharmony_ci if any(cls.__name__ == "AST" for cls in node.__class__.__mro__): 287db96d56Sopenharmony_ci cls = type(node) 297db96d56Sopenharmony_ci args = [] 307db96d56Sopenharmony_ci allsimple = True 317db96d56Sopenharmony_ci keywords = annotate_fields 327db96d56Sopenharmony_ci for name in node._fields: 337db96d56Sopenharmony_ci try: 347db96d56Sopenharmony_ci value = getattr(node, name) 357db96d56Sopenharmony_ci except AttributeError: 367db96d56Sopenharmony_ci keywords = True 377db96d56Sopenharmony_ci continue 387db96d56Sopenharmony_ci if value is None and getattr(cls, name, ...) is None: 397db96d56Sopenharmony_ci keywords = True 407db96d56Sopenharmony_ci continue 417db96d56Sopenharmony_ci value, simple = _format(value, level) 427db96d56Sopenharmony_ci allsimple = allsimple and simple 437db96d56Sopenharmony_ci if keywords: 447db96d56Sopenharmony_ci args.append("%s=%s" % (name, value)) 457db96d56Sopenharmony_ci else: 467db96d56Sopenharmony_ci args.append(value) 477db96d56Sopenharmony_ci if include_attributes and node._attributes: 487db96d56Sopenharmony_ci for name in node._attributes: 497db96d56Sopenharmony_ci try: 507db96d56Sopenharmony_ci value = getattr(node, name) 517db96d56Sopenharmony_ci except AttributeError: 527db96d56Sopenharmony_ci continue 537db96d56Sopenharmony_ci if value is None and getattr(cls, name, ...) is None: 547db96d56Sopenharmony_ci continue 557db96d56Sopenharmony_ci value, simple = _format(value, level) 567db96d56Sopenharmony_ci allsimple = allsimple and simple 577db96d56Sopenharmony_ci args.append("%s=%s" % (name, value)) 587db96d56Sopenharmony_ci if allsimple and len(args) <= 3: 597db96d56Sopenharmony_ci return "%s(%s)" % (node.__class__.__name__, ", ".join(args)), not args 607db96d56Sopenharmony_ci return "%s(%s%s)" % (node.__class__.__name__, prefix, sep.join(args)), False 617db96d56Sopenharmony_ci elif isinstance(node, list): 627db96d56Sopenharmony_ci if not node: 637db96d56Sopenharmony_ci return "[]", True 647db96d56Sopenharmony_ci return "[%s%s]" % (prefix, sep.join(_format(x, level)[0] for x in node)), False 657db96d56Sopenharmony_ci return repr(node), True 667db96d56Sopenharmony_ci 677db96d56Sopenharmony_ci if all(cls.__name__ != "AST" for cls in node.__class__.__mro__): 687db96d56Sopenharmony_ci raise TypeError("expected AST, got %r" % node.__class__.__name__) 697db96d56Sopenharmony_ci if indent is not None and not isinstance(indent, str): 707db96d56Sopenharmony_ci indent = " " * indent 717db96d56Sopenharmony_ci return _format(node)[0] 72