Skip to content
This repository was archived by the owner on Mar 23, 2023. It is now read-only.

Commit 332739d

Browse files
author
Dylan Trotter
committed
Use pythonparser instead of ast for parsing Python.
1 parent 9c117f9 commit 332739d

14 files changed

Lines changed: 3896 additions & 107 deletions

File tree

.pylintrc

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,3 +20,8 @@ disable=design,similarities,no-self-use,attribute-defined-outside-init,locally-d
2020
[REPORTS]
2121
msg-template={path}:{line}: {msg} ({symbol})
2222
reports=no
23+
24+
[TYPECHECK]
25+
# AST classes have dynamic members. Writer does not but for some reason pylint
26+
# barfs on some of its members.
27+
ignored-classes=pythonparser.ast.Module,grumpy.compiler.util.Writer

compiler/block.py

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,11 @@
1919
from __future__ import unicode_literals
2020

2121
import abc
22-
import ast
2322
import collections
2423
import re
2524

25+
from pythonparser import algorithm
26+
from pythonparser import ast
2627
from pythonparser import source
2728

2829
from grumpy.compiler import expr
@@ -226,7 +227,7 @@ class ModuleBlock(Block):
226227

227228
def __init__(self, full_package_name, runtime, libroot, filename, src,
228229
future_features):
229-
super(ModuleBlock, self).__init__(None, '<module>')
230+
Block.__init__(self, None, '<module>')
230231
self._full_package_name = full_package_name
231232
self._runtime = runtime
232233
self._libroot = libroot
@@ -253,7 +254,7 @@ class ClassBlock(Block):
253254
"""Python block for a class definition."""
254255

255256
def __init__(self, parent_block, name, global_vars):
256-
super(ClassBlock, self).__init__(parent_block, name)
257+
Block.__init__(self, parent_block, name)
257258
self.global_vars = global_vars
258259

259260
def bind_var(self, writer, name, value):
@@ -293,7 +294,7 @@ class FunctionBlock(Block):
293294
"""Python block for a function definition."""
294295

295296
def __init__(self, parent_block, name, block_vars, is_generator):
296-
super(FunctionBlock, self).__init__(parent_block, name)
297+
Block.__init__(self, parent_block, name)
297298
self.vars = block_vars
298299
self.parent_block = parent_block
299300
self.is_generator = is_generator
@@ -353,7 +354,7 @@ def __init__(self, name, var_type, arg_index=None):
353354
self.init_expr = None
354355

355356

356-
class BlockVisitor(ast.NodeVisitor):
357+
class BlockVisitor(algorithm.Visitor):
357358
"""Visits nodes in a function or class to determine block variables."""
358359

359360
# pylint: disable=invalid-name,missing-docstring
@@ -401,8 +402,9 @@ def visit_ImportFrom(self, node):
401402
self._register_local(alias.asname or alias.name)
402403

403404
def visit_With(self, node):
404-
if node.optional_vars:
405-
self._assign_target(node.optional_vars)
405+
for item in node.items:
406+
if item.optional_vars:
407+
self._assign_target(item.optional_vars)
406408
self.generic_visit(node)
407409

408410
def _assign_target(self, target):
@@ -435,14 +437,14 @@ class FunctionBlockVisitor(BlockVisitor):
435437
# pylint: disable=invalid-name,missing-docstring
436438

437439
def __init__(self, node):
438-
super(FunctionBlockVisitor, self).__init__()
440+
BlockVisitor.__init__(self)
439441
self.is_generator = False
440442
node_args = node.args
441-
args = [a.id for a in node_args.args]
443+
args = [a.arg for a in node_args.args]
442444
if node_args.vararg:
443-
args.append(node_args.vararg)
445+
args.append(node_args.vararg.arg)
444446
if node_args.kwarg:
445-
args.append(node_args.kwarg)
447+
args.append(node_args.kwarg.arg)
446448
for i, name in enumerate(args):
447449
if name in self.vars:
448450
msg = "duplicate argument '{}' in function definition".format(name)

compiler/block_test.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,11 @@
1818

1919
from __future__ import unicode_literals
2020

21-
import ast
2221
import textwrap
2322
import unittest
2423

24+
import pythonparser
25+
2526
from grumpy.compiler import block
2627
from grumpy.compiler import stmt
2728
from grumpy.compiler import util
@@ -206,7 +207,7 @@ def testGlobalIsParam(self):
206207
visitor.visit, _ParseStmt('global foo'))
207208

208209
def testGlobalUsedPriorToDeclaration(self):
209-
node = ast.parse('foo = 42\nglobal foo')
210+
node = pythonparser.parse('foo = 42\nglobal foo')
210211
visitor = block.BlockVisitor()
211212
self.assertRaisesRegexp(util.ParseError, 'used prior to global declaration',
212213
visitor.generic_visit, node)
@@ -250,7 +251,7 @@ def _MakeModuleBlock():
250251

251252

