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

Commit da6ceba

Browse files
authored
Merge pull request #124 from vmarkovtsev/master
Fix PB imports (#122)
2 parents bc807c7 + 11c98ac commit da6ceba

File tree

5 files changed

+72
-39
lines changed

5 files changed

+72
-39
lines changed

.gitignore

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,4 +106,4 @@ libuast
106106

107107
bblfsh/github
108108
bblfsh/gopkg
109-
gopkg.in/bblfsh
109+
proto/gopkg.in

bblfsh/aliases.py

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,9 @@
33
"ProtocolServiceStub"]
44

55
import importlib
6-
import os
7-
import sys
86

97
from bblfsh.sdkversion import VERSION
108

11-
# The following two insertions fix the broken pb import paths
12-
sys.path.insert(0, os.path.join(os.path.dirname(__file__),
13-
"gopkg/in/bblfsh/sdk/%s/protocol" % VERSION))
14-
sys.path.insert(0, os.path.dirname(__file__))
15-
169
# "in" is a reserved keyword in Python thus can't be used as package name, so
1710
# we import by string
1811

bblfsh/test.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -299,6 +299,7 @@ def testSupportedLanguages(self):
299299

300300
def _validate_filter(self, resp):
301301
results = filter(resp.uast, "//Num")
302+
self.assertIsInstance(resp.uast, Node)
302303
self.assertEqual(next(results).token, "0")
303304
self.assertEqual(next(results).token, "1")
304305
self.assertEqual(next(results).token, "100")
File renamed without changes.

setup.py

Lines changed: 70 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
1-
import fileinput
1+
import glob
22
import logging
33
import os
44
import pkg_resources
5+
import re
56
import shutil
67
import subprocess
78
import sys
@@ -11,7 +12,7 @@
1112
from setuptools import setup, find_packages, Extension
1213
from setuptools.command.build_ext import build_ext
1314

14-
VERSION = "2.11.2"
15+
VERSION = "2.12.0"
1516
LIBUAST_VERSION = "v1.9.5"
1617
SDK_VERSION = "v1.16.1"
1718
SDK_MAJOR = SDK_VERSION.split('.')[0]
@@ -101,8 +102,8 @@ def call(*cmd):
101102

102103

103104
def create_dirs():
104-
mkdir(j("gopkg.in", "bblfsh", "sdk.{SDK_MAJOR}", "protocol"))
105-
mkdir(j("gopkg.in", "bblfsh", "sdk.{SDK_MAJOR}", "uast"))
105+
mkdir(j("proto", "gopkg.in", "bblfsh", "sdk.{SDK_MAJOR}", "protocol"))
106+
mkdir(j("proto", "gopkg.in", "bblfsh", "sdk.{SDK_MAJOR}", "uast"))
106107
mkdir(j("bblfsh", "gopkg", "in", "bblfsh", "sdk", SDK_MAJOR, "protocol"))
107108
mkdir(j("bblfsh", "gopkg", "in", "bblfsh", "sdk", SDK_MAJOR, "uast"))
108109
mkdir(j("bblfsh", "github", "com", "gogo", "protobuf", "gogoproto"))
@@ -143,42 +144,80 @@ def get_libuast():
143144
def proto_download():
144145
untar_url("https://github.com/bblfsh/sdk/archive/%s.tar.gz" % SDK_VERSION)
145146
sdkdir = "sdk-" + SDK_VERSION[1:]
146-
cp(j(sdkdir, "protocol", "generated.proto"),
147-
j("gopkg.in", "bblfsh", "sdk.{SDK_MAJOR}", "protocol", "generated.proto"))
148-
cp(j(sdkdir, "uast", "generated.proto"),
149-
j("gopkg.in", "bblfsh", "sdk.{SDK_MAJOR}", "uast", "generated.proto"))
147+
destdir = j("proto", "gopkg.in", "bblfsh", "sdk.{SDK_MAJOR}")
148+
cp(j(sdkdir, "protocol", "generated.proto"), j(destdir, "protocol", "generated.proto"))
149+
cp(j(sdkdir, "uast", "generated.proto"), j(destdir, "uast", "generated.proto"))
150150
rimraf(sdkdir)
151151

152152

153153
def proto_compile():
154154
sysinclude = "-I" + pkg_resources.resource_filename("grpc_tools", "_proto")
155155
from grpc.tools import protoc as protoc_module
156156

