diff --git a/.circleci/config.yml b/.circleci/config.yml new file mode 100644 index 0000000..2204979 --- /dev/null +++ b/.circleci/config.yml @@ -0,0 +1,48 @@ +version: 2 + +jobs: + build: + working_directory: ~/py-graphqlparser + docker: + - image: ubuntu:16.04 + steps: + - checkout + - run: + name: apt update + command: apt-get -q update + - run: + name: apt required packages + command: apt-get install -qy build-essential python python3 python3-pip python3-dev git cmake bison flex pkg-config + - run: + name: install cython + command: pip3 install -q cython==0.27.3 + - run: + name: git submodules + command: | + mkdir -p -m 700 ~/.ssh + ssh-keyscan github.com >> ~/.ssh/known_hosts + git submodule -q sync + git submodule -q update -f --init + - run: + name: build libgraphqlparser + command: | + cd libgraphqlparser + cmake . + make + - run: + name: ast + command: python2 ast/build_ast.py + - run: + name: build ext + command: LDFLAGS="-L./libgraphqlparser" CFLAGS="-Ilibgraphqlparser/c -Ilibgraphqlparser" python3 setup.py build_ext + - run: + name: install package + command: pip3 install -e . + - run: + name: install pytest + command: pip3 install pytest + - run: + name: test + command: python3 -m pytest + environment: + LD_LIBRARY_PATH: "./libgraphqlparser" diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..fa0fe61 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,7 @@ +**/.git/ +**/__pycache__/ +.circleci/ +.pytest_cache/ +.tox/ +.wheelhouse/ +**/CMakeCache.txt diff --git a/.gitignore b/.gitignore index bd169f6..29f89a8 100644 --- a/.gitignore +++ b/.gitignore @@ -9,3 +9,4 @@ __pycache__ /.cache /dist/ /*.egg-info +.pytest_cache diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..d471113 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,26 @@ +FROM ubuntu:16.04 + +RUN apt-get update -qy +RUN apt-get install -qy build-essential python python3 python3-pip python3-dev git cmake bison flex pkg-config +RUN pip3 install cython + +RUN mkdir /tmp/build +COPY libgraphqlparser /tmp/build/libgraphqlparser +COPY ast /tmp/build/ast +COPY examples /tmp/build/examples +COPY graphql_parser /tmp/build/graphql_parser +COPY setup.py *.rst /tmp/build/ + + +RUN cd /tmp/build/libgraphqlparser && \ + cmake . && \ + make && \ + cp libgraphqlparser.so /usr/local/lib +RUN cd /tmp/build && \ + python2 ast/build_ast.py && \ + LDFLAGS="-L./libgraphqlparser" CFLAGS="-Ilibgraphqlparser/c -Ilibgraphqlparser" \ + python3 setup.py build_ext && \ + pip3 install . +ENV LD_LIBRARY_PATH=/usr/local/lib + +ENTRYPOINT ["python3", "/tmp/build/examples/visitor_example.py"] diff --git a/NEWS.rst b/NEWS.rst index 611a075..180ede0 100644 --- a/NEWS.rst +++ b/NEWS.rst @@ -1,6 +1,13 @@ News ---- +v0.0.4 +------ + +- compatible with latest libgraphqlparser 0.7.0 +- built wheels for python 3.6 + + v0.0.3 ------ diff --git a/README.rst b/README.rst index 5ed1b42..1b63048 100644 --- a/README.rst +++ b/README.rst @@ -1,6 +1,9 @@ Graphql parser based on libgraphqlparser ========================================= +.. image:: https://circleci.com/gh/elastic-coders/py-graphqlparser.svg?style=svg + :target: https://circleci.com/gh/elastic-coders/py-graphqlparser + Python2.7+ Python3.4+ class-based bindings to libgraphqlparser; just a thin layer on top of ``libgraphqlparser`` C API. Still **EXPERIMENTAL** @@ -16,7 +19,7 @@ on `graphqlparser github releases`_ Pick the right wheel for your platform and python version, then install it using pip:: - pip install https://github.com/elastic-coders/py-graphqlparser/releases/download/v0.0.3/graphqlparser-0.0.3-cp27-none-linux_x86_64.whl + pip install https://github.com/elastic-coders/py-graphqlparser/releases/download/v0.0.4/graphqlparser-0.0.4-cp36-cp36m-linux_x86_64.whl As an alternative you can install ``graphqlparser`` from source distribution: diff --git a/ast/ast_cython.py b/ast/ast_cython.py index 2f0f423..4fbd184 100644 --- a/ast/ast_cython.py +++ b/ast/ast_cython.py @@ -36,10 +36,10 @@ def start_type(self, name): print ''' cdef class %(name)s(GraphQLAst): - cdef %(cmodule)s.%(name)s* _wrapped + cdef const %(cmodule)s.%(name)s* _wrapped @staticmethod - cdef create(cGraphQLAst.%(name)s *thing) + cdef create(const cGraphQLAst.%(name)s *thing) ''' % {'name': st_name, 'cmodule': ast_cython_c.CMODULE_NAME} self._current_type = name diff --git a/ast/ast_cython_impl.py b/ast/ast_cython_impl.py index 7f99521..48e0ed7 100644 --- a/ast/ast_cython_impl.py +++ b/ast/ast_cython_impl.py @@ -55,7 +55,7 @@ def get_%(snake)s(self): # python object return type return ''' def get_%(snake)s(self): - cdef %(cmodule)s.%(return_st)s *next + cdef const %(cmodule)s.%(return_st)s *next next = %(cmodule)s.%(owning_st)s_get_%(snake)s(self._wrapped) if next is NULL: return None @@ -88,7 +88,7 @@ def start_type(self, name): cdef class %(name)s(GraphQLAst): @staticmethod - cdef create(%(cmodule)s.%(name)s *thing): + cdef create(const %(cmodule)s.%(name)s *thing): node = %(name)s() node._wrapped = thing return node diff --git a/ast/ast_cython_visitor.py b/ast/ast_cython_visitor.py index 0af4906..c9e3881 100644 --- a/ast/ast_cython_visitor.py +++ b/ast/ast_cython_visitor.py @@ -50,7 +50,7 @@ def end_file(self): print ''' void graphql_node_visit(GraphQLAstNode *node, - GraphQLAstVisitorCallbacks *callbacks, + const GraphQLAstVisitorCallbacks *callbacks, void *userData) ''' diff --git a/ast/ast_cython_visitor_impl.py b/ast/ast_cython_visitor_impl.py index ad9d5c5..16c1fb7 100644 --- a/ast/ast_cython_visitor_impl.py +++ b/ast/ast_cython_visitor_impl.py @@ -55,7 +55,7 @@ def end_file(self): _map = {'snake': snake(type), 'name': type, 'cmodule': CMODULE_NAME} print ''' -cdef int _visit_%(snake)s(%(cmodule)s.GraphQLAst%(name)s* node, void* userData, int end): +cdef int _visit_%(snake)s(const %(cmodule)s.GraphQLAst%(name)s* node, void* userData, int end): cdef GraphQLAstVisitor visitor ast = GraphQLAst.GraphQLAst%(name)s.create(node) if userData is not NULL: @@ -66,10 +66,10 @@ def end_file(self): retval = fun(ast) return 0 if retval is None else retval -cdef int visit_%(snake)s(%(cmodule)s.GraphQLAst%(name)s* node, void* userData): +cdef int visit_%(snake)s(const %(cmodule)s.GraphQLAst%(name)s* node, void* userData): return _visit_%(snake)s(node, userData, 0) -cdef void end_visit_%(snake)s(%(cmodule)s.GraphQLAst%(name)s* node, void* userData): +cdef void end_visit_%(snake)s(const %(cmodule)s.GraphQLAst%(name)s* node, void* userData): _visit_%(snake)s(node, userData, 1) ''' % _map diff --git a/examples/visitor_example.py b/examples/visitor_example.py index c2ef968..d0f883e 100644 --- a/examples/visitor_example.py +++ b/examples/visitor_example.py @@ -14,7 +14,7 @@ def visit_document(self, node): return 1 def visit_operation_definition(self, node): - print(node.__class__, node.get_operation(), node.get_name().get_value()) + print(node.__class__, node.get_operation()) return 1 def visit_variable_definition(self, node): @@ -65,7 +65,14 @@ def visit_int_value(self, node): print(node.__class__, node.get_value()) return 1 + def visit_string_value(self, node): + print(node.__class__, node.get_value()) + return 1 + if __name__ == '__main__': - query = sys.argv[1] - node = GraphQLParser.graphql_parse_string(query) + import argparse + parser = argparse.ArgumentParser(description='GraphQL parser example') + parser.add_argument('query') + args = parser.parse_args() + node = GraphQLParser.graphql_parse_string(args.query) Visitor().visit_node(node) diff --git a/graphql_parser/.gitignore b/graphql_parser/.gitignore index 61862a1..08be525 100644 --- a/graphql_parser/.gitignore +++ b/graphql_parser/.gitignore @@ -6,3 +6,6 @@ GraphQLAstVisitor.pyx *~ *.c .python-version +*.so +*.html +.pytest_cache diff --git a/graphql_parser/GraphQLParser.pyx b/graphql_parser/GraphQLParser.pyx index 41841bd..b20a83c 100644 --- a/graphql_parser/GraphQLParser.pyx +++ b/graphql_parser/GraphQLParser.pyx @@ -9,8 +9,8 @@ class GraphQLParseError(Exception): def graphql_parse_string(text): - cdef char* error_c = NULL - cdef char* text_c + cdef const char* error_c = NULL + cdef const char* text_c cdef cGraphQLAstNode.GraphQLAstNode* node_c byte_string = text.encode() text_c = byte_string diff --git a/graphql_parser/cGraphQLParser.pxd b/graphql_parser/cGraphQLParser.pxd index 83ac34e..6273e36 100644 --- a/graphql_parser/cGraphQLParser.pxd +++ b/graphql_parser/cGraphQLParser.pxd @@ -2,4 +2,4 @@ cdef extern from "GraphQLParser.h": struct GraphQLAstNode: pass - GraphQLAstNode* graphql_parse_string(char* text, char** error) + GraphQLAstNode* graphql_parse_string(const char* text, const char** error) diff --git a/libgraphqlparser b/libgraphqlparser index 50f7e8f..c934c79 160000 --- a/libgraphqlparser +++ b/libgraphqlparser @@ -1 +1 @@ -Subproject commit 50f7e8fe0e0d8ab137d5654c74abac5d69ac1f03 +Subproject commit c934c79feee69c5680a76118d737e3a81b3efb5c diff --git a/setup.py b/setup.py index f306b2b..36abd71 100644 --- a/setup.py +++ b/setup.py @@ -15,7 +15,7 @@ setup( name='graphqlparser', - version='0.0.3', + version='0.0.4', author='Marco Paolini', author_email='markopaolini@gmail.com', description='Python bindings for libgraphqlparser (Cython-based)',