Skip to content
This repository was archived by the owner on Mar 8, 2020. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 26 additions & 0 deletions bblfsh/__init__.py
Original file line number Diff line number Diff line change
@@ -1,2 +1,28 @@
from bblfsh.client import BblfshClient
from bblfsh.pyuast import filter
from bblfsh.aliases import *

# "in" is a reserved keyword in Python thus can't be used as package name, so
# we import by string


class RoleSearchException(Exception):
pass


def role_id(role_name):
try:
name = DESCRIPTOR.enum_types_by_name["Role"].values_by_name[role_name].number
except KeyError:
raise RoleSearchException("Role with name '{}' not found".format(role_name))

return name


def role_name(role_id):
try:
id_ = DESCRIPTOR.enum_types_by_name["Role"].values_by_number[role_id].name
except KeyError:
raise RoleSearchException("Role with ID '{}' not found".format(role_id))

return id_
45 changes: 45 additions & 0 deletions bblfsh/aliases.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
__all__ = ["DESCRIPTOR", "Node", "ParseResponse", "NativeParseResponse",
"ParseRequest", "NativeParseRequest", "VersionRequest",
"ProtocolServiceStub"]

import importlib
import os
import sys

from bblfsh.sdkversion import VERSION

# The following two insertions fix the broken pb import paths
sys.path.insert(0, os.path.join(os.path.dirname(__file__),
"gopkg/in/bblfsh/sdk/%s/protocol" % VERSION))
sys.path.insert(0, os.path.dirname(__file__))

# "in" is a reserved keyword in Python thus can't be used as package name, so
# we import by string

DESCRIPTOR = importlib.import_module(
"bblfsh.gopkg.in.bblfsh.sdk.%s.uast.generated_pb2" % VERSION).DESCRIPTOR

Node = importlib.import_module(
"bblfsh.gopkg.in.bblfsh.sdk.%s.uast.generated_pb2" % VERSION).Node

ParseResponse = importlib.import_module(
"bblfsh.gopkg.in.bblfsh.sdk.%s.protocol.generated_pb2" % VERSION).ParseResponse

NativeParseResponse = importlib.import_module(
"bblfsh.gopkg.in.bblfsh.sdk.%s.protocol.generated_pb2" % VERSION
).NativeParseResponse

ParseRequest = importlib.import_module(
"bblfsh.gopkg.in.bblfsh.sdk.%s.protocol.generated_pb2" % VERSION).ParseRequest

NativeParseRequest = importlib.import_module(
"bblfsh.gopkg.in.bblfsh.sdk.%s.protocol.generated_pb2" % VERSION
).NativeParseRequest

VersionRequest = importlib.import_module(
"bblfsh.gopkg.in.bblfsh.sdk.%s.protocol.generated_pb2" % VERSION
).VersionRequest

ProtocolServiceStub = importlib.import_module(
"bblfsh.gopkg.in.bblfsh.sdk.%s.protocol.generated_pb2_grpc" % VERSION
).ProtocolServiceStub
18 changes: 1 addition & 17 deletions bblfsh/client.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
from ast import literal_eval
import os
import sys
import importlib

import grpc

from bblfsh.aliases import ParseRequest, NativeParseRequest, VersionRequest, ProtocolServiceStub
from bblfsh.sdkversion import VERSION

# The following two insertions fix the broken pb import paths
Expand All @@ -26,10 +25,6 @@ def __init__(self, endpoint):
for example "0.0.0.0:9432"
:type endpoint: str
"""
ProtocolServiceStub = importlib.import_module(
"bblfsh.gopkg.in.bblfsh.sdk.%s.protocol.generated_pb2_grpc" % VERSION
).ProtocolServiceStub

self._channel = grpc.insecure_channel(endpoint)
self._stub = ProtocolServiceStub(self._channel)

Expand All @@ -52,9 +47,6 @@ def parse(self, filename, language=None, contents=None, timeout=None):
:type timeout: float
:return: UAST object.
"""
ParseRequest = importlib.import_module(
"bblfsh.gopkg.in.bblfsh.sdk.%s.protocol.generated_pb2" % VERSION
).ParseRequest

