summaryrefslogtreecommitdiffstats
path: root/Tools/peg_generator/pegen
diff options
context:
space:
mode:
authorPablo Galindo <Pablogsal@gmail.com>2020-05-02 04:23:06 (GMT)
committerGitHub <noreply@github.com>2020-05-02 04:23:06 (GMT)
commit9dbaa8d9f054e53fac0c3d308d0bce3fc8850525 (patch)
tree994b8e48379713ddf7cc77ae1aa87522b5a8dc4c /Tools/peg_generator/pegen
parent02047265eb83a43ba18cc7fee81756f1a1a1f968 (diff)
downloadcpython-9dbaa8d9f054e53fac0c3d308d0bce3fc8850525.zip
cpython-9dbaa8d9f054e53fac0c3d308d0bce3fc8850525.tar.gz
cpython-9dbaa8d9f054e53fac0c3d308d0bce3fc8850525.tar.bz2
Fix some scripts in the peg generator folder (GH-19853)
Diffstat (limited to 'Tools/peg_generator/pegen')
-rw-r--r--Tools/peg_generator/pegen/ast_dump.py63
-rw-r--r--Tools/peg_generator/pegen/build.py11
2 files changed, 71 insertions, 3 deletions
diff --git a/Tools/peg_generator/pegen/ast_dump.py b/Tools/peg_generator/pegen/ast_dump.py
new file mode 100644
index 0000000..93dfbfd
--- /dev/null
+++ b/Tools/peg_generator/pegen/ast_dump.py
@@ -0,0 +1,63 @@
+"""
+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.
+"""
+
+
+def ast_dump(node, annotate_fields=True, include_attributes=False, *, indent=None):
+ def _format(node, level=0):
+ if indent is not None:
+ level += 1
+ prefix = "\n" + indent * level
+ sep = ",\n" + indent * level
+ else:
+ prefix = ""
+ sep = ", "
+ if any(cls.__name__ == "AST" for cls in node.__class__.__mro__):
+ 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:
+ args.append("%s=%s" % (name, value))
+ 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
+ args.append("%s=%s" % (name, value))
+ if allsimple and len(args) <= 3:
+ return "%s(%s)" % (node.__class__.__name__, ", ".join(args)), not args
+ return "%s(%s%s)" % (node.__class__.__name__, prefix, sep.join(args)), False
+ elif isinstance(node, list):
+ if not node:
+ return "[]", True
+ return "[%s%s]" % (prefix, sep.join(_format(x, level)[0] for x in node)), False
+ return repr(node), True
+
+ if all(cls.__name__ != "AST" for cls in node.__class__.__mro__):
+ raise TypeError("expected AST, got %r" % node.__class__.__name__)
+ if indent is not None and not isinstance(indent, str):
+ indent = " " * indent
+ return _format(node)[0]
diff --git a/Tools/peg_generator/pegen/build.py b/Tools/peg_generator/pegen/build.py
index 907feea..8f9348d 100644
--- a/Tools/peg_generator/pegen/build.py
+++ b/Tools/peg_generator/pegen/build.py
@@ -3,6 +3,7 @@ import shutil
import tokenize
import sys
import sysconfig
+import tempfile
import itertools
from typing import Optional, Tuple, List, IO, Iterator, Set, Dict
@@ -162,9 +163,13 @@ def build_c_generator(
gen.generate(grammar_file)
if compile_extension:
- compile_c_extension(
- output_file, verbose=verbose_c_extension, keep_asserts=keep_asserts_in_extension
- )
+ with tempfile.TemporaryDirectory() as build_dir:
+ compile_c_extension(
+ output_file,
+ build_dir=build_dir,
+ verbose=verbose_c_extension,
+ keep_asserts=keep_asserts_in_extension,
+ )
return gen