157-
def protoc(python_out, proto_file, *extra, grpc=True):
158-
main_args = [protoc_module.__file__, "--python_out=" + python_out]
157+
from_import_re = re.compile(r"from ((github|gopkg)\.[^ ]*) import (.*)")
158+
importlib_import_re = re.compile(r"([^ ]+) = importlib\.import_module\('(.*)")
159+
grpc_import_re = re.compile(
160+
r"from (([^ .]+\.)*in(\.[^ .]+)*) import ([^ ]+) as ([^\n]+)")
161+
162+
def patch(file, *patchers):
163+
with open(file) as fin:
164+
code = fin.readlines()
165+
for i, line in enumerate(code):
166+
for regexp, replacer in patchers:
167+
match = regexp.match(line)
168+
if match:
169+
code[i] = replacer(match)
170+
log.info("patched import in %s: %s", file, match.groups()[0])
171+
break
172+
if line.startswith("class") or line.startswith("DESCRIPTOR"):
173+
break
174+
with open(file, "w") as fout:
175+
fout.write("".join(code))
176+
177+
def protoc(proto_file, grpc=False):
178+
main_args = [protoc_module.__file__, "--python_out=bblfsh"]
179+
target_dir = j("bblfsh", *os.path.dirname(proto_file).split("."))
159180
if grpc:
160-
main_args += ["--grpc_python_out=" + python_out]
161-
main_args += extra
162-
main_args += ["-I.", sysinclude, proto_file]
163-
log.info("%s -m grpc.tools.protoc " + " ".join(main_args), sys.executable)
181+
# using "." creates "gopkg.in" instead of "gopkg/in" directories
182+
main_args += ["--grpc_python_out=" + target_dir]
183+
main_args += ["-Iproto", sysinclude, j("proto", proto_file)]
184+
log.info("%s -m grpc.tools.protoc " + " ".join(main_args[1:]), sys.executable)
164185
protoc_module.main(main_args)
165-
166-
sdk_root = j("bblfsh", "gopkg", "in", "bblfsh", "sdk", SDK_MAJOR)
167-
# SDK
168-
protoc(j(sdk_root, "protocol"),
169-
j("gopkg.in", "bblfsh", "sdk." + SDK_MAJOR, "protocol", "generated.proto"),
170-
"-I" + j("gopkg.in", "bblfsh", "sdk." + SDK_MAJOR, "protocol"))
171-
# UAST
172-
protoc("bblfsh", j("github.com", "gogo", "protobuf", "gogoproto", "gogo.proto"),
173-
grpc=False)
174-
protoc("bblfsh", j("gopkg.in", "bblfsh", "sdk." + SDK_MAJOR, "uast", "generated.proto"),
175-
grpc=False)
176-
for line in fileinput.input([j(sdk_root, "protocol", "generated_pb2.py"),
177-
j(sdk_root, "uast", "generated_pb2.py")],
178-
inplace=True):
179-
print(line.replace("from github.com.gogo.protobuf.gogoproto import",
180-
"from bblfsh.github.com.gogo.protobuf.gogoproto import"),
181-
end="")
186+
if grpc:
187+
# we need to move the file back to grpc_out
188+
grpc_garbage_dir = None
189+
target = j(target_dir, "generated_pb2_grpc.py")
190+
for root, dirnames, filenames in os.walk(target_dir):
191+
for filename in filenames:
192+
if filename == "generated_pb2_grpc.py" and grpc_garbage_dir is not None:
193+
mv(j(root, filename), target)
194+
if os.path.samefile(root, target_dir):
195+
grpc_garbage_dir = j(root, dirnames[0])
196+
rimraf(grpc_garbage_dir)
197+
198+
# grpc ignores "in" and we need to patch the import path
199+
def grpc_replacer(match):
200+
groups = match.groups()
201+
return 'import importlib\n%s = importlib.import_module("bblfsh.%s.%s")\n' % (
202+
groups[-1], groups[0], groups[-2])
203+
204+
patch(target, (grpc_import_re, grpc_replacer))
205+
206+
target = glob.glob(j(target_dir, "*_pb2.py"))[0]
207+
208+
def from_import_replacer(match):
209+
return "from bblfsh.%s import %s\n" % (match.group(1), match.group(3))
210+
211+
def importlib_import_replacer(match):
212+
return "%s = importlib.import_module('bblfsh.%s\n" % (match.group(1), match.group(2))
213+
214+
patch(target,
215+
(from_import_re, from_import_replacer),
216+
(importlib_import_re, importlib_import_replacer))
217+
218+
protoc(j("gopkg.in", "bblfsh", "sdk." + SDK_MAJOR, "protocol", "generated.proto"), True)
219+
protoc(j("github.com", "gogo", "protobuf", "gogoproto", "gogo.proto"))
220+
protoc(j("gopkg.in", "bblfsh", "sdk." + SDK_MAJOR, "uast", "generated.proto"))
182221

183222

184223
def do_get_deps():

0 commit comments

Comments
 (0)