From 116982ea89e85c046fbc3a48b8829e3c4d4a5c1a Mon Sep 17 00:00:00 2001 From: Masood Malekghassemi Date: Fri, 11 Dec 2015 15:53:38 -0800 Subject: [PATCH] Include core in Python distribution --- .gitignore | 9 +- MANIFEST.in | 8 + build.yaml | 4 + .../requirements.txt => requirements.txt | 0 src/python/grpcio/setup.cfg => setup.cfg | 0 src/python/grpcio/setup.py => setup.py | 42 ++-- src/python/grpcio/MANIFEST.in | 4 - src/python/grpcio/commands.py | 8 +- .../_cygrpc/{call.pxd => call.pxd.pxi} | 4 +- .../_cygrpc/{call.pyx => call.pyx.pxi} | 30 +-- .../_cygrpc/{channel.pxd => channel.pxd.pxi} | 4 +- .../_cygrpc/{channel.pyx => channel.pyx.pxi} | 44 ++-- ...ion_queue.pxd => completion_queue.pxd.pxi} | 6 +- ...ion_queue.pyx => completion_queue.pyx.pxi} | 56 ++--- .../{credentials.pxd => credentials.pxd.pxi} | 21 +- .../{credentials.pyx => credentials.pyx.pxi} | 59 +++-- .../_cython/_cygrpc/{grpc.pxd => grpc.pxi} | 0 .../_cygrpc/{records.pxd => records.pxd.pxi} | 34 ++- .../_cygrpc/{records.pyx => records.pyx.pxi} | 238 +++++++++--------- .../_cygrpc/{server.pxd => server.pxd.pxi} | 7 +- .../_cygrpc/{server.pyx => server.pyx.pxi} | 56 ++--- src/python/grpcio/grpc/_cython/cygrpc.pxd | 8 + src/python/grpcio/grpc/_cython/cygrpc.pyx | 84 +------ src/python/grpcio/grpc_core_dependencies.py | 195 ++++++++++++++ .../tests/unit/_cython/test_utilities.py | 2 +- src/python/grpcio/tox.ini | 19 -- .../grpcio/grpc_core_dependencies.py.template | 13 + .../plugins/transitive_dependencies.py | 6 +- tools/distrib/python/submit.py | 2 +- tools/jenkins/grpc_interop_python/Dockerfile | 1 + .../grpc_interop_python/build_interop.sh | 2 +- tools/run_tests/build_python.sh | 6 +- tools/run_tests/run_interop_tests.py | 8 +- tools/run_tests/run_python.sh | 6 +- tox.ini | 17 ++ 35 files changed, 563 insertions(+), 440 deletions(-) create mode 100644 MANIFEST.in rename src/python/grpcio/requirements.txt => requirements.txt (100%) rename src/python/grpcio/setup.cfg => setup.cfg (100%) rename src/python/grpcio/setup.py => setup.py (85%) delete mode 100644 src/python/grpcio/MANIFEST.in rename src/python/grpcio/grpc/_cython/_cygrpc/{call.pxd => call.pxd.pxi} (95%) rename src/python/grpcio/grpc/_cython/_cygrpc/{call.pyx => call.pyx.pxi} (77%) rename src/python/grpcio/grpc/_cython/_cygrpc/{channel.pxd => channel.pxd.pxi} (95%) rename src/python/grpcio/grpc/_cython/_cygrpc/{channel.pyx => channel.pyx.pxi} (72%) rename src/python/grpcio/grpc/_cython/_cygrpc/{completion_queue.pxd => completion_queue.pxd.pxi} (91%) rename src/python/grpcio/grpc/_cython/_cygrpc/{completion_queue.pyx => completion_queue.pyx.pxi} (77%) rename src/python/grpcio/grpc/_cython/_cygrpc/{credentials.pxd => credentials.pxd.pxi} (76%) rename src/python/grpcio/grpc/_cython/_cygrpc/{credentials.pyx => credentials.pyx.pxi} (83%) rename src/python/grpcio/grpc/_cython/_cygrpc/{grpc.pxd => grpc.pxi} (100%) rename src/python/grpcio/grpc/_cython/_cygrpc/{records.pxd => records.pxd.pxi} (80%) rename src/python/grpcio/grpc/_cython/_cygrpc/{records.pyx => records.pyx.pxi} (70%) rename src/python/grpcio/grpc/_cython/_cygrpc/{server.pxd => server.pxd.pxi} (90%) rename src/python/grpcio/grpc/_cython/_cygrpc/{server.pyx => server.pyx.pxi} (75%) create mode 100644 src/python/grpcio/grpc/_cython/cygrpc.pxd create mode 100644 src/python/grpcio/grpc_core_dependencies.py delete mode 100644 src/python/grpcio/tox.ini create mode 100644 templates/src/python/grpcio/grpc_core_dependencies.py.template create mode 100644 tox.ini diff --git a/.gitignore b/.gitignore index f059eca2393..471649d7a04 100644 --- a/.gitignore +++ b/.gitignore @@ -4,8 +4,13 @@ gens libs objs -# Python virtual environments -python*_virtual_environment +# Python items +.coverage* +.eggs +.tox +htmlcov/ +dist/ +*.egg # gcov coverage data reports diff --git a/MANIFEST.in b/MANIFEST.in new file mode 100644 index 00000000000..5b4ab04207a --- /dev/null +++ b/MANIFEST.in @@ -0,0 +1,8 @@ +graft src/python/grpcio/grpc +graft src/python/grpcio/tests +graft src/core +graft include/grpc +include src/python/grpcio/commands.py +include src/python/grpcio/grpc_core_dependencies.py +include src/python/grpcio/README.rst +include requirements.txt diff --git a/build.yaml b/build.yaml index 51d417ed0e2..4abef736d77 100644 --- a/build.yaml +++ b/build.yaml @@ -2474,3 +2474,7 @@ node_modules: - src/node/ext/server.cc - src/node/ext/server_credentials.cc - src/node/ext/timeval.cc +python_dependencies: + deps: + - grpc + - gpr diff --git a/src/python/grpcio/requirements.txt b/requirements.txt similarity index 100% rename from src/python/grpcio/requirements.txt rename to requirements.txt diff --git a/src/python/grpcio/setup.cfg b/setup.cfg similarity index 100% rename from src/python/grpcio/setup.cfg rename to setup.cfg diff --git a/src/python/grpcio/setup.py b/setup.py similarity index 85% rename from src/python/grpcio/setup.py rename to setup.py index 366ebe3b3fb..e0b0bf7622d 100644 --- a/src/python/grpcio/setup.py +++ b/setup.py @@ -37,11 +37,16 @@ from distutils import core as _core from distutils import extension as _extension import setuptools +PYTHON_STEM = './src/python/grpcio/' +CORE_INCLUDE = ('./include', './',) + # Ensure we're in the proper directory whether or not we're being used by pip. os.chdir(os.path.dirname(os.path.abspath(__file__))) +sys.path.insert(0, PYTHON_STEM) -# Break import-style to ensure we can actually find our commands module. +# Break import-style to ensure we can actually find our in-repo dependencies. import commands +import grpc_core_dependencies # Environment variable to determine whether or not the Cython extension should # *use* Cython or use the generated C files. Note that this requires the C files @@ -59,23 +64,13 @@ INSTALL_TESTS = os.environ.get('GRPC_PYTHON_INSTALL_TESTS', False) CYTHON_EXTENSION_PACKAGE_NAMES = () -CYTHON_EXTENSION_MODULE_NAMES = ( - 'grpc._cython.cygrpc', - 'grpc._cython._cygrpc.call', - 'grpc._cython._cygrpc.channel', - 'grpc._cython._cygrpc.completion_queue', - 'grpc._cython._cygrpc.credentials', - 'grpc._cython._cygrpc.records', - 'grpc._cython._cygrpc.server', -) +CYTHON_EXTENSION_MODULE_NAMES = ('grpc._cython.cygrpc',) -EXTENSION_INCLUDE_DIRECTORIES = ( - '.', -) +EXTENSION_INCLUDE_DIRECTORIES = (PYTHON_STEM,) + CORE_INCLUDE EXTENSION_LIBRARIES = ( - 'grpc', - 'gpr', + 'ssl', + 'crypto', ) if not "darwin" in sys.platform: EXTENSION_LIBRARIES += ('rt',) @@ -84,11 +79,13 @@ if not "darwin" in sys.platform: def cython_extensions(package_names, module_names, include_dirs, libraries, build_with_cython=False): file_extension = 'pyx' if build_with_cython else 'c' - module_files = [name.replace('.', '/') + '.' + file_extension + module_files = [os.path.join(PYTHON_STEM, + name.replace('.', '/') + '.' + file_extension) for name in module_names] extensions = [ _extension.Extension( - name=module_name, sources=[module_file], + name=module_name, + sources=[module_file] + grpc_core_dependencies.CORE_SOURCE_FILES, include_dirs=include_dirs, libraries=libraries, define_macros=[('CYTHON_TRACE_NOGIL', 1)] if ENABLE_CYTHON_TRACING else [] ) for (module_name, module_file) in zip(module_names, module_files) @@ -97,6 +94,7 @@ def cython_extensions(package_names, module_names, include_dirs, libraries, import Cython.Build return Cython.Build.cythonize( extensions, + include_path=include_dirs, compiler_directives={'linetrace': bool(ENABLE_CYTHON_TRACING)}) else: return extensions @@ -107,7 +105,7 @@ CYTHON_EXTENSION_MODULES = cython_extensions( bool(BUILD_WITH_CYTHON)) PACKAGE_DIRECTORIES = { - '': '.', + '': PYTHON_STEM, } INSTALL_REQUIRES = ( @@ -157,16 +155,18 @@ TEST_RUNNER = 'tests:Runner' PACKAGE_DATA = {} if INSTALL_TESTS: PACKAGE_DATA = dict(PACKAGE_DATA, **TEST_PACKAGE_DATA) - PACKAGES = setuptools.find_packages('.') + PACKAGES = setuptools.find_packages(PYTHON_STEM) else: - PACKAGES = setuptools.find_packages('.', exclude=['tests', 'tests.*']) + PACKAGES = setuptools.find_packages( + PYTHON_STEM, exclude=['tests', 'tests.*']) setuptools.setup( name='grpcio', - version='0.12.0b0', + version='0.12.0b1', ext_modules=CYTHON_EXTENSION_MODULES, packages=list(PACKAGES), package_dir=PACKAGE_DIRECTORIES, + package_data=PACKAGE_DATA, install_requires=INSTALL_REQUIRES, setup_requires=SETUP_REQUIRES, cmdclass=COMMAND_CLASS, diff --git a/src/python/grpcio/MANIFEST.in b/src/python/grpcio/MANIFEST.in deleted file mode 100644 index 407eeabc179..00000000000 --- a/src/python/grpcio/MANIFEST.in +++ /dev/null @@ -1,4 +0,0 @@ -graft grpc -graft tests -include commands.py -include requirements.txt diff --git a/src/python/grpcio/commands.py b/src/python/grpcio/commands.py index d9fd023b214..7450e5b455e 100644 --- a/src/python/grpcio/commands.py +++ b/src/python/grpcio/commands.py @@ -40,6 +40,8 @@ import setuptools from setuptools.command import build_py from setuptools.command import test +PYTHON_STEM = os.path.dirname(os.path.abspath(__file__)) + CONF_PY_ADDENDUM = """ extensions.append('sphinx.ext.napoleon') napoleon_google_docstring = True @@ -68,7 +70,7 @@ class SphinxDocumentation(setuptools.Command): import sphinx.apidoc metadata = self.distribution.metadata src_dir = os.path.join( - os.getcwd(), self.distribution.package_dir[''], 'grpc') + PYTHON_STEM, self.distribution.package_dir[''], 'grpc') sys.path.append(src_dir) sphinx.apidoc.main([ '', '--force', '--full', '-H', metadata.name, '-A', metadata.author, @@ -104,7 +106,7 @@ class BuildProtoModules(setuptools.Command): include_regex = re.compile(self.include) exclude_regex = re.compile(self.exclude) if self.exclude else None paths = [] - root_directory = os.getcwd() + root_directory = PYTHON_STEM for walk_root, directories, filenames in os.walk(root_directory): for filename in filenames: path = os.path.join(walk_root, filename) @@ -140,7 +142,7 @@ class BuildProjectMetadata(setuptools.Command): pass def run(self): - with open('grpc/_grpcio_metadata.py', 'w') as module_file: + with open(os.path.join(PYTHON_STEM, 'grpc/_grpcio_metadata.py'), 'w') as module_file: module_file.write('__version__ = """{}"""'.format( self.distribution.get_version())) diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/call.pxd b/src/python/grpcio/grpc/_cython/_cygrpc/call.pxd.pxi similarity index 95% rename from src/python/grpcio/grpc/_cython/_cygrpc/call.pxd rename to src/python/grpcio/grpc/_cython/_cygrpc/call.pxd.pxi index fe9b81e3d3a..6a316746fbd 100644 --- a/src/python/grpcio/grpc/_cython/_cygrpc/call.pxd +++ b/src/python/grpcio/grpc/_cython/_cygrpc/call.pxd.pxi @@ -27,11 +27,9 @@ # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -from grpc._cython._cygrpc cimport grpc - cdef class Call: - cdef grpc.grpc_call *c_call + cdef grpc_call *c_call cdef list references diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/call.pyx b/src/python/grpcio/grpc/_cython/_cygrpc/call.pyx.pxi similarity index 77% rename from src/python/grpcio/grpc/_cython/_cygrpc/call.pyx rename to src/python/grpcio/grpc/_cython/_cygrpc/call.pyx.pxi index 1c07f9f4f4c..80f4da51e8c 100644 --- a/src/python/grpcio/grpc/_cython/_cygrpc/call.pyx +++ b/src/python/grpcio/grpc/_cython/_cygrpc/call.pyx.pxi @@ -29,10 +29,6 @@ cimport cpython -from grpc._cython._cygrpc cimport credentials -from grpc._cython._cygrpc cimport grpc -from grpc._cython._cygrpc cimport records - cdef class Call: @@ -44,24 +40,24 @@ cdef class Call: def start_batch(self, operations, tag): if not self.is_valid: raise ValueError("invalid call object cannot be used from Python") - cdef records.Operations cy_operations = records.Operations(operations) - cdef records.OperationTag operation_tag = records.OperationTag(tag) + cdef Operations cy_operations = Operations(operations) + cdef OperationTag operation_tag = OperationTag(tag) operation_tag.operation_call = self operation_tag.batch_operations = cy_operations cpython.Py_INCREF(operation_tag) - return grpc.grpc_call_start_batch( + return grpc_call_start_batch( self.c_call, cy_operations.c_ops, cy_operations.c_nops, operation_tag, NULL) def cancel( - self, grpc.grpc_status_code error_code=grpc.GRPC_STATUS__DO_NOT_USE, + self, grpc_status_code error_code=GRPC_STATUS__DO_NOT_USE, details=None): if not self.is_valid: raise ValueError("invalid call object cannot be used from Python") - if (details is None) != (error_code == grpc.GRPC_STATUS__DO_NOT_USE): + if (details is None) != (error_code == GRPC_STATUS__DO_NOT_USE): raise ValueError("if error_code is specified, so must details " "(and vice-versa)") - if error_code != grpc.GRPC_STATUS__DO_NOT_USE: + if error_code != GRPC_STATUS__DO_NOT_USE: if isinstance(details, bytes): pass elif isinstance(details, basestring): @@ -69,25 +65,25 @@ cdef class Call: else: raise TypeError("expected details to be str or bytes") self.references.append(details) - return grpc.grpc_call_cancel_with_status( + return grpc_call_cancel_with_status( self.c_call, error_code, details, NULL) else: - return grpc.grpc_call_cancel(self.c_call, NULL) + return grpc_call_cancel(self.c_call, NULL) def set_credentials( - self, credentials.CallCredentials call_credentials not None): - return grpc.grpc_call_set_credentials( + self, CallCredentials call_credentials not None): + return grpc_call_set_credentials( self.c_call, call_credentials.c_credentials) def peer(self): - cdef char *peer = grpc.grpc_call_get_peer(self.c_call) + cdef char *peer = grpc_call_get_peer(self.c_call) result = peer - grpc.gpr_free(peer) + gpr_free(peer) return result def __dealloc__(self): if self.c_call != NULL: - grpc.grpc_call_destroy(self.c_call) + grpc_call_destroy(self.c_call) # The object *should* always be valid from Python. Used for debugging. @property diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/channel.pxd b/src/python/grpcio/grpc/_cython/_cygrpc/channel.pxd.pxi similarity index 95% rename from src/python/grpcio/grpc/_cython/_cygrpc/channel.pxd rename to src/python/grpcio/grpc/_cython/_cygrpc/channel.pxd.pxi index 3e341bf2225..70da63db978 100644 --- a/src/python/grpcio/grpc/_cython/_cygrpc/channel.pxd +++ b/src/python/grpcio/grpc/_cython/_cygrpc/channel.pxd.pxi @@ -27,10 +27,8 @@ # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -from grpc._cython._cygrpc cimport grpc - cdef class Channel: - cdef grpc.grpc_channel *c_channel + cdef grpc_channel *c_channel cdef list references diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/channel.pyx b/src/python/grpcio/grpc/_cython/_cygrpc/channel.pyx.pxi similarity index 72% rename from src/python/grpcio/grpc/_cython/_cygrpc/channel.pyx rename to src/python/grpcio/grpc/_cython/_cygrpc/channel.pyx.pxi index a944a83576c..ac67f32d923 100644 --- a/src/python/grpcio/grpc/_cython/_cygrpc/channel.pyx +++ b/src/python/grpcio/grpc/_cython/_cygrpc/channel.pyx.pxi @@ -29,18 +29,12 @@ cimport cpython -from grpc._cython._cygrpc cimport call -from grpc._cython._cygrpc cimport completion_queue -from grpc._cython._cygrpc cimport credentials -from grpc._cython._cygrpc cimport grpc -from grpc._cython._cygrpc cimport records - cdef class Channel: - def __cinit__(self, target, records.ChannelArgs arguments=None, - credentials.ChannelCredentials channel_credentials=None): - cdef grpc.grpc_channel_args *c_arguments = NULL + def __cinit__(self, target, ChannelArgs arguments=None, + ChannelCredentials channel_credentials=None): + cdef grpc_channel_args *c_arguments = NULL self.c_channel = NULL self.references = [] if arguments is not None: @@ -52,18 +46,18 @@ cdef class Channel: else: raise TypeError("expected target to be str or bytes") if channel_credentials is None: - self.c_channel = grpc.grpc_insecure_channel_create(target, c_arguments, + self.c_channel = grpc_insecure_channel_create(target, c_arguments, NULL) else: - self.c_channel = grpc.grpc_secure_channel_create( + self.c_channel = grpc_secure_channel_create( channel_credentials.c_credentials, target, c_arguments, NULL) self.references.append(channel_credentials) self.references.append(target) self.references.append(arguments) - def create_call(self, call.Call parent, int flags, - completion_queue.CompletionQueue queue not None, - method, host, records.Timespec deadline not None): + def create_call(self, Call parent, int flags, + CompletionQueue queue not None, + method, host, Timespec deadline not None): if queue.is_shutting_down: raise ValueError("queue must not be shutting down or shutdown") if isinstance(method, bytes): @@ -82,36 +76,36 @@ cdef class Channel: host_c_string = host else: raise TypeError("expected host to be str, bytes, or None") - cdef call.Call operation_call = call.Call() + cdef Call operation_call = Call() operation_call.references = [self, method, host, queue] - cdef grpc.grpc_call *parent_call = NULL + cdef grpc_call *parent_call = NULL if parent is not None: parent_call = parent.c_call - operation_call.c_call = grpc.grpc_channel_create_call( + operation_call.c_call = grpc_channel_create_call( self.c_channel, parent_call, flags, queue.c_completion_queue, method, host_c_string, deadline.c_time, NULL) return operation_call def check_connectivity_state(self, bint try_to_connect): - return grpc.grpc_channel_check_connectivity_state(self.c_channel, + return grpc_channel_check_connectivity_state(self.c_channel, try_to_connect) def watch_connectivity_state( - self, last_observed_state, records.Timespec deadline not None, - completion_queue.CompletionQueue queue not None, tag): - cdef records.OperationTag operation_tag = records.OperationTag(tag) + self, last_observed_state, Timespec deadline not None, + CompletionQueue queue not None, tag): + cdef OperationTag operation_tag = OperationTag(tag) cpython.Py_INCREF(operation_tag) - grpc.grpc_channel_watch_connectivity_state( + grpc_channel_watch_connectivity_state( self.c_channel, last_observed_state, deadline.c_time, queue.c_completion_queue, operation_tag) def target(self): - cdef char * target = grpc.grpc_channel_get_target(self.c_channel) + cdef char * target = grpc_channel_get_target(self.c_channel) result = target - grpc.gpr_free(target) + gpr_free(target) return result def __dealloc__(self): if self.c_channel != NULL: - grpc.grpc_channel_destroy(self.c_channel) + grpc_channel_destroy(self.c_channel) diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/completion_queue.pxd b/src/python/grpcio/grpc/_cython/_cygrpc/completion_queue.pxd.pxi similarity index 91% rename from src/python/grpcio/grpc/_cython/_cygrpc/completion_queue.pxd rename to src/python/grpcio/grpc/_cython/_cygrpc/completion_queue.pxd.pxi index 1ed5d4b2299..757f1245e85 100644 --- a/src/python/grpcio/grpc/_cython/_cygrpc/completion_queue.pxd +++ b/src/python/grpcio/grpc/_cython/_cygrpc/completion_queue.pxd.pxi @@ -27,15 +27,13 @@ # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -from grpc._cython._cygrpc cimport grpc - cdef class CompletionQueue: - cdef grpc.grpc_completion_queue *c_completion_queue + cdef grpc_completion_queue *c_completion_queue cdef object poll_condition cdef bint is_polling cdef bint is_shutting_down cdef bint is_shutdown - cdef _interpret_event(self, grpc.grpc_event event) + cdef _interpret_event(self, grpc_event event) diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/completion_queue.pyx b/src/python/grpcio/grpc/_cython/_cygrpc/completion_queue.pyx.pxi similarity index 77% rename from src/python/grpcio/grpc/_cython/_cygrpc/completion_queue.pyx rename to src/python/grpcio/grpc/_cython/_cygrpc/completion_queue.pyx.pxi index 635a38fe28e..bbf84132993 100644 --- a/src/python/grpcio/grpc/_cython/_cygrpc/completion_queue.pyx +++ b/src/python/grpcio/grpc/_cython/_cygrpc/completion_queue.pyx.pxi @@ -29,10 +29,6 @@ cimport cpython -from grpc._cython._cygrpc cimport call -from grpc._cython._cygrpc cimport grpc -from grpc._cython._cygrpc cimport records - import threading import time @@ -40,29 +36,29 @@ import time cdef class CompletionQueue: def __cinit__(self): - self.c_completion_queue = grpc.grpc_completion_queue_create(NULL) + self.c_completion_queue = grpc_completion_queue_create(NULL) self.is_shutting_down = False self.is_shutdown = False self.poll_condition = threading.Condition() self.is_polling = False - cdef _interpret_event(self, grpc.grpc_event event): - cdef records.OperationTag tag = None + cdef _interpret_event(self, grpc_event event): + cdef OperationTag tag = None cdef object user_tag = None - cdef call.Call operation_call = None - cdef records.CallDetails request_call_details = None - cdef records.Metadata request_metadata = None - cdef records.Operations batch_operations = None - if event.type == grpc.GRPC_QUEUE_TIMEOUT: - return records.Event( + cdef Call operation_call = None + cdef CallDetails request_call_details = None + cdef Metadata request_metadata = None + cdef Operations batch_operations = None + if event.type == GRPC_QUEUE_TIMEOUT: + return Event( event.type, False, None, None, None, None, False, None) - elif event.type == grpc.GRPC_QUEUE_SHUTDOWN: + elif event.type == GRPC_QUEUE_SHUTDOWN: self.is_shutdown = True - return records.Event( + return Event( event.type, True, None, None, None, None, False, None) else: if event.tag != NULL: - tag = event.tag + tag = event.tag # We receive event tags only after they've been inc-ref'd elsewhere in # the code. cpython.Py_DECREF(tag) @@ -77,19 +73,19 @@ cdef class CompletionQueue: # Stuff in the tag not explicitly handled by us needs to live through # the life of the call operation_call.references.extend(tag.references) - return records.Event( + return Event( event.type, event.success, user_tag, operation_call, request_call_details, request_metadata, tag.is_new_request, batch_operations) - def poll(self, records.Timespec deadline=None): + def poll(self, Timespec deadline=None): # We name this 'poll' to avoid problems with CPython's expectations for # 'special' methods (like next and __next__). - cdef grpc.gpr_timespec c_deadline = grpc.gpr_inf_future( - grpc.GPR_CLOCK_REALTIME) + cdef gpr_timespec c_deadline = gpr_inf_future( + GPR_CLOCK_REALTIME) if deadline is not None: c_deadline = deadline.c_time - cdef grpc.grpc_event event + cdef grpc_event event # Poll within a critical section # TODO(atash) consider making queue polling contention a hard error to @@ -99,21 +95,21 @@ cdef class CompletionQueue: self.poll_condition.wait(float(deadline) - time.time()) self.is_polling = True with nogil: - event = grpc.grpc_completion_queue_next( + event = grpc_completion_queue_next( self.c_completion_queue, c_deadline, NULL) with self.poll_condition: self.is_polling = False self.poll_condition.notify() return self._interpret_event(event) - def pluck(self, records.OperationTag tag, records.Timespec deadline=None): + def pluck(self, OperationTag tag, Timespec deadline=None): # Plucking a 'None' tag is equivalent to passing control to GRPC core until # the deadline. - cdef grpc.gpr_timespec c_deadline = grpc.gpr_inf_future( - grpc.GPR_CLOCK_REALTIME) + cdef gpr_timespec c_deadline = gpr_inf_future( + GPR_CLOCK_REALTIME) if deadline is not None: c_deadline = deadline.c_time - cdef grpc.grpc_event event + cdef grpc_event event # Poll within a critical section # TODO(atash) consider making queue polling contention a hard error to @@ -123,7 +119,7 @@ cdef class CompletionQueue: self.poll_condition.wait(float(deadline) - time.time()) self.is_polling = True with nogil: - event = grpc.grpc_completion_queue_pluck( + event = grpc_completion_queue_pluck( self.c_completion_queue, tag, c_deadline, NULL) with self.poll_condition: self.is_polling = False @@ -131,13 +127,13 @@ cdef class CompletionQueue: return self._interpret_event(event) def shutdown(self): - grpc.grpc_completion_queue_shutdown(self.c_completion_queue) + grpc_completion_queue_shutdown(self.c_completion_queue) self.is_shutting_down = True def clear(self): if not self.is_shutting_down: raise ValueError('queue must be shutting down to be cleared') - while self.poll().type != grpc.GRPC_QUEUE_SHUTDOWN: + while self.poll().type != GRPC_QUEUE_SHUTDOWN: pass def __dealloc__(self): @@ -147,4 +143,4 @@ cdef class CompletionQueue: self.shutdown() while not self.is_shutdown: self.poll() - grpc.grpc_completion_queue_destroy(self.c_completion_queue) + grpc_completion_queue_destroy(self.c_completion_queue) diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/credentials.pxd b/src/python/grpcio/grpc/_cython/_cygrpc/credentials.pxd.pxi similarity index 76% rename from src/python/grpcio/grpc/_cython/_cygrpc/credentials.pxd rename to src/python/grpcio/grpc/_cython/_cygrpc/credentials.pxd.pxi index db9f8ddec99..c793c8f5e58 100644 --- a/src/python/grpcio/grpc/_cython/_cygrpc/credentials.pxd +++ b/src/python/grpcio/grpc/_cython/_cygrpc/credentials.pxd.pxi @@ -29,27 +29,24 @@ cimport cpython -from grpc._cython._cygrpc cimport grpc -from grpc._cython._cygrpc cimport records - cdef class ChannelCredentials: - cdef grpc.grpc_channel_credentials *c_credentials - cdef grpc.grpc_ssl_pem_key_cert_pair c_ssl_pem_key_cert_pair + cdef grpc_channel_credentials *c_credentials + cdef grpc_ssl_pem_key_cert_pair c_ssl_pem_key_cert_pair cdef list references cdef class CallCredentials: - cdef grpc.grpc_call_credentials *c_credentials + cdef grpc_call_credentials *c_credentials cdef list references cdef class ServerCredentials: - cdef grpc.grpc_server_credentials *c_credentials - cdef grpc.grpc_ssl_pem_key_cert_pair *c_ssl_pem_key_cert_pairs + cdef grpc_server_credentials *c_credentials + cdef grpc_ssl_pem_key_cert_pair *c_ssl_pem_key_cert_pairs cdef size_t c_ssl_pem_key_cert_pairs_count cdef list references @@ -59,16 +56,16 @@ cdef class CredentialsMetadataPlugin: cdef object plugin_callback cdef str plugin_name - cdef grpc.grpc_metadata_credentials_plugin make_c_plugin(self) + cdef grpc_metadata_credentials_plugin make_c_plugin(self) cdef class AuthMetadataContext: - cdef grpc.grpc_auth_metadata_context context + cdef grpc_auth_metadata_context context cdef void plugin_get_metadata( - void *state, grpc.grpc_auth_metadata_context context, - grpc.grpc_credentials_plugin_metadata_cb cb, void *user_data) with gil + void *state, grpc_auth_metadata_context context, + grpc_credentials_plugin_metadata_cb cb, void *user_data) with gil cdef void plugin_destroy_c_plugin_state(void *state) diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/credentials.pyx b/src/python/grpcio/grpc/_cython/_cygrpc/credentials.pyx.pxi similarity index 83% rename from src/python/grpcio/grpc/_cython/_cygrpc/credentials.pyx rename to src/python/grpcio/grpc/_cython/_cygrpc/credentials.pyx.pxi index a968894967a..3f439c8900f 100644 --- a/src/python/grpcio/grpc/_cython/_cygrpc/credentials.pyx +++ b/src/python/grpcio/grpc/_cython/_cygrpc/credentials.pyx.pxi @@ -29,9 +29,6 @@ cimport cpython -from grpc._cython._cygrpc cimport grpc -from grpc._cython._cygrpc cimport records - cdef class ChannelCredentials: @@ -49,7 +46,7 @@ cdef class ChannelCredentials: def __dealloc__(self): if self.c_credentials != NULL: - grpc.grpc_channel_credentials_release(self.c_credentials) + grpc_channel_credentials_release(self.c_credentials) cdef class CallCredentials: @@ -66,7 +63,7 @@ cdef class CallCredentials: def __dealloc__(self): if self.c_credentials != NULL: - grpc.grpc_call_credentials_release(self.c_credentials) + grpc_call_credentials_release(self.c_credentials) cdef class ServerCredentials: @@ -77,7 +74,7 @@ cdef class ServerCredentials: def __dealloc__(self): if self.c_credentials != NULL: - grpc.grpc_server_credentials_release(self.c_credentials) + grpc_server_credentials_release(self.c_credentials) cdef class CredentialsMetadataPlugin: @@ -86,8 +83,8 @@ cdef class CredentialsMetadataPlugin: """ Args: plugin_callback (callable): Callback accepting a service URL (str/bytes) - and callback object (accepting a records.Metadata, - grpc.grpc_status_code, and a str/bytes error message). This argument + and callback object (accepting a Metadata, + grpc_status_code, and a str/bytes error message). This argument when called should be non-blocking and eventually call the callback object with the appropriate status code/details and metadata (if successful). @@ -99,8 +96,8 @@ cdef class CredentialsMetadataPlugin: self.plugin_name = name @staticmethod - cdef grpc.grpc_metadata_credentials_plugin make_c_plugin(self): - cdef grpc.grpc_metadata_credentials_plugin result + cdef grpc_metadata_credentials_plugin make_c_plugin(self): + cdef grpc_metadata_credentials_plugin result result.get_metadata = plugin_get_metadata result.destroy = plugin_destroy_c_plugin_state result.state = self @@ -125,10 +122,10 @@ cdef class AuthMetadataContext: cdef void plugin_get_metadata( - void *state, grpc.grpc_auth_metadata_context context, - grpc.grpc_credentials_plugin_metadata_cb cb, void *user_data) with gil: + void *state, grpc_auth_metadata_context context, + grpc_credentials_plugin_metadata_cb cb, void *user_data) with gil: def python_callback( - records.Metadata metadata, grpc.grpc_status_code status, + Metadata metadata, grpc_status_code status, const char *error_details): cb(user_data, metadata.c_metadata_array.metadata, metadata.c_metadata_array.count, status, error_details) @@ -142,11 +139,11 @@ cdef void plugin_destroy_c_plugin_state(void *state): def channel_credentials_google_default(): cdef ChannelCredentials credentials = ChannelCredentials(); - credentials.c_credentials = grpc.grpc_google_default_credentials_create() + credentials.c_credentials = grpc_google_default_credentials_create() return credentials def channel_credentials_ssl(pem_root_certificates, - records.SslPemKeyCertPair ssl_pem_key_cert_pair): + SslPemKeyCertPair ssl_pem_key_cert_pair): if pem_root_certificates is None: pass elif isinstance(pem_root_certificates, bytes): @@ -161,11 +158,11 @@ def channel_credentials_ssl(pem_root_certificates, c_pem_root_certificates = pem_root_certificates credentials.references.append(pem_root_certificates) if ssl_pem_key_cert_pair is not None: - credentials.c_credentials = grpc.grpc_ssl_credentials_create( + credentials.c_credentials = grpc_ssl_credentials_create( c_pem_root_certificates, &ssl_pem_key_cert_pair.c_pair, NULL) credentials.references.append(ssl_pem_key_cert_pair) else: - credentials.c_credentials = grpc.grpc_ssl_credentials_create( + credentials.c_credentials = grpc_ssl_credentials_create( c_pem_root_certificates, NULL, NULL) return credentials @@ -175,7 +172,7 @@ def channel_credentials_composite( if not credentials_1.is_valid or not credentials_2.is_valid: raise ValueError("passed credentials must both be valid") cdef ChannelCredentials credentials = ChannelCredentials() - credentials.c_credentials = grpc.grpc_composite_channel_credentials_create( + credentials.c_credentials = grpc_composite_channel_credentials_create( credentials_1.c_credentials, credentials_2.c_credentials, NULL) credentials.references.append(credentials_1) credentials.references.append(credentials_2) @@ -187,7 +184,7 @@ def call_credentials_composite( if not credentials_1.is_valid or not credentials_2.is_valid: raise ValueError("passed credentials must both be valid") cdef CallCredentials credentials = CallCredentials() - credentials.c_credentials = grpc.grpc_composite_call_credentials_create( + credentials.c_credentials = grpc_composite_call_credentials_create( credentials_1.c_credentials, credentials_2.c_credentials, NULL) credentials.references.append(credentials_1) credentials.references.append(credentials_2) @@ -196,11 +193,11 @@ def call_credentials_composite( def call_credentials_google_compute_engine(): cdef CallCredentials credentials = CallCredentials() credentials.c_credentials = ( - grpc.grpc_google_compute_engine_credentials_create(NULL)) + grpc_google_compute_engine_credentials_create(NULL)) return credentials def call_credentials_service_account_jwt_access( - json_key, records.Timespec token_lifetime not None): + json_key, Timespec token_lifetime not None): if isinstance(json_key, bytes): pass elif isinstance(json_key, basestring): @@ -209,7 +206,7 @@ def call_credentials_service_account_jwt_access( raise TypeError("expected json_key to be str or bytes") cdef CallCredentials credentials = CallCredentials() credentials.c_credentials = ( - grpc.grpc_service_account_jwt_access_credentials_create( + grpc_service_account_jwt_access_credentials_create( json_key, token_lifetime.c_time, NULL)) credentials.references.append(json_key) return credentials @@ -222,7 +219,7 @@ def call_credentials_google_refresh_token(json_refresh_token): else: raise TypeError("expected json_refresh_token to be str or bytes") cdef CallCredentials credentials = CallCredentials() - credentials.c_credentials = grpc.grpc_google_refresh_token_credentials_create( + credentials.c_credentials = grpc_google_refresh_token_credentials_create( json_refresh_token, NULL) credentials.references.append(json_refresh_token) return credentials @@ -241,7 +238,7 @@ def call_credentials_google_iam(authorization_token, authority_selector): else: raise TypeError("expected authority_selector to be str or bytes") cdef CallCredentials credentials = CallCredentials() - credentials.c_credentials = grpc.grpc_google_iam_credentials_create( + credentials.c_credentials = grpc_google_iam_credentials_create( authorization_token, authority_selector, NULL) credentials.references.append(authorization_token) credentials.references.append(authority_selector) @@ -250,7 +247,7 @@ def call_credentials_google_iam(authorization_token, authority_selector): def call_credentials_metadata_plugin(CredentialsMetadataPlugin plugin): cdef CallCredentials credentials = CallCredentials() credentials.c_credentials = ( - grpc.grpc_metadata_credentials_create_from_plugin(plugin.make_c_plugin(), + grpc_metadata_credentials_create_from_plugin(plugin.make_c_plugin(), NULL)) # TODO(atash): the following held reference is *probably* never necessary credentials.references.append(plugin) @@ -270,22 +267,22 @@ def server_credentials_ssl(pem_root_certs, pem_key_cert_pairs, raise TypeError("expected pem_root_certs to be str or bytes") pem_key_cert_pairs = list(pem_key_cert_pairs) for pair in pem_key_cert_pairs: - if not isinstance(pair, records.SslPemKeyCertPair): + if not isinstance(pair, SslPemKeyCertPair): raise TypeError("expected pem_key_cert_pairs to be sequence of " - "records.SslPemKeyCertPair") + "SslPemKeyCertPair") cdef ServerCredentials credentials = ServerCredentials() credentials.references.append(pem_key_cert_pairs) credentials.references.append(pem_root_certs) credentials.c_ssl_pem_key_cert_pairs_count = len(pem_key_cert_pairs) credentials.c_ssl_pem_key_cert_pairs = ( - grpc.gpr_malloc( - sizeof(grpc.grpc_ssl_pem_key_cert_pair) * + gpr_malloc( + sizeof(grpc_ssl_pem_key_cert_pair) * credentials.c_ssl_pem_key_cert_pairs_count )) for i in range(credentials.c_ssl_pem_key_cert_pairs_count): credentials.c_ssl_pem_key_cert_pairs[i] = ( - (pem_key_cert_pairs[i]).c_pair) - credentials.c_credentials = grpc.grpc_ssl_server_credentials_create( + (pem_key_cert_pairs[i]).c_pair) + credentials.c_credentials = grpc_ssl_server_credentials_create( c_pem_root_certs, credentials.c_ssl_pem_key_cert_pairs, credentials.c_ssl_pem_key_cert_pairs_count, force_client_auth, NULL) return credentials diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/grpc.pxd b/src/python/grpcio/grpc/_cython/_cygrpc/grpc.pxi similarity index 100% rename from src/python/grpcio/grpc/_cython/_cygrpc/grpc.pxd rename to src/python/grpcio/grpc/_cython/_cygrpc/grpc.pxi diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/records.pxd b/src/python/grpcio/grpc/_cython/_cygrpc/records.pxd.pxi similarity index 80% rename from src/python/grpcio/grpc/_cython/_cygrpc/records.pxd rename to src/python/grpcio/grpc/_cython/_cygrpc/records.pxd.pxi index 4c844e4cb6c..30397818a15 100644 --- a/src/python/grpcio/grpc/_cython/_cygrpc/records.pxd +++ b/src/python/grpcio/grpc/_cython/_cygrpc/records.pxd.pxi @@ -27,19 +27,15 @@ # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -from grpc._cython._cygrpc cimport grpc -from grpc._cython._cygrpc cimport call -from grpc._cython._cygrpc cimport server - cdef class Timespec: - cdef grpc.gpr_timespec c_time + cdef gpr_timespec c_time cdef class CallDetails: - cdef grpc.grpc_call_details c_details + cdef grpc_call_details c_details cdef class OperationTag: @@ -48,8 +44,8 @@ cdef class OperationTag: cdef list references # This allows CompletionQueue to notify the Python Server object that the # underlying GRPC core server has shutdown - cdef server.Server shutting_down_server - cdef call.Call operation_call + cdef Server shutting_down_server + cdef Call operation_call cdef CallDetails request_call_details cdef Metadata request_metadata cdef Operations batch_operations @@ -58,12 +54,12 @@ cdef class OperationTag: cdef class Event: - cdef readonly grpc.grpc_completion_type type + cdef readonly grpc_completion_type type cdef readonly bint success cdef readonly object tag # For operations with calls - cdef readonly call.Call operation_call + cdef readonly Call operation_call # For Server.request_call cdef readonly bint is_new_request @@ -76,45 +72,45 @@ cdef class Event: cdef class ByteBuffer: - cdef grpc.grpc_byte_buffer *c_byte_buffer + cdef grpc_byte_buffer *c_byte_buffer cdef class SslPemKeyCertPair: - cdef grpc.grpc_ssl_pem_key_cert_pair c_pair + cdef grpc_ssl_pem_key_cert_pair c_pair cdef readonly object private_key, certificate_chain cdef class ChannelArg: - cdef grpc.grpc_arg c_arg + cdef grpc_arg c_arg cdef readonly object key, value cdef class ChannelArgs: - cdef grpc.grpc_channel_args c_args + cdef grpc_channel_args c_args cdef list args cdef class Metadatum: - cdef grpc.grpc_metadata c_metadata + cdef grpc_metadata c_metadata cdef object _key, _value cdef class Metadata: - cdef grpc.grpc_metadata_array c_metadata_array + cdef grpc_metadata_array c_metadata_array cdef object metadata cdef class Operation: - cdef grpc.grpc_op c_op + cdef grpc_op c_op cdef ByteBuffer _received_message cdef Metadata _received_metadata - cdef grpc.grpc_status_code _received_status_code + cdef grpc_status_code _received_status_code cdef char *_received_status_details cdef size_t _received_status_details_capacity cdef int _received_cancelled @@ -124,7 +120,7 @@ cdef class Operation: cdef class Operations: - cdef grpc.grpc_op *c_ops + cdef grpc_op *c_ops cdef size_t c_nops cdef list operations diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/records.pyx b/src/python/grpcio/grpc/_cython/_cygrpc/records.pyx.pxi similarity index 70% rename from src/python/grpcio/grpc/_cython/_cygrpc/records.pyx rename to src/python/grpcio/grpc/_cython/_cygrpc/records.pyx.pxi index 79a7f8f563b..d7ad9e5215b 100644 --- a/src/python/grpcio/grpc/_cython/_cygrpc/records.pyx +++ b/src/python/grpcio/grpc/_cython/_cygrpc/records.pyx.pxi @@ -27,103 +27,99 @@ # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -from grpc._cython._cygrpc cimport grpc -from grpc._cython._cygrpc cimport call -from grpc._cython._cygrpc cimport server - class ConnectivityState: - idle = grpc.GRPC_CHANNEL_IDLE - connecting = grpc.GRPC_CHANNEL_CONNECTING - ready = grpc.GRPC_CHANNEL_READY - transient_failure = grpc.GRPC_CHANNEL_TRANSIENT_FAILURE - fatal_failure = grpc.GRPC_CHANNEL_FATAL_FAILURE + idle = GRPC_CHANNEL_IDLE + connecting = GRPC_CHANNEL_CONNECTING + ready = GRPC_CHANNEL_READY + transient_failure = GRPC_CHANNEL_TRANSIENT_FAILURE + fatal_failure = GRPC_CHANNEL_FATAL_FAILURE class ChannelArgKey: - enable_census = grpc.GRPC_ARG_ENABLE_CENSUS - max_concurrent_streams = grpc.GRPC_ARG_MAX_CONCURRENT_STREAMS - max_message_length = grpc.GRPC_ARG_MAX_MESSAGE_LENGTH - http2_initial_sequence_number = grpc.GRPC_ARG_HTTP2_INITIAL_SEQUENCE_NUMBER - default_authority = grpc.GRPC_ARG_DEFAULT_AUTHORITY - primary_user_agent_string = grpc.GRPC_ARG_PRIMARY_USER_AGENT_STRING - secondary_user_agent_string = grpc.GRPC_ARG_SECONDARY_USER_AGENT_STRING - ssl_target_name_override = grpc.GRPC_SSL_TARGET_NAME_OVERRIDE_ARG + enable_census = GRPC_ARG_ENABLE_CENSUS + max_concurrent_streams = GRPC_ARG_MAX_CONCURRENT_STREAMS + max_message_length = GRPC_ARG_MAX_MESSAGE_LENGTH + http2_initial_sequence_number = GRPC_ARG_HTTP2_INITIAL_SEQUENCE_NUMBER + default_authority = GRPC_ARG_DEFAULT_AUTHORITY + primary_user_agent_string = GRPC_ARG_PRIMARY_USER_AGENT_STRING + secondary_user_agent_string = GRPC_ARG_SECONDARY_USER_AGENT_STRING + ssl_target_name_override = GRPC_SSL_TARGET_NAME_OVERRIDE_ARG class WriteFlag: - buffer_hint = grpc.GRPC_WRITE_BUFFER_HINT - no_compress = grpc.GRPC_WRITE_NO_COMPRESS + buffer_hint = GRPC_WRITE_BUFFER_HINT + no_compress = GRPC_WRITE_NO_COMPRESS class StatusCode: - ok = grpc.GRPC_STATUS_OK - cancelled = grpc.GRPC_STATUS_CANCELLED - unknown = grpc.GRPC_STATUS_UNKNOWN - invalid_argument = grpc.GRPC_STATUS_INVALID_ARGUMENT - deadline_exceeded = grpc.GRPC_STATUS_DEADLINE_EXCEEDED - not_found = grpc.GRPC_STATUS_NOT_FOUND - already_exists = grpc.GRPC_STATUS_ALREADY_EXISTS - permission_denied = grpc.GRPC_STATUS_PERMISSION_DENIED - unauthenticated = grpc.GRPC_STATUS_UNAUTHENTICATED - resource_exhausted = grpc.GRPC_STATUS_RESOURCE_EXHAUSTED - failed_precondition = grpc.GRPC_STATUS_FAILED_PRECONDITION - aborted = grpc.GRPC_STATUS_ABORTED - out_of_range = grpc.GRPC_STATUS_OUT_OF_RANGE - unimplemented = grpc.GRPC_STATUS_UNIMPLEMENTED - internal = grpc.GRPC_STATUS_INTERNAL - unavailable = grpc.GRPC_STATUS_UNAVAILABLE - data_loss = grpc.GRPC_STATUS_DATA_LOSS + ok = GRPC_STATUS_OK + cancelled = GRPC_STATUS_CANCELLED + unknown = GRPC_STATUS_UNKNOWN + invalid_argument = GRPC_STATUS_INVALID_ARGUMENT + deadline_exceeded = GRPC_STATUS_DEADLINE_EXCEEDED + not_found = GRPC_STATUS_NOT_FOUND + already_exists = GRPC_STATUS_ALREADY_EXISTS + permission_denied = GRPC_STATUS_PERMISSION_DENIED + unauthenticated = GRPC_STATUS_UNAUTHENTICATED + resource_exhausted = GRPC_STATUS_RESOURCE_EXHAUSTED + failed_precondition = GRPC_STATUS_FAILED_PRECONDITION + aborted = GRPC_STATUS_ABORTED + out_of_range = GRPC_STATUS_OUT_OF_RANGE + unimplemented = GRPC_STATUS_UNIMPLEMENTED + internal = GRPC_STATUS_INTERNAL + unavailable = GRPC_STATUS_UNAVAILABLE + data_loss = GRPC_STATUS_DATA_LOSS class CallError: - ok = grpc.GRPC_CALL_OK - error = grpc.GRPC_CALL_ERROR - not_on_server = grpc.GRPC_CALL_ERROR_NOT_ON_SERVER - not_on_client = grpc.GRPC_CALL_ERROR_NOT_ON_CLIENT - already_accepted = grpc.GRPC_CALL_ERROR_ALREADY_ACCEPTED - already_invoked = grpc.GRPC_CALL_ERROR_ALREADY_INVOKED - not_invoked = grpc.GRPC_CALL_ERROR_NOT_INVOKED - already_finished = grpc.GRPC_CALL_ERROR_ALREADY_FINISHED - too_many_operations = grpc.GRPC_CALL_ERROR_TOO_MANY_OPERATIONS - invalid_flags = grpc.GRPC_CALL_ERROR_INVALID_FLAGS - invalid_metadata = grpc.GRPC_CALL_ERROR_INVALID_METADATA + ok = GRPC_CALL_OK + error = GRPC_CALL_ERROR + not_on_server = GRPC_CALL_ERROR_NOT_ON_SERVER + not_on_client = GRPC_CALL_ERROR_NOT_ON_CLIENT + already_accepted = GRPC_CALL_ERROR_ALREADY_ACCEPTED + already_invoked = GRPC_CALL_ERROR_ALREADY_INVOKED + not_invoked = GRPC_CALL_ERROR_NOT_INVOKED + already_finished = GRPC_CALL_ERROR_ALREADY_FINISHED + too_many_operations = GRPC_CALL_ERROR_TOO_MANY_OPERATIONS + invalid_flags = GRPC_CALL_ERROR_INVALID_FLAGS + invalid_metadata = GRPC_CALL_ERROR_INVALID_METADATA class CompletionType: - queue_shutdown = grpc.GRPC_QUEUE_SHUTDOWN - queue_timeout = grpc.GRPC_QUEUE_TIMEOUT - operation_complete = grpc.GRPC_OP_COMPLETE + queue_shutdown = GRPC_QUEUE_SHUTDOWN + queue_timeout = GRPC_QUEUE_TIMEOUT + operation_complete = GRPC_OP_COMPLETE class OperationType: - send_initial_metadata = grpc.GRPC_OP_SEND_INITIAL_METADATA - send_message = grpc.GRPC_OP_SEND_MESSAGE - send_close_from_client = grpc.GRPC_OP_SEND_CLOSE_FROM_CLIENT - send_status_from_server = grpc.GRPC_OP_SEND_STATUS_FROM_SERVER - receive_initial_metadata = grpc.GRPC_OP_RECV_INITIAL_METADATA - receive_message = grpc.GRPC_OP_RECV_MESSAGE - receive_status_on_client = grpc.GRPC_OP_RECV_STATUS_ON_CLIENT - receive_close_on_server = grpc.GRPC_OP_RECV_CLOSE_ON_SERVER + send_initial_metadata = GRPC_OP_SEND_INITIAL_METADATA + send_message = GRPC_OP_SEND_MESSAGE + send_close_from_client = GRPC_OP_SEND_CLOSE_FROM_CLIENT + send_status_from_server = GRPC_OP_SEND_STATUS_FROM_SERVER + receive_initial_metadata = GRPC_OP_RECV_INITIAL_METADATA + receive_message = GRPC_OP_RECV_MESSAGE + receive_status_on_client = GRPC_OP_RECV_STATUS_ON_CLIENT + receive_close_on_server = GRPC_OP_RECV_CLOSE_ON_SERVER cdef class Timespec: def __cinit__(self, time): if time is None: - self.c_time = grpc.gpr_now(grpc.GPR_CLOCK_REALTIME) + self.c_time = gpr_now(GPR_CLOCK_REALTIME) return if isinstance(time, int): time = float(time) if isinstance(time, float): if time == float("+inf"): - self.c_time = grpc.gpr_inf_future(grpc.GPR_CLOCK_REALTIME) + self.c_time = gpr_inf_future(GPR_CLOCK_REALTIME) elif time == float("-inf"): - self.c_time = grpc.gpr_inf_past(grpc.GPR_CLOCK_REALTIME) + self.c_time = gpr_inf_past(GPR_CLOCK_REALTIME) else: self.c_time.seconds = time self.c_time.nanoseconds = (time - float(self.c_time.seconds)) * 1e9 - self.c_time.clock_type = grpc.GPR_CLOCK_REALTIME + self.c_time.clock_type = GPR_CLOCK_REALTIME elif isinstance(time, Timespec): self.c_time = (time).c_time else: @@ -135,19 +131,19 @@ cdef class Timespec: # TODO(atash) ensure that everywhere a Timespec is created that it's # converted to GPR_CLOCK_REALTIME then and not every time someone wants to # read values off in Python. - cdef grpc.gpr_timespec real_time = ( - grpc.gpr_convert_clock_type(self.c_time, grpc.GPR_CLOCK_REALTIME)) + cdef gpr_timespec real_time = ( + gpr_convert_clock_type(self.c_time, GPR_CLOCK_REALTIME)) return real_time.seconds @property def nanoseconds(self): - cdef grpc.gpr_timespec real_time = ( - grpc.gpr_convert_clock_type(self.c_time, grpc.GPR_CLOCK_REALTIME)) + cdef gpr_timespec real_time = ( + gpr_convert_clock_type(self.c_time, GPR_CLOCK_REALTIME)) return real_time.nanoseconds def __float__(self): - cdef grpc.gpr_timespec real_time = ( - grpc.gpr_convert_clock_type(self.c_time, grpc.GPR_CLOCK_REALTIME)) + cdef gpr_timespec real_time = ( + gpr_convert_clock_type(self.c_time, GPR_CLOCK_REALTIME)) return real_time.seconds + real_time.nanoseconds / 1e9 infinite_future = Timespec(float("+inf")) @@ -157,10 +153,10 @@ cdef class Timespec: cdef class CallDetails: def __cinit__(self): - grpc.grpc_call_details_init(&self.c_details) + grpc_call_details_init(&self.c_details) def __dealloc__(self): - grpc.grpc_call_details_destroy(&self.c_details) + grpc_call_details_destroy(&self.c_details) @property def method(self): @@ -192,8 +188,8 @@ cdef class OperationTag: cdef class Event: - def __cinit__(self, grpc.grpc_completion_type type, bint success, - object tag, call.Call operation_call, + def __cinit__(self, grpc_completion_type type, bint success, + object tag, Call operation_call, CallDetails request_call_details, Metadata request_metadata, bint is_new_request, @@ -228,31 +224,31 @@ cdef class ByteBuffer: "ByteBuffer, not {}".format(type(data))) cdef char *c_data = data - data_slice = grpc.gpr_slice_from_copied_buffer(c_data, len(data)) - self.c_byte_buffer = grpc.grpc_raw_byte_buffer_create( + data_slice = gpr_slice_from_copied_buffer(c_data, len(data)) + self.c_byte_buffer = grpc_raw_byte_buffer_create( &data_slice, 1) - grpc.gpr_slice_unref(data_slice) + gpr_slice_unref(data_slice) def bytes(self): - cdef grpc.grpc_byte_buffer_reader reader - cdef grpc.gpr_slice data_slice + cdef grpc_byte_buffer_reader reader + cdef gpr_slice data_slice cdef size_t data_slice_length cdef void *data_slice_pointer if self.c_byte_buffer != NULL: - grpc.grpc_byte_buffer_reader_init(&reader, self.c_byte_buffer) + grpc_byte_buffer_reader_init(&reader, self.c_byte_buffer) result = b"" - while grpc.grpc_byte_buffer_reader_next(&reader, &data_slice): - data_slice_pointer = grpc.gpr_slice_start_ptr(data_slice) - data_slice_length = grpc.gpr_slice_length(data_slice) + while grpc_byte_buffer_reader_next(&reader, &data_slice): + data_slice_pointer = gpr_slice_start_ptr(data_slice) + data_slice_length = gpr_slice_length(data_slice) result += (data_slice_pointer)[:data_slice_length] - grpc.grpc_byte_buffer_reader_destroy(&reader) + grpc_byte_buffer_reader_destroy(&reader) return result else: return None def __len__(self): if self.c_byte_buffer != NULL: - return grpc.grpc_byte_buffer_length(self.c_byte_buffer) + return grpc_byte_buffer_length(self.c_byte_buffer) else: return 0 @@ -261,7 +257,7 @@ cdef class ByteBuffer: def __dealloc__(self): if self.c_byte_buffer != NULL: - grpc.grpc_byte_buffer_destroy(self.c_byte_buffer) + grpc_byte_buffer_destroy(self.c_byte_buffer) cdef class SslPemKeyCertPair: @@ -295,15 +291,15 @@ cdef class ChannelArg: raise TypeError("expected key to be of type str or bytes") if isinstance(value, bytes): self.value = value - self.c_arg.type = grpc.GRPC_ARG_STRING + self.c_arg.type = GRPC_ARG_STRING self.c_arg.value.string = self.value elif isinstance(value, basestring): self.value = value.encode() - self.c_arg.type = grpc.GRPC_ARG_STRING + self.c_arg.type = GRPC_ARG_STRING self.c_arg.value.string = self.value elif isinstance(value, int): self.value = int(value) - self.c_arg.type = grpc.GRPC_ARG_INTEGER + self.c_arg.type = GRPC_ARG_INTEGER self.c_arg.value.integer = self.value else: raise TypeError("expected value to be of type str or bytes or int") @@ -318,14 +314,14 @@ cdef class ChannelArgs: if not isinstance(arg, ChannelArg): raise TypeError("expected list of ChannelArg") self.c_args.arguments_length = len(self.args) - self.c_args.arguments = grpc.gpr_malloc( - self.c_args.arguments_length*sizeof(grpc.grpc_arg) + self.c_args.arguments = gpr_malloc( + self.c_args.arguments_length*sizeof(grpc_arg) ) for i in range(self.c_args.arguments_length): self.c_args.arguments[i] = (self.args[i]).c_arg def __dealloc__(self): - grpc.gpr_free(self.c_args.arguments) + gpr_free(self.c_args.arguments) def __len__(self): # self.args is never stale; it's only updated from this file @@ -406,11 +402,11 @@ cdef class Metadata: for metadatum in metadata: if not isinstance(metadatum, Metadatum): raise TypeError("expected list of Metadatum") - grpc.grpc_metadata_array_init(&self.c_metadata_array) + grpc_metadata_array_init(&self.c_metadata_array) self.c_metadata_array.count = len(self.metadata) self.c_metadata_array.capacity = len(self.metadata) - self.c_metadata_array.metadata = grpc.gpr_malloc( - self.c_metadata_array.count*sizeof(grpc.grpc_metadata) + self.c_metadata_array.metadata = gpr_malloc( + self.c_metadata_array.count*sizeof(grpc_metadata) ) for i in range(self.c_metadata_array.count): self.c_metadata_array.metadata[i] = ( @@ -420,7 +416,7 @@ cdef class Metadata: # this frees the allocated memory for the grpc_metadata_array (although # it'd be nice if that were documented somewhere...) TODO(atash): document # this in the C core - grpc.grpc_metadata_array_destroy(&self.c_metadata_array) + grpc_metadata_array_destroy(&self.c_metadata_array) def __len__(self): return self.c_metadata_array.count @@ -449,49 +445,49 @@ cdef class Operation: @property def has_status(self): - return self.c_op.type == grpc.GRPC_OP_RECV_STATUS_ON_CLIENT + return self.c_op.type == GRPC_OP_RECV_STATUS_ON_CLIENT @property def received_message(self): - if self.c_op.type != grpc.GRPC_OP_RECV_MESSAGE: + if self.c_op.type != GRPC_OP_RECV_MESSAGE: raise TypeError("self must be an operation receiving a message") return self._received_message @property def received_message_or_none(self): - if self.c_op.type != grpc.GRPC_OP_RECV_MESSAGE: + if self.c_op.type != GRPC_OP_RECV_MESSAGE: return None return self._received_message @property def received_metadata(self): - if (self.c_op.type != grpc.GRPC_OP_RECV_INITIAL_METADATA and - self.c_op.type != grpc.GRPC_OP_RECV_STATUS_ON_CLIENT): + if (self.c_op.type != GRPC_OP_RECV_INITIAL_METADATA and + self.c_op.type != GRPC_OP_RECV_STATUS_ON_CLIENT): raise TypeError("self must be an operation receiving metadata") return self._received_metadata @property def received_metadata_or_none(self): - if (self.c_op.type != grpc.GRPC_OP_RECV_INITIAL_METADATA and - self.c_op.type != grpc.GRPC_OP_RECV_STATUS_ON_CLIENT): + if (self.c_op.type != GRPC_OP_RECV_INITIAL_METADATA and + self.c_op.type != GRPC_OP_RECV_STATUS_ON_CLIENT): return None return self._received_metadata @property def received_status_code(self): - if self.c_op.type != grpc.GRPC_OP_RECV_STATUS_ON_CLIENT: + if self.c_op.type != GRPC_OP_RECV_STATUS_ON_CLIENT: raise TypeError("self must be an operation receiving a status code") return self._received_status_code @property def received_status_code_or_none(self): - if self.c_op.type != grpc.GRPC_OP_RECV_STATUS_ON_CLIENT: + if self.c_op.type != GRPC_OP_RECV_STATUS_ON_CLIENT: return None return self._received_status_code @property def received_status_details(self): - if self.c_op.type != grpc.GRPC_OP_RECV_STATUS_ON_CLIENT: + if self.c_op.type != GRPC_OP_RECV_STATUS_ON_CLIENT: raise TypeError("self must be an operation receiving status details") if self._received_status_details: return self._received_status_details @@ -500,7 +496,7 @@ cdef class Operation: @property def received_status_details_or_none(self): - if self.c_op.type != grpc.GRPC_OP_RECV_STATUS_ON_CLIENT: + if self.c_op.type != GRPC_OP_RECV_STATUS_ON_CLIENT: return None if self._received_status_details: return self._received_status_details @@ -509,14 +505,14 @@ cdef class Operation: @property def received_cancelled(self): - if self.c_op.type != grpc.GRPC_OP_RECV_CLOSE_ON_SERVER: + if self.c_op.type != GRPC_OP_RECV_CLOSE_ON_SERVER: raise TypeError("self must be an operation receiving cancellation " "information") return False if self._received_cancelled == 0 else True @property def received_cancelled_or_none(self): - if self.c_op.type != grpc.GRPC_OP_RECV_CLOSE_ON_SERVER: + if self.c_op.type != GRPC_OP_RECV_CLOSE_ON_SERVER: return None return False if self._received_cancelled == 0 else True @@ -524,12 +520,12 @@ cdef class Operation: # We *almost* don't need to do anything; most of the objects are handled by # Python. The remaining one(s) are primitive fields filled in by GRPC core. # This means that we need to clean up after receive_status_on_client. - if self.c_op.type == grpc.GRPC_OP_RECV_STATUS_ON_CLIENT: - grpc.gpr_free(self._received_status_details) + if self.c_op.type == GRPC_OP_RECV_STATUS_ON_CLIENT: + gpr_free(self._received_status_details) def operation_send_initial_metadata(Metadata metadata): cdef Operation op = Operation() - op.c_op.type = grpc.GRPC_OP_SEND_INITIAL_METADATA + op.c_op.type = GRPC_OP_SEND_INITIAL_METADATA op.c_op.data.send_initial_metadata.count = metadata.c_metadata_array.count op.c_op.data.send_initial_metadata.metadata = ( metadata.c_metadata_array.metadata) @@ -539,7 +535,7 @@ def operation_send_initial_metadata(Metadata metadata): def operation_send_message(data): cdef Operation op = Operation() - op.c_op.type = grpc.GRPC_OP_SEND_MESSAGE + op.c_op.type = GRPC_OP_SEND_MESSAGE byte_buffer = ByteBuffer(data) op.c_op.data.send_message = byte_buffer.c_byte_buffer op.references.append(byte_buffer) @@ -548,12 +544,12 @@ def operation_send_message(data): def operation_send_close_from_client(): cdef Operation op = Operation() - op.c_op.type = grpc.GRPC_OP_SEND_CLOSE_FROM_CLIENT + op.c_op.type = GRPC_OP_SEND_CLOSE_FROM_CLIENT op.is_valid = True return op def operation_send_status_from_server( - Metadata metadata, grpc.grpc_status_code code, details): + Metadata metadata, grpc_status_code code, details): if isinstance(details, bytes): pass elif isinstance(details, basestring): @@ -561,7 +557,7 @@ def operation_send_status_from_server( else: raise TypeError("expected a str or bytes object for details") cdef Operation op = Operation() - op.c_op.type = grpc.GRPC_OP_SEND_STATUS_FROM_SERVER + op.c_op.type = GRPC_OP_SEND_STATUS_FROM_SERVER op.c_op.data.send_status_from_server.trailing_metadata_count = ( metadata.c_metadata_array.count) op.c_op.data.send_status_from_server.trailing_metadata = ( @@ -575,7 +571,7 @@ def operation_send_status_from_server( def operation_receive_initial_metadata(): cdef Operation op = Operation() - op.c_op.type = grpc.GRPC_OP_RECV_INITIAL_METADATA + op.c_op.type = GRPC_OP_RECV_INITIAL_METADATA op._received_metadata = Metadata([]) op.c_op.data.receive_initial_metadata = ( &op._received_metadata.c_metadata_array) @@ -584,7 +580,7 @@ def operation_receive_initial_metadata(): def operation_receive_message(): cdef Operation op = Operation() - op.c_op.type = grpc.GRPC_OP_RECV_MESSAGE + op.c_op.type = GRPC_OP_RECV_MESSAGE op._received_message = ByteBuffer(None) # n.b. the c_op.data.receive_message field needs to be deleted by us, # anyway, so we just let that be handled by the ByteBuffer() we allocated @@ -595,7 +591,7 @@ def operation_receive_message(): def operation_receive_status_on_client(): cdef Operation op = Operation() - op.c_op.type = grpc.GRPC_OP_RECV_STATUS_ON_CLIENT + op.c_op.type = GRPC_OP_RECV_STATUS_ON_CLIENT op._received_metadata = Metadata([]) op.c_op.data.receive_status_on_client.trailing_metadata = ( &op._received_metadata.c_metadata_array) @@ -610,7 +606,7 @@ def operation_receive_status_on_client(): def operation_receive_close_on_server(): cdef Operation op = Operation() - op.c_op.type = grpc.GRPC_OP_RECV_CLOSE_ON_SERVER + op.c_op.type = GRPC_OP_RECV_CLOSE_ON_SERVER op.c_op.data.receive_close_on_server.cancelled = &op._received_cancelled op.is_valid = True return op @@ -647,8 +643,8 @@ cdef class Operations: if not isinstance(operation, Operation): raise TypeError("expected operations to be iterable of Operation") self.c_nops = len(self.operations) - self.c_ops = grpc.gpr_malloc( - sizeof(grpc.grpc_op)*self.c_nops) + self.c_ops = gpr_malloc( + sizeof(grpc_op)*self.c_nops) for i in range(self.c_nops): self.c_ops[i] = ((self.operations[i])).c_op @@ -660,7 +656,7 @@ cdef class Operations: return self.operations[i] def __dealloc__(self): - grpc.gpr_free(self.c_ops) + gpr_free(self.c_ops) def __iter__(self): return _OperationsIterator(self) diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/server.pxd b/src/python/grpcio/grpc/_cython/_cygrpc/server.pxd.pxi similarity index 90% rename from src/python/grpcio/grpc/_cython/_cygrpc/server.pxd rename to src/python/grpcio/grpc/_cython/_cygrpc/server.pxd.pxi index 0257542a037..9db49e4d307 100644 --- a/src/python/grpcio/grpc/_cython/_cygrpc/server.pxd +++ b/src/python/grpcio/grpc/_cython/_cygrpc/server.pxd.pxi @@ -27,18 +27,15 @@ # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -from grpc._cython._cygrpc cimport grpc -from grpc._cython._cygrpc cimport completion_queue - cdef class Server: - cdef grpc.grpc_server *c_server + cdef grpc_server *c_server cdef bint is_started # start has been called cdef bint is_shutting_down # shutdown has been called cdef bint is_shutdown # notification of complete shutdown received # used at dealloc when user forgets to shutdown - cdef completion_queue.CompletionQueue backup_shutdown_queue + cdef CompletionQueue backup_shutdown_queue cdef list references cdef list registered_completion_queues diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/server.pyx b/src/python/grpcio/grpc/_cython/_cygrpc/server.pyx.pxi similarity index 75% rename from src/python/grpcio/grpc/_cython/_cygrpc/server.pyx rename to src/python/grpcio/grpc/_cython/_cygrpc/server.pyx.pxi index b0bafbc1f49..8b65935c3b9 100644 --- a/src/python/grpcio/grpc/_cython/_cygrpc/server.pyx +++ b/src/python/grpcio/grpc/_cython/_cygrpc/server.pyx.pxi @@ -29,45 +29,39 @@ cimport cpython -from grpc._cython._cygrpc cimport call -from grpc._cython._cygrpc cimport completion_queue -from grpc._cython._cygrpc cimport credentials -from grpc._cython._cygrpc cimport grpc -from grpc._cython._cygrpc cimport records - import time cdef class Server: - def __cinit__(self, records.ChannelArgs arguments=None): - cdef grpc.grpc_channel_args *c_arguments = NULL + def __cinit__(self, ChannelArgs arguments=None): + cdef grpc_channel_args *c_arguments = NULL self.references = [] self.registered_completion_queues = [] if arguments is not None: c_arguments = &arguments.c_args self.references.append(arguments) - self.c_server = grpc.grpc_server_create(c_arguments, NULL) + self.c_server = grpc_server_create(c_arguments, NULL) self.is_started = False self.is_shutting_down = False self.is_shutdown = False def request_call( - self, completion_queue.CompletionQueue call_queue not None, - completion_queue.CompletionQueue server_queue not None, tag): + self, CompletionQueue call_queue not None, + CompletionQueue server_queue not None, tag): if not self.is_started or self.is_shutting_down: raise ValueError("server must be started and not shutting down") if server_queue not in self.registered_completion_queues: raise ValueError("server_queue must be a registered completion queue") - cdef records.OperationTag operation_tag = records.OperationTag(tag) - operation_tag.operation_call = call.Call() - operation_tag.request_call_details = records.CallDetails() - operation_tag.request_metadata = records.Metadata([]) + cdef OperationTag operation_tag = OperationTag(tag) + operation_tag.operation_call = Call() + operation_tag.request_call_details = CallDetails() + operation_tag.request_metadata = Metadata([]) operation_tag.references.extend([self, call_queue, server_queue]) operation_tag.is_new_request = True - operation_tag.batch_operations = records.Operations([]) + operation_tag.batch_operations = Operations([]) cpython.Py_INCREF(operation_tag) - return grpc.grpc_server_request_call( + return grpc_server_request_call( self.c_server, &operation_tag.operation_call.c_call, &operation_tag.request_call_details.c_details, &operation_tag.request_metadata.c_metadata_array, @@ -75,25 +69,25 @@ cdef class Server: operation_tag) def register_completion_queue( - self, completion_queue.CompletionQueue queue not None): + self, CompletionQueue queue not None): if self.is_started: raise ValueError("cannot register completion queues after start") - grpc.grpc_server_register_completion_queue( + grpc_server_register_completion_queue( self.c_server, queue.c_completion_queue, NULL) self.registered_completion_queues.append(queue) def start(self): if self.is_started: raise ValueError("the server has already started") - self.backup_shutdown_queue = completion_queue.CompletionQueue() + self.backup_shutdown_queue = CompletionQueue() self.register_completion_queue(self.backup_shutdown_queue) self.is_started = True - grpc.grpc_server_start(self.c_server) + grpc_server_start(self.c_server) # Ensure the core has gotten a chance to do the start-up work - self.backup_shutdown_queue.pluck(None, records.Timespec(None)) + self.backup_shutdown_queue.pluck(None, Timespec(None)) def add_http2_port(self, address, - credentials.ServerCredentials server_credentials=None): + ServerCredentials server_credentials=None): if isinstance(address, bytes): pass elif isinstance(address, basestring): @@ -103,13 +97,13 @@ cdef class Server: self.references.append(address) if server_credentials is not None: self.references.append(server_credentials) - return grpc.grpc_server_add_secure_http2_port( + return grpc_server_add_secure_http2_port( self.c_server, address, server_credentials.c_credentials) else: - return grpc.grpc_server_add_insecure_http2_port(self.c_server, address) + return grpc_server_add_insecure_http2_port(self.c_server, address) - def shutdown(self, completion_queue.CompletionQueue queue not None, tag): - cdef records.OperationTag operation_tag + def shutdown(self, CompletionQueue queue not None, tag): + cdef OperationTag operation_tag if queue.is_shutting_down: raise ValueError("queue must be live") elif not self.is_started: @@ -120,11 +114,11 @@ cdef class Server: raise ValueError("expected registered completion queue") else: self.is_shutting_down = True - operation_tag = records.OperationTag(tag) + operation_tag = OperationTag(tag) operation_tag.shutting_down_server = self operation_tag.references.extend([self, queue]) cpython.Py_INCREF(operation_tag) - grpc.grpc_server_shutdown_and_notify( + grpc_server_shutdown_and_notify( self.c_server, queue.c_completion_queue, operation_tag) @@ -138,7 +132,7 @@ cdef class Server: elif self.is_shutdown: return else: - grpc.grpc_server_cancel_all_calls(self.c_server) + grpc_server_cancel_all_calls(self.c_server) def __dealloc__(self): if self.c_server != NULL: @@ -157,5 +151,5 @@ cdef class Server: # much but repeatedly release the GIL and wait while not self.is_shutdown: time.sleep(0) - grpc.grpc_server_destroy(self.c_server) + grpc_server_destroy(self.c_server) diff --git a/src/python/grpcio/grpc/_cython/cygrpc.pxd b/src/python/grpcio/grpc/_cython/cygrpc.pxd new file mode 100644 index 00000000000..f38134efedd --- /dev/null +++ b/src/python/grpcio/grpc/_cython/cygrpc.pxd @@ -0,0 +1,8 @@ +include "grpc/_cython/_cygrpc/grpc.pxi" + +include "grpc/_cython/_cygrpc/call.pxd.pxi" +include "grpc/_cython/_cygrpc/channel.pxd.pxi" +include "grpc/_cython/_cygrpc/credentials.pxd.pxi" +include "grpc/_cython/_cygrpc/completion_queue.pxd.pxi" +include "grpc/_cython/_cygrpc/records.pxd.pxi" +include "grpc/_cython/_cygrpc/server.pxd.pxi" diff --git a/src/python/grpcio/grpc/_cython/cygrpc.pyx b/src/python/grpcio/grpc/_cython/cygrpc.pyx index 16ec12dac0d..297c8001c5e 100644 --- a/src/python/grpcio/grpc/_cython/cygrpc.pyx +++ b/src/python/grpcio/grpc/_cython/cygrpc.pyx @@ -29,78 +29,14 @@ cimport cpython -from grpc._cython._cygrpc cimport grpc -from grpc._cython._cygrpc cimport call -from grpc._cython._cygrpc cimport channel -from grpc._cython._cygrpc cimport credentials -from grpc._cython._cygrpc cimport completion_queue -from grpc._cython._cygrpc cimport records -from grpc._cython._cygrpc cimport server - -from grpc._cython._cygrpc import call -from grpc._cython._cygrpc import channel -from grpc._cython._cygrpc import credentials -from grpc._cython._cygrpc import completion_queue -from grpc._cython._cygrpc import records -from grpc._cython._cygrpc import server - -ConnectivityState = records.ConnectivityState -ChannelArgKey = records.ChannelArgKey -WriteFlag = records.WriteFlag -StatusCode = records.StatusCode -CallError = records.CallError -CompletionType = records.CompletionType -OperationType = records.OperationType -Timespec = records.Timespec -CallDetails = records.CallDetails -Event = records.Event -ByteBuffer = records.ByteBuffer -SslPemKeyCertPair = records.SslPemKeyCertPair -ChannelArg = records.ChannelArg -ChannelArgs = records.ChannelArgs -Metadatum = records.Metadatum -Metadata = records.Metadata -Operation = records.Operation - -operation_send_initial_metadata = records.operation_send_initial_metadata -operation_send_message = records.operation_send_message -operation_send_close_from_client = records.operation_send_close_from_client -operation_send_status_from_server = records.operation_send_status_from_server -operation_receive_initial_metadata = records.operation_receive_initial_metadata -operation_receive_message = records.operation_receive_message -operation_receive_status_on_client = records.operation_receive_status_on_client -operation_receive_close_on_server = records.operation_receive_close_on_server - -Operations = records.Operations - -CallCredentials = credentials.CallCredentials -ChannelCredentials = credentials.ChannelCredentials -ServerCredentials = credentials.ServerCredentials -CredentialsMetadataPlugin = credentials.CredentialsMetadataPlugin -AuthMetadataContext = credentials.AuthMetadataContext - -channel_credentials_google_default = ( - credentials.channel_credentials_google_default) -channel_credentials_ssl = credentials.channel_credentials_ssl -channel_credentials_composite = ( - credentials.channel_credentials_composite) -call_credentials_composite = ( - credentials.call_credentials_composite) -call_credentials_google_compute_engine = ( - credentials.call_credentials_google_compute_engine) -call_credentials_jwt_access = ( - credentials.call_credentials_service_account_jwt_access) -call_credentials_refresh_token = ( - credentials.call_credentials_google_refresh_token) -call_credentials_google_iam = credentials.call_credentials_google_iam -call_credentials_metadata_plugin = credentials.call_credentials_metadata_plugin -server_credentials_ssl = credentials.server_credentials_ssl - -CompletionQueue = completion_queue.CompletionQueue -Channel = channel.Channel -Server = server.Server -Call = call.Call - +# TODO(atash): figure out why the coverage tool gets confused about the Cython +# coverage plugin when the following files don't have a '.pxi' suffix. +include "grpc/_cython/_cygrpc/call.pyx.pxi" +include "grpc/_cython/_cygrpc/channel.pyx.pxi" +include "grpc/_cython/_cygrpc/credentials.pyx.pxi" +include "grpc/_cython/_cygrpc/completion_queue.pyx.pxi" +include "grpc/_cython/_cygrpc/records.pyx.pxi" +include "grpc/_cython/_cygrpc/server.pyx.pxi" # # Global state @@ -109,10 +45,10 @@ Call = call.Call cdef class _ModuleState: def __cinit__(self): - grpc.grpc_init() + grpc_init() def __dealloc__(self): - grpc.grpc_shutdown() + grpc_shutdown() _module_state = _ModuleState() diff --git a/src/python/grpcio/grpc_core_dependencies.py b/src/python/grpcio/grpc_core_dependencies.py new file mode 100644 index 00000000000..cd4b7101d43 --- /dev/null +++ b/src/python/grpcio/grpc_core_dependencies.py @@ -0,0 +1,195 @@ +# AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio/grpc_core_dependencies.py.template`!!! + +CORE_SOURCE_FILES = [ + 'src/core/profiling/basic_timers.c', + 'src/core/profiling/stap_timers.c', + 'src/core/support/alloc.c', + 'src/core/support/avl.c', + 'src/core/support/cmdline.c', + 'src/core/support/cpu_iphone.c', + 'src/core/support/cpu_linux.c', + 'src/core/support/cpu_posix.c', + 'src/core/support/cpu_windows.c', + 'src/core/support/env_linux.c', + 'src/core/support/env_posix.c', + 'src/core/support/env_win32.c', + 'src/core/support/file.c', + 'src/core/support/file_posix.c', + 'src/core/support/file_win32.c', + 'src/core/support/histogram.c', + 'src/core/support/host_port.c', + 'src/core/support/log.c', + 'src/core/support/log_android.c', + 'src/core/support/log_linux.c', + 'src/core/support/log_posix.c', + 'src/core/support/log_win32.c', + 'src/core/support/murmur_hash.c', + 'src/core/support/slice.c', + 'src/core/support/slice_buffer.c', + 'src/core/support/stack_lockfree.c', + 'src/core/support/string.c', + 'src/core/support/string_posix.c', + 'src/core/support/string_win32.c', + 'src/core/support/subprocess_posix.c', + 'src/core/support/sync.c', + 'src/core/support/sync_posix.c', + 'src/core/support/sync_win32.c', + 'src/core/support/thd.c', + 'src/core/support/thd_posix.c', + 'src/core/support/thd_win32.c', + 'src/core/support/time.c', + 'src/core/support/time_posix.c', + 'src/core/support/time_precise.c', + 'src/core/support/time_win32.c', + 'src/core/support/tls_pthread.c', + 'src/core/httpcli/httpcli_security_connector.c', + 'src/core/security/base64.c', + 'src/core/security/client_auth_filter.c', + 'src/core/security/credentials.c', + 'src/core/security/credentials_metadata.c', + 'src/core/security/credentials_posix.c', + 'src/core/security/credentials_win32.c', + 'src/core/security/google_default_credentials.c', + 'src/core/security/handshake.c', + 'src/core/security/json_token.c', + 'src/core/security/jwt_verifier.c', + 'src/core/security/secure_endpoint.c', + 'src/core/security/security_connector.c', + 'src/core/security/security_context.c', + 'src/core/security/server_auth_filter.c', + 'src/core/security/server_secure_chttp2.c', + 'src/core/surface/init_secure.c', + 'src/core/surface/secure_channel_create.c', + 'src/core/tsi/fake_transport_security.c', + 'src/core/tsi/ssl_transport_security.c', + 'src/core/tsi/transport_security.c', + 'src/core/census/grpc_context.c', + 'src/core/census/grpc_filter.c', + 'src/core/channel/channel_args.c', + 'src/core/channel/channel_stack.c', + 'src/core/channel/client_channel.c', + 'src/core/channel/client_uchannel.c', + 'src/core/channel/compress_filter.c', + 'src/core/channel/connected_channel.c', + 'src/core/channel/http_client_filter.c', + 'src/core/channel/http_server_filter.c', + 'src/core/channel/subchannel_call_holder.c', + 'src/core/client_config/client_config.c', + 'src/core/client_config/connector.c', + 'src/core/client_config/default_initial_connect_string.c', + 'src/core/client_config/initial_connect_string.c', + 'src/core/client_config/lb_policies/pick_first.c', + 'src/core/client_config/lb_policies/round_robin.c', + 'src/core/client_config/lb_policy.c', + 'src/core/client_config/lb_policy_factory.c', + 'src/core/client_config/lb_policy_registry.c', + 'src/core/client_config/resolver.c', + 'src/core/client_config/resolver_factory.c', + 'src/core/client_config/resolver_registry.c', + 'src/core/client_config/resolvers/dns_resolver.c', + 'src/core/client_config/resolvers/sockaddr_resolver.c', + 'src/core/client_config/subchannel.c', + 'src/core/client_config/subchannel_factory.c', + 'src/core/client_config/uri_parser.c', + 'src/core/compression/algorithm.c', + 'src/core/compression/message_compress.c', + 'src/core/debug/trace.c', + 'src/core/httpcli/format_request.c', + 'src/core/httpcli/httpcli.c', + 'src/core/httpcli/parser.c', + 'src/core/iomgr/closure.c', + 'src/core/iomgr/endpoint.c', + 'src/core/iomgr/endpoint_pair_posix.c', + 'src/core/iomgr/endpoint_pair_windows.c', + 'src/core/iomgr/exec_ctx.c', + 'src/core/iomgr/executor.c', + 'src/core/iomgr/fd_posix.c', + 'src/core/iomgr/iocp_windows.c', + 'src/core/iomgr/iomgr.c', + 'src/core/iomgr/iomgr_posix.c', + 'src/core/iomgr/iomgr_windows.c', + 'src/core/iomgr/pollset_multipoller_with_epoll.c', + 'src/core/iomgr/pollset_multipoller_with_poll_posix.c', + 'src/core/iomgr/pollset_posix.c', + 'src/core/iomgr/pollset_set_posix.c', + 'src/core/iomgr/pollset_set_windows.c', + 'src/core/iomgr/pollset_windows.c', + 'src/core/iomgr/resolve_address_posix.c', + 'src/core/iomgr/resolve_address_windows.c', + 'src/core/iomgr/sockaddr_utils.c', + 'src/core/iomgr/socket_utils_common_posix.c', + 'src/core/iomgr/socket_utils_linux.c', + 'src/core/iomgr/socket_utils_posix.c', + 'src/core/iomgr/socket_windows.c', + 'src/core/iomgr/tcp_client_posix.c', + 'src/core/iomgr/tcp_client_windows.c', + 'src/core/iomgr/tcp_posix.c', + 'src/core/iomgr/tcp_server_posix.c', + 'src/core/iomgr/tcp_server_windows.c', + 'src/core/iomgr/tcp_windows.c', + 'src/core/iomgr/time_averaged_stats.c', + 'src/core/iomgr/timer.c', + 'src/core/iomgr/timer_heap.c', + 'src/core/iomgr/udp_server.c', + 'src/core/iomgr/wakeup_fd_eventfd.c', + 'src/core/iomgr/wakeup_fd_nospecial.c', + 'src/core/iomgr/wakeup_fd_pipe.c', + 'src/core/iomgr/wakeup_fd_posix.c', + 'src/core/iomgr/workqueue_posix.c', + 'src/core/iomgr/workqueue_windows.c', + 'src/core/json/json.c', + 'src/core/json/json_reader.c', + 'src/core/json/json_string.c', + 'src/core/json/json_writer.c', + 'src/core/surface/api_trace.c', + 'src/core/surface/byte_buffer.c', + 'src/core/surface/byte_buffer_reader.c', + 'src/core/surface/call.c', + 'src/core/surface/call_details.c', + 'src/core/surface/call_log_batch.c', + 'src/core/surface/channel.c', + 'src/core/surface/channel_connectivity.c', + 'src/core/surface/channel_create.c', + 'src/core/surface/channel_ping.c', + 'src/core/surface/completion_queue.c', + 'src/core/surface/event_string.c', + 'src/core/surface/init.c', + 'src/core/surface/lame_client.c', + 'src/core/surface/metadata_array.c', + 'src/core/surface/server.c', + 'src/core/surface/server_chttp2.c', + 'src/core/surface/server_create.c', + 'src/core/surface/version.c', + 'src/core/transport/byte_stream.c', + 'src/core/transport/chttp2/alpn.c', + 'src/core/transport/chttp2/bin_encoder.c', + 'src/core/transport/chttp2/frame_data.c', + 'src/core/transport/chttp2/frame_goaway.c', + 'src/core/transport/chttp2/frame_ping.c', + 'src/core/transport/chttp2/frame_rst_stream.c', + 'src/core/transport/chttp2/frame_settings.c', + 'src/core/transport/chttp2/frame_window_update.c', + 'src/core/transport/chttp2/hpack_encoder.c', + 'src/core/transport/chttp2/hpack_parser.c', + 'src/core/transport/chttp2/hpack_table.c', + 'src/core/transport/chttp2/huffsyms.c', + 'src/core/transport/chttp2/incoming_metadata.c', + 'src/core/transport/chttp2/parsing.c', + 'src/core/transport/chttp2/status_conversion.c', + 'src/core/transport/chttp2/stream_lists.c', + 'src/core/transport/chttp2/stream_map.c', + 'src/core/transport/chttp2/timeout_encoding.c', + 'src/core/transport/chttp2/varint.c', + 'src/core/transport/chttp2/writing.c', + 'src/core/transport/chttp2_transport.c', + 'src/core/transport/connectivity_state.c', + 'src/core/transport/metadata.c', + 'src/core/transport/metadata_batch.c', + 'src/core/transport/static_metadata.c', + 'src/core/transport/transport.c', + 'src/core/transport/transport_op_string.c', + 'src/core/census/context.c', + 'src/core/census/initialize.c', + 'src/core/census/operation.c', + 'src/core/census/tracing.c', +] diff --git a/src/python/grpcio/tests/unit/_cython/test_utilities.py b/src/python/grpcio/tests/unit/_cython/test_utilities.py index 21ea3075b47..6a097396431 100644 --- a/src/python/grpcio/tests/unit/_cython/test_utilities.py +++ b/src/python/grpcio/tests/unit/_cython/test_utilities.py @@ -29,7 +29,7 @@ import threading -from grpc._cython._cygrpc import completion_queue +from grpc._cython import cygrpc class CompletionQueuePollFuture: diff --git a/src/python/grpcio/tox.ini b/src/python/grpcio/tox.ini deleted file mode 100644 index bfb1ca0cfad..00000000000 --- a/src/python/grpcio/tox.ini +++ /dev/null @@ -1,19 +0,0 @@ -# Tox (http://tox.testrun.org/) is a tool for running tests -# in multiple virtualenvs. This configuration file will run the -# test suite on all supported python versions. To use it, "pip install tox" -# and then run "tox" from this directory. - -[tox] -skipsdist = true -envlist = py27 - -[testenv] -commands = - {envpython} setup.py build_py - {envpython} setup.py test - coverage combine - coverage html --include='grpc/*' --omit='grpc/framework/alpha/*','grpc/early_adopter/*','grpc/framework/base/*','grpc/framework/face/*','grpc/_adapter/fore.py','grpc/_adapter/rear.py' - coverage report --include='grpc/*' --omit='grpc/framework/alpha/*','grpc/early_adopter/*','grpc/framework/base/*','grpc/framework/face/*','grpc/_adapter/fore.py','grpc/_adapter/rear.py' -deps = - -rrequirements.txt -passenv = * diff --git a/templates/src/python/grpcio/grpc_core_dependencies.py.template b/templates/src/python/grpcio/grpc_core_dependencies.py.template new file mode 100644 index 00000000000..1ca5f7ad6c7 --- /dev/null +++ b/templates/src/python/grpcio/grpc_core_dependencies.py.template @@ -0,0 +1,13 @@ +%YAML 1.2 +--- | + # AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio/grpc_core_dependencies.py.template`!!! + + CORE_SOURCE_FILES = [ + % for lib in libs: + % if lib.name in python_dependencies.transitive_deps: + % for src in lib.src: + '${src}', + % endfor + % endif + % endfor + ] diff --git a/tools/buildgen/plugins/transitive_dependencies.py b/tools/buildgen/plugins/transitive_dependencies.py index c2d3da3a3b2..1fc76a3cd51 100644 --- a/tools/buildgen/plugins/transitive_dependencies.py +++ b/tools/buildgen/plugins/transitive_dependencies.py @@ -58,6 +58,10 @@ def mako_plugin(dictionary): node_modules = dictionary.get('node_modules') targets = dictionary.get('targets') - for target_list in (libs, node_modules, targets): + for target_list in (libs, targets, node_modules): for target in target_list: target['transitive_deps'] = transitive_deps(target, libs) + + python_dependencies = dictionary.get('python_dependencies') + python_dependencies['transitive_deps'] = ( + transitive_deps(python_dependencies, libs)) diff --git a/tools/distrib/python/submit.py b/tools/distrib/python/submit.py index dffbefd5fe4..08ace7c6901 100755 --- a/tools/distrib/python/submit.py +++ b/tools/distrib/python/submit.py @@ -59,7 +59,7 @@ args = parser.parse_args() # Move to the root directory of Python GRPC. pkgdir = os.path.join(os.path.dirname(os.path.abspath(__file__)), - '../../../src/python/grpcio') + '../../../') # Remove previous distributions; they somehow confuse twine. try: shutil.rmtree(os.path.join(pkgdir, 'dist/')) diff --git a/tools/jenkins/grpc_interop_python/Dockerfile b/tools/jenkins/grpc_interop_python/Dockerfile index 6034cbf9550..047604b1b79 100644 --- a/tools/jenkins/grpc_interop_python/Dockerfile +++ b/tools/jenkins/grpc_interop_python/Dockerfile @@ -48,6 +48,7 @@ RUN apt-get update && apt-get install -y \ libc6-dbg \ libc6-dev \ libgtest-dev \ + libssl-dev \ libtool \ make \ strace \ diff --git a/tools/jenkins/grpc_interop_python/build_interop.sh b/tools/jenkins/grpc_interop_python/build_interop.sh index 8f5bfd11e20..39c93677d8b 100755 --- a/tools/jenkins/grpc_interop_python/build_interop.sh +++ b/tools/jenkins/grpc_interop_python/build_interop.sh @@ -43,5 +43,5 @@ make install-certs make # build Python interop client and server -CONFIG=opt ./tools/run_tests/build_python.sh 2.7 +CONFIG=opt ./tools/run_tests/build_python.sh diff --git a/tools/run_tests/build_python.sh b/tools/run_tests/build_python.sh index 57080ce9348..8159e5a464f 100755 --- a/tools/run_tests/build_python.sh +++ b/tools/run_tests/build_python.sh @@ -34,16 +34,14 @@ set -ex cd $(dirname $0)/../.. ROOT=`pwd` -GRPCIO=$ROOT/src/python/grpcio export LD_LIBRARY_PATH=$ROOT/libs/$CONFIG export DYLD_LIBRARY_PATH=$ROOT/libs/$CONFIG export PATH=$ROOT/bins/$CONFIG:$ROOT/bins/$CONFIG/protobuf:$PATH export CFLAGS="-I$ROOT/include -std=c89" -export LDFLAGS="-L$ROOT/libs/$CONFIG" +export LDFLAGS="-L$ROOT/libs/$CONFIG -L$ROOT/libs/$CONFIG/openssl" export GRPC_PYTHON_BUILD_WITH_CYTHON=1 export GRPC_PYTHON_ENABLE_CYTHON_TRACING=1 -cd $GRPCIO tox --notest -$GRPCIO/.tox/py27/bin/python $GRPCIO/setup.py build +$ROOT/.tox/py27/bin/python $ROOT/setup.py build diff --git a/tools/run_tests/run_interop_tests.py b/tools/run_tests/run_interop_tests.py index e69e9877c5c..1a806ab206e 100755 --- a/tools/run_tests/run_interop_tests.py +++ b/tools/run_tests/run_interop_tests.py @@ -298,8 +298,8 @@ class PythonLanguage: def client_cmd(self, args): return [ - 'src/python/grpcio/.tox/py27/bin/python', - 'src/python/grpcio/setup.py', + '.tox/py27/bin/python', + 'setup.py', 'run_interop', '--client', '--args=\'{}\''.format(' '.join(args)) @@ -310,8 +310,8 @@ class PythonLanguage: def server_cmd(self, args): return [ - 'src/python/grpcio/.tox/py27/bin/python', - 'src/python/grpcio/setup.py', + '.tox/py27/bin/python', + 'setup.py', 'run_interop', '--server', '--args=\'{}\''.format(' '.join(args) + ' --use_tls=true') diff --git a/tools/run_tests/run_python.sh b/tools/run_tests/run_python.sh index 042b40485df..35144926460 100755 --- a/tools/run_tests/run_python.sh +++ b/tools/run_tests/run_python.sh @@ -34,18 +34,16 @@ set -ex cd $(dirname $0)/../.. ROOT=`pwd` -GRPCIO=$ROOT/src/python/grpcio export LD_LIBRARY_PATH=$ROOT/libs/$CONFIG export DYLD_LIBRARY_PATH=$ROOT/libs/$CONFIG export PATH=$ROOT/bins/$CONFIG:$ROOT/bins/$CONFIG/protobuf:$PATH export CFLAGS="-I$ROOT/include -std=c89" -export LDFLAGS="-L$ROOT/libs/$CONFIG" +export LDFLAGS="-L$ROOT/libs/$CONFIG -L$ROOT/libs/$CONFIG/openssl" export GRPC_PYTHON_BUILD_WITH_CYTHON=1 export GRPC_PYTHON_ENABLE_CYTHON_TRACING=1 -cd $GRPCIO tox mkdir -p $ROOT/reports rm -rf $ROOT/reports/python-coverage -(mv -T $GRPCIO/htmlcov $ROOT/reports/python-coverage) || true +(mv -T $ROOT/htmlcov $ROOT/reports/python-coverage) || true diff --git a/tox.ini b/tox.ini new file mode 100644 index 00000000000..8bb5fc2bc60 --- /dev/null +++ b/tox.ini @@ -0,0 +1,17 @@ +[tox] +skipsdist = true +envlist = py27 + +[testenv] +setenv = + PYGRPC_ROOT = {toxinidir}/src/python/grpcio/ +commands = + {envpython} setup.py build_py + {envpython} setup.py test + {envbindir}/coverage combine +# TODO(atash): we currently ignore cygrpc.pyx due to an insufficiency in Cython's coverage plug-in. Discussion is ongoing. + {envbindir}/coverage html --include='{env:PYGRPC_ROOT}/grpc/*' --omit='{env:PYGRPC_ROOT}/grpc/framework/alpha/*','{env:PYGRPC_ROOT}/grpc/early_adopter/*','{env:PYGRPC_ROOT}/grpc/framework/base/*','{env:PYGRPC_ROOT}/grpc/framework/face/*','{env:PYGRPC_ROOT}/grpc/_adapter/fore.py','{env:PYGRPC_ROOT}/grpc/_adapter/rear.py','{env:PYGRPC_ROOT}/grpc/_cython/cygrpc.pyx' + {envbindir}/coverage report --include='{env:PYGRPC_ROOT}/grpc/*' --omit='{env:PYGRPC_ROOT}/grpc/framework/alpha/*','{env:PYGRPC_ROOT}/grpc/early_adopter/*','{env:PYGRPC_ROOT}/grpc/framework/base/*','{env:PYGRPC_ROOT}/grpc/framework/face/*','{env:PYGRPC_ROOT}/grpc/_adapter/fore.py','{env:PYGRPC_ROOT}/grpc/_adapter/rear.py','{env:PYGRPC_ROOT}/grpc/_cython/cygrpc.pyx' +deps = + -rrequirements.txt +passenv = *