if contents is None:
with open(filename, "rb") as fin:
Expand Down Expand Up @@ -84,10 +76,6 @@ def native_parse(self, filename, language=None, contents=None, timeout=None):
:return: Native AST object.
"""

NativeParseRequest = importlib.import_module(
"bblfsh.gopkg.in.bblfsh.sdk.%s.protocol.generated_pb2" % VERSION
).NativeParseRequest

if contents is None:
with open(filename, "rb") as fin:
contents = fin.read()
Expand All @@ -103,10 +91,6 @@ def version(self):
:return: A dictionary with the keys "version" for the semantic version and
"build" for the build timestamp.
"""
VersionRequest = importlib.import_module(
"bblfsh.gopkg.in.bblfsh.sdk.%s.protocol.generated_pb2" % VERSION
).VersionRequest

return self._stub.Version(VersionRequest())

@staticmethod
Expand Down
48 changes: 22 additions & 26 deletions bblfsh/test.py
Original file line number Diff line number Diff line change
@@ -1,18 +1,9 @@
import unittest
import importlib

import docker

from bblfsh import BblfshClient, filter
from bblfsh import BblfshClient, filter, role_id, role_name, Node, ParseResponse
from bblfsh.launcher import ensure_bblfsh_is_running
from bblfsh.sdkversion import VERSION

# "in" is a reserved keyword in Python thus can't be used as package name, so
# we import by string
ParseResponse = importlib.import_module(
"bblfsh.gopkg.in.bblfsh.sdk.%s.protocol.generated_pb2" % VERSION).ParseResponse
Node = importlib.import_module(
"bblfsh.gopkg.in.bblfsh.sdk.%s.uast.generated_pb2" % VERSION).Node


class BblfshTests(unittest.TestCase):
Expand Down Expand Up @@ -44,19 +35,17 @@ def testNativeParse(self):
assert(reply.ast)

def testUASTDefaultLanguage(self):
uast = self.client.parse(__file__)
self._validate_uast(uast)
self._validate_resp(self.client.parse(__file__))

def testUASTPython(self):
uast = self.client.parse(__file__, language="Python")
self._validate_uast(uast)
self._validate_resp(self.client.parse(__file__, language="Python"))

def testUASTFileContents(self):
with open(__file__, "rb") as fin:
contents = fin.read()
uast = self.client.parse("file.py", contents=contents)
self._validate_uast(uast)
self._validate_filter(uast)
resp = self.client.parse("file.py", contents=contents)
self._validate_resp(resp)
self._validate_filter(resp)

def testBrokenFilter(self):
self.assertRaises(RuntimeError, filter, 0, "foo")
Expand Down Expand Up @@ -123,18 +112,25 @@ def testFilterEndCol(self):
self.assertTrue(any(filter(node, "//*[@endCol=50]")))
self.assertFalse(any(filter(node, "//*[@endCol=5]")))

def _validate_uast(self, uast):
self.assertIsNotNone(uast)
# self.assertIsInstance() does not work - must be some metaclass magic
self.assertEqual(type(uast).DESCRIPTOR.full_name,
def testRoleIdName(sedlf):
assert(role_id(role_name(1)) == 1)
assert(role_name(role_id("IDENTIFIER")) == "IDENTIFIER")

def _validate_resp(self, resp):
self.assertIsNotNone(resp)
self.assertEqual(type(resp).DESCRIPTOR.full_name,
ParseResponse.DESCRIPTOR.full_name)
self.assertEqual(len(uast.errors), 0)
self.assertIsInstance(uast.uast, Node)
self.assertEqual(len(resp.errors), 0)
# self.assertIsInstance() does not work - must be some metaclass magic
# self.assertIsInstance(resp.uast, Node)

# Sometimes its fully qualified, sometimes is just "Node"... ditto
assert(resp.uast.__class__.__name__.endswith('Node'))

def _validate_filter(self, uast):
results = filter(uast.uast, "//Import[@roleImport and @roleDeclaration]//alias")
def _validate_filter(self, resp):
results = filter(resp.uast, "//Import[@roleImport and @roleDeclaration]//alias")
self.assertEqual(next(results).token, "unittest")
self.assertEqual(next(results).token, "importlib")
self.assertEqual(next(results).token, "docker")


if __name__ == "__main__":
Expand Down
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ def main():
},
name="bblfsh",
description="Fetches Universal Abstract Syntax Trees from Babelfish.",
version="2.5.1",
version="2.6.0",
license="Apache 2.0",
author="source{d}",
author_email="[email protected]",
Expand Down