252253
def _ParseStmt(stmt_str):
253-
return ast.parse(stmt_str).body[0]
254+
return pythonparser.parse(stmt_str).body[0]
254255

255256

256257
if __name__ == '__main__':

compiler/expr_visitor.py

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -18,16 +18,18 @@
1818

1919
from __future__ import unicode_literals
2020

21-
import ast
2221
import contextlib
2322
import textwrap
2423

24+
from pythonparser import algorithm
25+
from pythonparser import ast
26+
2527
from grumpy.compiler import block
2628
from grumpy.compiler import expr
2729
from grumpy.compiler import util
2830

2931

30-
class ExprVisitor(ast.NodeVisitor):
32+
class ExprVisitor(algorithm.Visitor):
3133
"""Builds and returns a Go expression representing the Python nodes."""
3234

3335
# pylint: disable=invalid-name,missing-docstring
@@ -194,8 +196,10 @@ def visit_Set(self, node):
194196

195197
def visit_DictComp(self, node):
196198
result = self.block.alloc_temp()
197-
elt = ast.Tuple(elts=[node.key, node.value], context=ast.Load)
198-
with self.visit(ast.GeneratorExp(elt, node.generators)) as gen:
199+
elt = ast.Tuple(elts=[node.key, node.value])
200+
gen_node = ast.GeneratorExp(
201+
elt=elt, generators=node.generators, loc=node.loc)
202+
with self.visit(gen_node) as gen:
199203
self.writer.write_checked_call2(
200204
result, 'πg.DictType.Call(πF, πg.Args{{{}}}, nil)', gen.expr)
201205
return result
@@ -218,12 +222,12 @@ def visit_ExtSlice(self, node):
218222
return result
219223

220224
def visit_GeneratorExp(self, node):
221-
body = ast.Expr(value=ast.Yield(node.elt), lineno=None)
225+
body = ast.Expr(value=ast.Yield(value=node.elt), loc=node.loc)
222226
for comp_node in reversed(node.generators):
223227
for if_node in reversed(comp_node.ifs):
224-
body = ast.If(test=if_node, body=[body], orelse=[], lineno=None) # pylint: disable=redefined-variable-type
228+
body = ast.If(test=if_node, body=[body], orelse=[], loc=node.loc) # pylint: disable=redefined-variable-type
225229
body = ast.For(target=comp_node.target, iter=comp_node.iter,
226-
body=[body], orelse=[], lineno=None)
230+
body=[body], orelse=[], loc=node.loc)
227231

228232
args = ast.arguments(args=[], vararg=None, kwarg=None, defaults=[])
229233
node = ast.FunctionDef(name='<generator>', args=args, body=[body])
@@ -259,7 +263,7 @@ def visit_Index(self, node):
259263
return result
260264

261265
def visit_Lambda(self, node):
262-
ret = ast.Return(node.body, lineno=node.lineno)
266+
ret = ast.Return(value=node.body, loc=node.loc)
263267
func_node = ast.FunctionDef(
264268
name='<lambda>', args=node.args, body=[ret])
265269
return self.visit_function_inline(func_node)
@@ -273,7 +277,9 @@ def visit_List(self, node):
273277

274278
def visit_ListComp(self, node):
275279
result = self.block.alloc_temp()
276-
with self.visit(ast.GeneratorExp(node.elt, node.generators)) as gen:
280+
gen_node = ast.GeneratorExp(
281+
elt=node.elt, generators=node.generators, loc=node.loc)
282+
with self.visit(gen_node) as gen:
277283
self.writer.write_checked_call2(
278284
result, 'πg.ListType.Call(πF, πg.Args{{{}}}, nil)', gen.expr)
279285
return result
@@ -438,7 +444,7 @@ def visit_function_inline(self, node):
438444
with self.visit(d) if d else expr.nil_expr as default:
439445
tmpl = '$args[$i] = πg.Param{Name: $name, Def: $default}'
440446
self.writer.write_tmpl(tmpl, args=func_args.expr, i=i,
441-
name=util.go_str(a.id), default=default.expr)
447+
name=util.go_str(a.arg), default=default.expr)
442448
flags = []
443449
if args.vararg:
444450
flags.append('πg.CodeFlagVarArg')

compiler/expr_visitor_test.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,12 @@
1818

1919
from __future__ import unicode_literals
2020

21-
import ast
2221
import subprocess
2322
import textwrap
2423
import unittest
2524

25+
import pythonparser
26+
2627
from grumpy.compiler import block
2728
from grumpy.compiler import expr_visitor
2829
from grumpy.compiler import shard_test
@@ -231,7 +232,7 @@ def _MakeModuleBlock():
231232

232233

233234
def _ParseExpr(expr):
234-
return ast.parse(expr).body[0].value
235+
return pythonparser.parse(expr).body[0].value
235236

236237

237238
def _ParseAndVisitExpr(expr):

0 commit comments

Comments
 (0)