| 
									
										
										
										
											2020-04-22 23:29:27 +01:00
										 |  |  | """
 | 
					
						
							|  |  |  | Copy-parse of ast.dump, removing the `isinstance` checks. This is needed, | 
					
						
							|  |  |  | because testing pegen requires generating a C extension module, which contains | 
					
						
							|  |  |  | a copy of the symbols defined in Python-ast.c. Thus, the isinstance check would | 
					
						
							|  |  |  | always fail. We rely on string comparison of the base classes instead. | 
					
						
							|  |  |  | TODO: Remove the above-described hack. | 
					
						
							|  |  |  | """
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-05-02 05:23:06 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-22 23:29:27 +01:00
										 |  |  | def ast_dump(node, annotate_fields=True, include_attributes=False, *, indent=None): | 
					
						
							|  |  |  |     def _format(node, level=0): | 
					
						
							|  |  |  |         if indent is not None: | 
					
						
							|  |  |  |             level += 1 | 
					
						
							| 
									
										
										
										
											2020-05-02 05:23:06 +01:00
										 |  |  |             prefix = "\n" + indent * level | 
					
						
							|  |  |  |             sep = ",\n" + indent * level | 
					
						
							| 
									
										
										
										
											2020-04-22 23:29:27 +01:00
										 |  |  |         else: | 
					
						
							| 
									
										
										
										
											2020-05-02 05:23:06 +01:00
										 |  |  |             prefix = "" | 
					
						
							|  |  |  |             sep = ", " | 
					
						
							|  |  |  |         if any(cls.__name__ == "AST" for cls in node.__class__.__mro__): | 
					
						
							| 
									
										
										
										
											2020-04-22 23:29:27 +01:00
										 |  |  |             cls = type(node) | 
					
						
							|  |  |  |             args = [] | 
					
						
							|  |  |  |             allsimple = True | 
					
						
							|  |  |  |             keywords = annotate_fields | 
					
						
							|  |  |  |             for name in node._fields: | 
					
						
							|  |  |  |                 try: | 
					
						
							|  |  |  |                     value = getattr(node, name) | 
					
						
							|  |  |  |                 except AttributeError: | 
					
						
							|  |  |  |                     keywords = True | 
					
						
							|  |  |  |                     continue | 
					
						
							|  |  |  |                 if value is None and getattr(cls, name, ...) is None: | 
					
						
							|  |  |  |                     keywords = True | 
					
						
							|  |  |  |                     continue | 
					
						
							|  |  |  |                 value, simple = _format(value, level) | 
					
						
							|  |  |  |                 allsimple = allsimple and simple | 
					
						
							|  |  |  |                 if keywords: | 
					
						
							| 
									
										
										
										
											2020-05-02 05:23:06 +01:00
										 |  |  |                     args.append("%s=%s" % (name, value)) | 
					
						
							| 
									
										
										
										
											2020-04-22 23:29:27 +01:00
										 |  |  |                 else: | 
					
						
							|  |  |  |                     args.append(value) | 
					
						
							|  |  |  |             if include_attributes and node._attributes: | 
					
						
							|  |  |  |                 for name in node._attributes: | 
					
						
							|  |  |  |                     try: | 
					
						
							|  |  |  |                         value = getattr(node, name) | 
					
						
							|  |  |  |                     except AttributeError: | 
					
						
							|  |  |  |                         continue | 
					
						
							|  |  |  |                     if value is None and getattr(cls, name, ...) is None: | 
					
						
							|  |  |  |                         continue | 
					
						
							|  |  |  |                     value, simple = _format(value, level) | 
					
						
							|  |  |  |                     allsimple = allsimple and simple | 
					
						
							| 
									
										
										
										
											2020-05-02 05:23:06 +01:00
										 |  |  |                     args.append("%s=%s" % (name, value)) | 
					
						
							| 
									
										
										
										
											2020-04-22 23:29:27 +01:00
										 |  |  |             if allsimple and len(args) <= 3: | 
					
						
							| 
									
										
										
										
											2020-05-02 05:23:06 +01:00
										 |  |  |                 return "%s(%s)" % (node.__class__.__name__, ", ".join(args)), not args | 
					
						
							|  |  |  |             return "%s(%s%s)" % (node.__class__.__name__, prefix, sep.join(args)), False | 
					
						
							| 
									
										
										
										
											2020-04-22 23:29:27 +01:00
										 |  |  |         elif isinstance(node, list): | 
					
						
							|  |  |  |             if not node: | 
					
						
							| 
									
										
										
										
											2020-05-02 05:23:06 +01:00
										 |  |  |                 return "[]", True | 
					
						
							|  |  |  |             return "[%s%s]" % (prefix, sep.join(_format(x, level)[0] for x in node)), False | 
					
						
							| 
									
										
										
										
											2020-04-22 23:29:27 +01:00
										 |  |  |         return repr(node), True | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-05-02 05:23:06 +01:00
										 |  |  |     if all(cls.__name__ != "AST" for cls in node.__class__.__mro__): | 
					
						
							|  |  |  |         raise TypeError("expected AST, got %r" % node.__class__.__name__) | 
					
						
							| 
									
										
										
										
											2020-04-22 23:29:27 +01:00
										 |  |  |     if indent is not None and not isinstance(indent, str): | 
					
						
							| 
									
										
										
										
											2020-05-02 05:23:06 +01:00
										 |  |  |         indent = " " * indent | 
					
						
							| 
									
										
										
										
											2020-04-22 23:29:27 +01:00
										 |  |  |     return _format(node)[0] |