Skip to content

Commit b332442

Browse files
authored
Merge pull request google#117 from grumpyhome/unvendor-pythonparser
Unvendorize pythonparser (Fixes google#108)
2 parents e6e6ead + 2496164 commit b332442

File tree

20 files changed

+103
-4146
lines changed

20 files changed

+103
-4146
lines changed

grumpy-tools-src/grumpy_tools/compiler/block.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,9 @@
2424

2525
from grumpy_tools.compiler import expr
2626
from grumpy_tools.compiler import util
27-
from grumpy_tools.vendor.pythonparser import algorithm
28-
from grumpy_tools.vendor.pythonparser import ast
29-
from grumpy_tools.vendor.pythonparser import source
27+
from pythonparser import algorithm
28+
from pythonparser import ast
29+
from pythonparser import source
3030

3131

3232
_non_word_re = re.compile('[^A-Za-z0-9_]')

grumpy-tools-src/grumpy_tools/compiler/block_test.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
from grumpy_tools.compiler import block
2525
from grumpy_tools.compiler import imputil
2626
from grumpy_tools.compiler import util
27-
from grumpy_tools.vendor import pythonparser
27+
import pythonparser
2828

2929

3030
class PackageTest(unittest.TestCase):

grumpy-tools-src/grumpy_tools/compiler/expr_visitor.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,8 @@
2323

2424
from grumpy_tools.compiler import expr
2525
from grumpy_tools.compiler import util
26-
from grumpy_tools.vendor.pythonparser import algorithm
27-
from grumpy_tools.vendor.pythonparser import ast
26+
from pythonparser import algorithm
27+
from pythonparser import ast
2828

2929
try:
3030
long # Python 2

grumpy-tools-src/grumpy_tools/compiler/expr_visitor_test.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
from grumpy_tools.compiler import imputil
2727
from grumpy_tools.compiler import shard_test
2828
from grumpy_tools.compiler import stmt
29-
from grumpy_tools.vendor import pythonparser
29+
import pythonparser
3030

3131
# Handles "Set self.maxDiff to None to see it" annoyance
3232
unittest.TestCase.maxDiff = None

grumpy-tools-src/grumpy_tools/compiler/imputil.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -33,10 +33,10 @@
3333
except ImportError:
3434
from backports.functools_lru_cache import lru_cache
3535

36-
from grumpy_tools.compiler import util
37-
from grumpy_tools.vendor import pythonparser
38-
from grumpy_tools.vendor.pythonparser import algorithm
39-
from grumpy_tools.vendor.pythonparser import ast
36+
from grumpy_tools.compiler import util, parser
37+
import pythonparser
38+
from pythonparser import algorithm
39+
from pythonparser import ast
4040

4141
try:
4242
xrange # Python 2
@@ -247,6 +247,7 @@ def visit_ImportFrom(self, node):
247247

248248

249249
def collect_imports(modname, script, gopath, package_dir=''):
250+
parser.patch_pythonparser()
250251
with open(script) as py_file:
251252
py_contents = py_file.read()
252253
mod = pythonparser.parse(py_contents)

grumpy-tools-src/grumpy_tools/compiler/imputil_test.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,10 @@
2727

2828
from grumpy_tools.compiler import imputil
2929
from grumpy_tools.compiler import util
30-
from grumpy_tools.vendor import pythonparser
30+
from grumpy_tools.compiler.parser import patch_pythonparser
31+
import pythonparser
32+
33+
patch_pythonparser()
3134

3235

3336
class ImportVisitorTest(unittest.TestCase):
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
# coding: utf-8
2+
"""
3+
Grumpy uses `pythonparser` as its AST parser. This module contains an augmented
4+
(extended) parser from it, letting us to accept special Grumpy-only syntax, like
5+
the `import '__go__/...'` syntax for importing Go code.
6+
"""
7+
import logging
8+
9+
import pythonparser.parser
10+
from pythonparser.parser import Parser, Seq, Loc, Opt, Tok, List, Alt, Rule, action
11+
from pythonparser import ast
12+
13+
logger = logging.getLogger(__name__)
14+
15+
PYTHNOPARSER_PATCHED = False
16+
17+
18+
def patch_pythonparser():
19+
global PYTHNOPARSER_PATCHED
20+
if PYTHNOPARSER_PATCHED:
21+
return False
22+
23+
logger.info('Monkeypatching pythonparser.parser.Parser with Grumpy extensions')
24+
pythonparser.parser.Parser = GrumpyParser
25+
PYTHNOPARSER_PATCHED = True
26+
return True
27+
28+
29+
class GrumpyParser(Parser):
30+
# From: https://github.com/google/grumpy/commit/9d80504e8d42c4a03ece9ed983b0ca160d170969#diff-c46e216e8423951b5f41dde139575b68R1038
31+
@action(Rule("atom_5"))
32+
def import_from_7(self, string):
33+
return (None, 0), (string.loc, string.s)
34+
35+
# From: https://github.com/google/grumpy/commit/9d80504e8d42c4a03ece9ed983b0ca160d170969#diff-c46e216e8423951b5f41dde139575b68R1046
36+
@action(Seq(Loc("from"), Alt(Parser.import_from_3, Parser.import_from_4, import_from_7),
37+
Loc("import"), Alt(Parser.import_from_5,
38+
Seq(Loc("("), Rule("import_as_names"), Loc(")")),
39+
Parser.import_from_6)))
40+
def import_from(self, from_loc, module_name, import_loc, names):
41+
"""
42+
(2.6, 2.7)
43+
import_from: ('from' ('.'* dotted_name | '.'+)
44+
'import' ('*' | '(' import_as_names ')' | import_as_names))
45+
(3.0-)
46+
# note below: the ('.' | '...') is necessary because '...' is tokenized as ELLIPSIS
47+
import_from: ('from' (('.' | '...')* dotted_name | ('.' | '...')+)
48+
'import' ('*' | '(' import_as_names ')' | import_as_names))
49+
"""
50+
(dots_loc, dots_count), dotted_name_opt = module_name
51+
module_loc = module = None
52+
if dotted_name_opt:
53+
module_loc, module = dotted_name_opt
54+
lparen_loc, names, rparen_loc = names
55+
loc = from_loc.join(names[-1].loc)
56+
if rparen_loc:
57+
loc = loc.join(rparen_loc)
58+
59+
if module == "__future__":
60+
self.add_flags([x.name for x in names])
61+
62+
return ast.ImportFrom(names=names, module=module, level=dots_count,
63+
keyword_loc=from_loc, dots_loc=dots_loc, module_loc=module_loc,
64+
import_loc=import_loc, lparen_loc=lparen_loc, rparen_loc=rparen_loc,
65+
loc=loc)
66+
67+
@action(Seq(Rule("atom_5"), Opt(Seq(Loc("as"), Tok("ident")))))
68+
def str_as_name(self, string, as_name_opt):
69+
asname_name = asname_loc = as_loc = None
70+
loc = string.loc
71+
if as_name_opt:
72+
as_loc, asname = as_name_opt
73+
asname_name = asname.value
74+
asname_loc = asname.loc
75+
loc = loc.join(asname.loc)
76+
return ast.alias(name=string.s, asname=asname_name,
77+
loc=loc, name_loc=string.loc, as_loc=as_loc, asname_loc=asname_loc)
78+
79+
dotted_as_names = List(Alt(Rule("dotted_as_name"), Rule("str_as_name")), ",", trailing=False)

grumpy-tools-src/grumpy_tools/compiler/stmt.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,8 @@
2727
from grumpy_tools.compiler import expr_visitor
2828
from grumpy_tools.compiler import imputil
2929
from grumpy_tools.compiler import util
30-
from grumpy_tools.vendor.pythonparser import algorithm
31-
from grumpy_tools.vendor.pythonparser import ast
30+
from pythonparser import algorithm
31+
from pythonparser import ast
3232

3333

3434
_NATIVE_TYPE_PREFIX = 'type_'

grumpy-tools-src/grumpy_tools/compiler/stmt_test.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,8 @@
2828
from grumpy_tools.compiler import shard_test
2929
from grumpy_tools.compiler import stmt
3030
from grumpy_tools.compiler import util
31-
from grumpy_tools.vendor import pythonparser
32-
from grumpy_tools.vendor.pythonparser import ast
31+
import pythonparser
32+
from pythonparser import ast
3333

3434
import pytest
3535

grumpy-tools-src/grumpy_tools/grumpc.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,14 +33,16 @@
3333
from .compiler import imputil
3434
from .compiler import stmt
3535
from .compiler import util
36-
from .vendor import pythonparser
36+
from .compiler.parser import patch_pythonparser
37+
import pythonparser
3738
from .pep_support.pep3147pycache import make_transpiled_module_folders, should_refresh, set_checksum, fixed_keyword
3839
from . import pydeps
3940

4041
logger = logging.getLogger(__name__)
4142

4243

4344
def _parse_and_visit(stream, script, modname):
45+
patch_pythonparser()
4446
gopath = os.environ['GOPATH']
4547

4648
stream.seek(0)

0 commit comments

Comments
 (0)