From b3021e4f6bab0952790ea5b83901cafca83cbba4 Mon Sep 17 00:00:00 2001 From: Jacob Alexander Date: Thu, 26 Sep 2019 22:18:28 -0700 Subject: [PATCH] Fixing flake8 warnings and errors flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics --exclude benchmark Excluding the benchmark directory (due to protobuf generated files) Also removing some Python2 specific code --- buildutils/__init__.py | 1 + buildutils/build.py | 45 ++++++------ buildutils/bundle.py | 43 ++++++----- buildutils/config.py | 28 +++---- buildutils/constants.py | 5 +- buildutils/detect.py | 24 +++--- buildutils/misc.py | 11 +-- buildutils/msg.py | 14 ++-- buildutils/patch.py | 11 +-- capnp/__init__.py | 20 ++++- capnp/_gen.py | 94 ++++++++++++------------ docs/conf.py | 126 ++++++++++++++++---------------- examples/addressbook.py | 3 +- examples/async_client.py | 92 ++++++++++++----------- examples/async_server.py | 3 +- examples/async_ssl_client.py | 116 +++++++++++++++-------------- examples/async_ssl_server.py | 2 +- examples/calculator_client.py | 2 +- examples/calculator_server.py | 3 +- examples/thread_client.py | 41 ++++++----- examples/thread_server.py | 1 + scripts/capnp-json.py | 7 +- scripts/capnp_test_pycapnp.py | 8 +- setup.py | 66 ++++++++++++----- test/test_capability.py | 8 +- test/test_capability_context.py | 12 +-- test/test_capability_old.py | 12 +-- test/test_large_read.py | 27 ++----- test/test_load.py | 14 ++-- test/test_object.py | 2 +- test/test_regression.py | 22 +++--- test/test_response.py | 5 -- test/test_rpc.py | 13 ++-- test/test_rpc_calculator.py | 16 ++-- test/test_serialization.py | 15 +++- test/test_struct.py | 23 +++--- test/test_threads.py | 53 +++++++++++--- 37 files changed, 536 insertions(+), 452 deletions(-) diff --git a/buildutils/__init__.py b/buildutils/__init__.py index 1da698d..65bb10d 100644 --- a/buildutils/__init__.py +++ b/buildutils/__init__.py @@ -2,6 +2,7 @@ Largely adapted from h5py """ +# flake8: noqa F401 F403 from .msg import * from .config import * diff --git a/buildutils/build.py b/buildutils/build.py index 82ffaab..5797c46 100644 --- a/buildutils/build.py +++ b/buildutils/build.py @@ -5,26 +5,29 @@ import os import tempfile def build_libcapnp(bundle_dir, build_dir, verbose=False): - bundle_dir = os.path.abspath(bundle_dir) - capnp_dir = os.path.join(bundle_dir, 'capnproto-c++') - build_dir = os.path.abspath(build_dir) + ''' + Build capnproto + ''' + bundle_dir = os.path.abspath(bundle_dir) + capnp_dir = os.path.join(bundle_dir, 'capnproto-c++') + build_dir = os.path.abspath(build_dir) - with tempfile.TemporaryFile() as f: - stdout = f - if verbose: - stdout = None - cxxflags = os.environ.get('CXXFLAGS', None) - os.environ['CXXFLAGS'] = (cxxflags or '') + ' -fPIC -O2 -DNDEBUG' - conf = subprocess.Popen(['./configure', '--disable-shared', '--prefix', build_dir], cwd=capnp_dir, stdout=stdout) - returncode = conf.wait() - if returncode != 0: - raise RuntimeError('Configure failed') + with tempfile.TemporaryFile() as f: + stdout = f + if verbose: + stdout = None + cxxflags = os.environ.get('CXXFLAGS', None) + os.environ['CXXFLAGS'] = (cxxflags or '') + ' -fPIC -O2 -DNDEBUG' + conf = subprocess.Popen(['./configure', '--disable-shared', '--prefix', build_dir], cwd=capnp_dir, stdout=stdout) + returncode = conf.wait() + if returncode != 0: + raise RuntimeError('Configure failed') - make = subprocess.Popen(['make', '-j4', 'install'], cwd=capnp_dir, stdout=stdout) - returncode = make.wait() - if cxxflags is None: - del os.environ['CXXFLAGS'] - else: - os.environ['CXXFLAGS'] = cxxflags - if returncode != 0: - raise RuntimeError('Make failed') + make = subprocess.Popen(['make', '-j4', 'install'], cwd=capnp_dir, stdout=stdout) + returncode = make.wait() + if cxxflags is None: + del os.environ['CXXFLAGS'] + else: + os.environ['CXXFLAGS'] = cxxflags + if returncode != 0: + raise RuntimeError('Make failed') diff --git a/buildutils/bundle.py b/buildutils/bundle.py index 18d0cdc..817797b 100644 --- a/buildutils/bundle.py +++ b/buildutils/bundle.py @@ -1,12 +1,11 @@ """utilities for fetching build dependencies.""" -#----------------------------------------------------------------------------- +# # Copyright (C) PyZMQ Developers # Distributed under the terms of the Modified BSD License. # # This bundling code is largely adapted from pyzmq-static's get.sh by # Brandon Craig-Rhodes, which is itself BSD licensed. -#----------------------------------------------------------------------------- # # Adapted for use in pycapnp from pyzmq. See https://github.com/zeromq/pyzmq # for original project. @@ -17,7 +16,6 @@ import shutil import stat import sys import tarfile -from glob import glob from subprocess import Popen, PIPE try: @@ -27,27 +25,28 @@ except ImportError: # py3 from urllib.request import urlopen -from .msg import fatal, debug, info, warn +from .msg import fatal, info, warn pjoin = os.path.join -#----------------------------------------------------------------------------- +# # Constants -#----------------------------------------------------------------------------- +# -bundled_version = (0,7,0) -libcapnp = "capnproto-c++-%i.%i.%i.tar.gz" % (bundled_version) -libcapnp_url = "https://capnproto.org/" + libcapnp +bundled_version = (0, 7, 4) +libcapnp_name = "capnproto-c++-%i.%i.%i.tar.gz" % (bundled_version) +libcapnp_url = "https://capnproto.org/" + libcapnp_name HERE = os.path.dirname(__file__) ROOT = os.path.dirname(HERE) -#----------------------------------------------------------------------------- +# # Utilities -#----------------------------------------------------------------------------- +# def untgz(archive): + """Remove .tar.gz""" return archive.replace('.tar.gz', '') def localpath(*args): @@ -69,9 +68,9 @@ def fetch_archive(savedir, url, fname, force=False): f.write(req.read()) return dest -#----------------------------------------------------------------------------- +# # libcapnp -#----------------------------------------------------------------------------- +# def fetch_libcapnp(savedir, url=None): """download and extract libcapnp""" @@ -83,7 +82,7 @@ def fetch_libcapnp(savedir, url=None): if os.path.exists(dest): info("already have %s" % dest) return - fname = fetch_archive(savedir, url, libcapnp) + fname = fetch_archive(savedir, url, libcapnp_name) tf = tarfile.open(fname) with_version = pjoin(savedir, tf.firstmember.path) tf.extractall(savedir) @@ -96,7 +95,7 @@ def fetch_libcapnp(savedir, url=None): conf = Popen(['autoreconf', '-i'], cwd=cpp_dir) returncode = conf.wait() if returncode != 0: - raise RuntimeError('Autoreconf failed. Make sure autotools are installed on your system.') + raise RuntimeError('Autoreconf failed. Make sure autotools are installed on your system.') shutil.move(cpp_dir, dest) @@ -120,7 +119,7 @@ def stage_platform_hpp(capnproot): p = Popen('./configure', cwd=capnproot, shell=True, stdout=PIPE, stderr=PIPE, ) - o,e = p.communicate() + _, e = p.communicate() if p.returncode: warn("failed to configure libcapnp:\n%s" % e) if sys.platform == 'darwin': @@ -146,14 +145,14 @@ def copy_and_patch_libcapnp(capnp, libcapnp): if sys.platform.startswith('win'): return # copy libcapnp into capnp for bdist - local = localpath('capnp',libcapnp) + local = localpath('capnp', libcapnp) if not capnp and not os.path.exists(local): fatal("Please specify capnp prefix via `setup.py configure --capnp=/path/to/capnp` " "or copy libcapnp into capnp/ manually prior to running bdist.") try: # resolve real file through symlinks lib = os.path.realpath(pjoin(capnp, 'lib', libcapnp)) - print ("copying %s -> %s"%(lib, local)) + print ("copying %s -> %s" % (lib, local)) shutil.copy(lib, local) except Exception: if not os.path.exists(local): @@ -167,11 +166,11 @@ def copy_and_patch_libcapnp(capnp, libcapnp): mode = os.stat(local).st_mode os.chmod(local, mode | stat.S_IWUSR) # patch install_name on darwin, instead of using rpath - cmd = ['install_name_tool', '-id', '@loader_path/../%s'%libcapnp, local] + cmd = ['install_name_tool', '-id', '@loader_path/../%s' % libcapnp, local] try: - p = Popen(cmd, stdout=PIPE,stderr=PIPE) + p = Popen(cmd, stdout=PIPE, stderr=PIPE) except OSError: fatal("install_name_tool not found, cannot patch libcapnp for bundling.") - out,err = p.communicate() + _, err = p.communicate() if p.returncode: - fatal("Could not patch bundled libcapnp install_name: %s"%err, p.returncode) + fatal("Could not patch bundled libcapnp install_name: %s" % err, p.returncode) diff --git a/buildutils/config.py b/buildutils/config.py index c674655..6701259 100644 --- a/buildutils/config.py +++ b/buildutils/config.py @@ -1,5 +1,5 @@ """Config functions""" -#----------------------------------------------------------------------------- +# # Copyright (C) PyZMQ Developers # # This file is part of pyzmq, copied and adapted from h5py. @@ -9,23 +9,24 @@ # # Distributed under the terms of the New BSD License. The full license is in # the file COPYING.BSD, distributed as part of this software. -#----------------------------------------------------------------------------- +# import sys import os import json +from .msg import debug, warn + try: from configparser import ConfigParser -except: +except Exception: from ConfigParser import ConfigParser pjoin = os.path.join -from .msg import debug, fatal, warn -#----------------------------------------------------------------------------- +# # Utility functions (adapted from h5py: http://h5py.googlecode.com) -#----------------------------------------------------------------------------- +# def load_config(name, base='conf'): @@ -46,7 +47,7 @@ def save_config(name, data, base='conf'): """Save config dict to JSON""" if not os.path.exists(base): os.mkdir(base) - fname = pjoin(base, name+'.json') + fname = pjoin(base, name + '.json') with open(fname, 'w') as f: json.dump(data, f, indent=2) @@ -69,7 +70,7 @@ def get_eargs(): def cfg2dict(cfg): """turn a ConfigParser into a nested dict - + because ConfigParser objects are dumb. """ d = {} @@ -120,7 +121,7 @@ def config_from_prefix(prefix): def merge(into, d): """merge two containers - + into is updated, d has priority """ if isinstance(into, dict): @@ -130,10 +131,9 @@ def merge(into, d): else: into[key] = merge(into[key], d[key]) return into - elif isinstance(into, list): + if isinstance(into, list): return into + d - else: - return d + return d def discover_settings(conf_base=None): """ Discover custom settings for ZMQ path""" @@ -147,11 +147,11 @@ def discover_settings(conf_base=None): } if sys.platform.startswith('win'): settings['have_sys_un_h'] = False - + if conf_base: # lowest priority merge(settings, load_config('config', conf_base)) merge(settings, get_cfg_args()) merge(settings, get_eargs()) - + return settings diff --git a/buildutils/constants.py b/buildutils/constants.py index e98c650..fa39722 100644 --- a/buildutils/constants.py +++ b/buildutils/constants.py @@ -23,7 +23,7 @@ pjoin = os.path.join root = os.path.abspath(pjoin(os.path.dirname(__file__), os.path.pardir)) sys.path.insert(0, pjoin(root, 'zmq', 'utils')) -from constant_names import all_names, no_prefix +from constant_names import all_names, no_prefix # noqa: E402 ifndef_t = """#ifndef {0} #define {0} (_PYZMQ_UNDEFINED) @@ -38,7 +38,7 @@ def cython_enums(): lines.append('enum: ZMQ_{0} "{0}"'.format(name)) else: lines.append('enum: ZMQ_{0}'.format(name)) - + return dict(ZMQ_ENUMS='\n '.join(lines)) def ifndefs(): @@ -79,5 +79,6 @@ def render_constants(): generate_file("constants.pxi", constants_pyx, pjoin(root, 'zmq', 'backend', 'cython')) generate_file("zmq_constants.h", ifndefs, pjoin(root, 'zmq', 'utils')) + if __name__ == '__main__': render_constants() diff --git a/buildutils/detect.py b/buildutils/detect.py index 7810380..19459b1 100644 --- a/buildutils/detect.py +++ b/buildutils/detect.py @@ -1,5 +1,5 @@ """Detect zmq version""" -#----------------------------------------------------------------------------- +# # Copyright (C) PyZMQ Developers # # This file is part of pyzmq, copied and adapted from h5py. @@ -9,7 +9,7 @@ # # Distributed under the terms of the New BSD License. The full license is in # the file COPYING.BSD, distributed as part of this software. -#----------------------------------------------------------------------------- +# # # Adapted for use in pycapnp from pyzmq. See https://github.com/zeromq/pyzmq # for original project. @@ -29,20 +29,20 @@ from .patch import patch_lib_paths pjoin = os.path.join -#----------------------------------------------------------------------------- +# # Utility functions (adapted from h5py: http://h5py.googlecode.com) -#----------------------------------------------------------------------------- +# def test_compilation(cfile, compiler=None, **compiler_attrs): """Test simple compilation with given settings""" cc = get_compiler(compiler, **compiler_attrs) - efile, ext = os.path.splitext(cfile) + efile, _ = os.path.splitext(cfile) cpreargs = lpreargs = [] if sys.platform == 'darwin': # use appropriate arch for compiler - if platform.architecture()[0]=='32bit': + if platform.architecture()[0] == '32bit': if platform.processor() == 'powerpc': cpu = 'ppc' else: @@ -53,7 +53,7 @@ def test_compilation(cfile, compiler=None, **compiler_attrs): # allow for missing UB arch, since it will still work: lpreargs = ['-undefined', 'dynamic_lookup'] if sys.platform == 'sunos5': - if platform.architecture()[0]=='32bit': + if platform.architecture()[0] == '32bit': lpreargs = ['-m32'] else: lpreargs = ['-m64'] @@ -65,6 +65,7 @@ def test_compilation(cfile, compiler=None, **compiler_attrs): return efile def compile_and_run(basedir, src, compiler=None, **compiler_attrs): + """Compile and run""" if not os.path.exists(basedir): os.makedirs(basedir) cfile = pjoin(basedir, os.path.basename(src)) @@ -130,11 +131,11 @@ def detect_version(basedir, compiler=None, **compiler_attrs): rc, so, se = get_output_error([efile]) if rc: - msg = "Error running version detection script:\n%s\n%s" % (so,se) + msg = "Error running version detection script:\n%s\n%s" % (so, se) logging.error(msg) raise IOError(msg) - handlers = {'vers': lambda val: tuple(int(v) for v in val.split('.'))} + handlers = {'vers': lambda val: tuple(int(v) for v in val.split('.'))} props = {} for line in (x for x in so.split('\n') if x): @@ -161,8 +162,9 @@ def test_build(): return detected -def erase_dir(dir): +def erase_dir(path): + """Erase directory""" try: - shutil.rmtree(dir) + shutil.rmtree(path) except Exception: pass diff --git a/buildutils/misc.py b/buildutils/misc.py index 5721ac1..fabb52d 100644 --- a/buildutils/misc.py +++ b/buildutils/misc.py @@ -4,7 +4,6 @@ # Distributed under the terms of the Modified BSD License. import os -import sys import logging from distutils import ccompiler from distutils.sysconfig import customize_compiler @@ -14,13 +13,8 @@ from subprocess import Popen, PIPE pjoin = os.path.join -if sys.version_info[0] >= 3: - u = lambda x: x -else: - u = lambda x: x.decode('utf8', 'replace') - - def customize_mingw(cc): + """customize mingw""" # strip -mno-cygwin from mingw32 (Python Issue #12641) for cmd in [cc.compiler, cc.compiler_cxx, cc.compiler_so, cc.linker_exe, cc.linker_so]: if '-mno-cygwin' in cmd: @@ -55,11 +49,10 @@ def get_output_error(cmd): try: result = Popen(cmd, stdout=PIPE, stderr=PIPE) except IOError as e: - return -1, u(''), u('Failed to run %r: %r' % (cmd, e)) + return -1, '', 'Failed to run %r: %r' % (cmd, e) so, se = result.communicate() # unicode: so = so.decode('utf8', 'replace') se = se.decode('utf8', 'replace') return result.returncode, so, se - diff --git a/buildutils/msg.py b/buildutils/msg.py index 70cd716..63f2e51 100644 --- a/buildutils/msg.py +++ b/buildutils/msg.py @@ -9,9 +9,9 @@ import os import sys import logging -#----------------------------------------------------------------------------- +# # Logging (adapted from h5py: http://h5py.googlecode.com) -#----------------------------------------------------------------------------- +# logger = logging.getLogger() @@ -22,18 +22,22 @@ else: logger.addHandler(logging.StreamHandler(sys.stderr)) def debug(msg): + """Debug""" logger.debug(msg) def info(msg): + """Info""" logger.info(msg) def fatal(msg, code=1): - logger.error("Fatal: " + msg) + """Fatal""" + logger.error("Fatal: %s", msg) exit(code) def warn(msg): - logger.error("Warning: " + msg) + """Warning""" + logger.error("Warning: %s", msg) def line(c='*', width=48): + """Horizontal rule""" print(c * (width // len(c))) - diff --git a/buildutils/patch.py b/buildutils/patch.py index 925b67b..dc58ac2 100644 --- a/buildutils/patch.py +++ b/buildutils/patch.py @@ -20,7 +20,7 @@ LIB_PAT = re.compile(r"\s*(.*) \(compatibility version (\d+\.\d+\.\d+), " def _get_libs(fname): rc, so, se = get_output_error(['otool', '-L', fname]) if rc: - logging.error("otool -L %s failed: %r" % (fname, se)) + logging.error("otool -L %s failed: %r", fname, se) return for line in so.splitlines()[1:]: m = LIB_PAT.match(line) @@ -33,6 +33,7 @@ def _find_library(lib, path): real_lib = os.path.join(d, lib) if os.path.exists(real_lib): return real_lib + return None def _install_name_change(fname, lib, real_lib): rc, so, se = get_output_error(['install_name_tool', '-change', lib, real_lib, fname]) @@ -41,15 +42,15 @@ def _install_name_change(fname, lib, real_lib): def patch_lib_paths(fname, library_dirs): """Load any weakly-defined libraries from their real location - + (only on OS X) - + - Find libraries with `otool -L` - Update with `install_name_tool -change` """ if sys.platform != 'darwin': return - + libs = _get_libs(fname) for lib in libs: if not lib.startswith(('@', '/')): @@ -58,4 +59,4 @@ def patch_lib_paths(fname, library_dirs): _install_name_change(fname, lib, real_lib) -__all__ = ['patch_lib_paths'] \ No newline at end of file +__all__ = ['patch_lib_paths'] diff --git a/capnp/__init__.py b/capnp/__init__.py index 2a04e92..7d36a9a 100644 --- a/capnp/__init__.py +++ b/capnp/__init__.py @@ -31,8 +31,26 @@ Example Usage:: for phone in person.phones: print(phone.type, ':', phone.number) """ +# flake8: noqa F401 F403 F405 from .version import version as __version__ from .lib.capnp import * -from .lib.capnp import _DynamicStructReader, _DynamicStructBuilder, _DynamicResizableListBuilder, _DynamicListReader, _DynamicListBuilder, _DynamicOrphan, _DynamicResizableListBuilder, _MallocMessageBuilder, _PackedFdMessageReader, _StreamFdMessageReader, _write_message_to_fd, _write_packed_message_to_fd, _StructModule, _InterfaceModule, _DynamicCapabilityClient, _CapabilityClient, _EventLoop +from .lib.capnp import ( + _CapabilityClient, + _DynamicCapabilityClient, + _DynamicListBuilder, + _DynamicListReader, + _DynamicOrphan, + _DynamicResizableListBuilder, + _DynamicStructBuilder, + _DynamicStructReader, + _EventLoop, + _InterfaceModule, + _MallocMessageBuilder, + _PackedFdMessageReader, + _StreamFdMessageReader, + _StructModule, + _write_message_to_fd, + _write_packed_message_to_fd, +) add_import_hook() # enable import hook by default diff --git a/capnp/_gen.py b/capnp/_gen.py index 5cb3eee..52087c1 100644 --- a/capnp/_gen.py +++ b/capnp/_gen.py @@ -7,58 +7,58 @@ from jinja2 import Environment, PackageLoader import os def find_type(code, id): - for node in code['nodes']: - if node['id'] == id: - return node + for node in code['nodes']: + if node['id'] == id: + return node - return None + return None def main(): - env = Environment(loader=PackageLoader('capnp', 'templates')) - env.filters['format_name'] = lambda name: name[name.find(':')+1:] + env = Environment(loader=PackageLoader('capnp', 'templates')) + env.filters['format_name'] = lambda name: name[name.find(':') + 1:] - code = schema_capnp.CodeGeneratorRequest.read(sys.stdin) - code=code.to_dict() - code['nodes'] = [node for node in code['nodes'] if 'struct' in node and node['scopeId'] != 0] - for node in code['nodes']: - displayName = node['displayName'] - parent, path = displayName.split(':') - node['module_path'] = parent.replace('.', '_') + '.' + '.'.join([x[0].upper() + x[1:] for x in path.split('.')]) - node['module_name'] = path.replace('.', '_') - node['c_module_path'] = '::'.join([x[0].upper() + x[1:] for x in path.split('.')]) - node['schema'] = '_{}_Schema'.format(node['module_name']) - is_union = False - for field in node['struct']['fields']: - if field['discriminantValue'] != 65535: - is_union = True - field['c_name'] = field['name'][0].upper() + field['name'][1:] - if 'slot' in field: - field['type'] = field['slot']['type'].keys()[0] - if not isinstance(field['slot']['type'][field['type']], dict): - continue - sub_type = field['slot']['type'][field['type']].get('typeId', None) - if sub_type: - field['sub_type'] = find_type(code, sub_type) - sub_type = field['slot']['type'][field['type']].get('elementType', None) - if sub_type: - field['sub_type'] = sub_type - else: - field['type'] = find_type(code, field['group']['typeId']) - node['is_union'] = is_union + code = schema_capnp.CodeGeneratorRequest.read(sys.stdin) + code = code.to_dict() + code['nodes'] = [node for node in code['nodes'] if 'struct' in node and node['scopeId'] != 0] + for node in code['nodes']: + displayName = node['displayName'] + parent, path = displayName.split(':') + node['module_path'] = parent.replace('.', '_') + '.' + '.'.join([x[0].upper() + x[1:] for x in path.split('.')]) + node['module_name'] = path.replace('.', '_') + node['c_module_path'] = '::'.join([x[0].upper() + x[1:] for x in path.split('.')]) + node['schema'] = '_{}_Schema'.format(node['module_name']) + is_union = False + for field in node['struct']['fields']: + if field['discriminantValue'] != 65535: + is_union = True + field['c_name'] = field['name'][0].upper() + field['name'][1:] + if 'slot' in field: + field['type'] = field['slot']['type'].keys()[0] + if not isinstance(field['slot']['type'][field['type']], dict): + continue + sub_type = field['slot']['type'][field['type']].get('typeId', None) + if sub_type: + field['sub_type'] = find_type(code, sub_type) + sub_type = field['slot']['type'][field['type']].get('elementType', None) + if sub_type: + field['sub_type'] = sub_type + else: + field['type'] = find_type(code, field['group']['typeId']) + node['is_union'] = is_union - include_dir = os.path.abspath(os.path.join(os.path.dirname(capnp.__file__), '..')) - module = env.get_template('module.pyx') + include_dir = os.path.abspath(os.path.join(os.path.dirname(capnp.__file__), '..')) + module = env.get_template('module.pyx') - for f in code['requestedFiles']: - filename = f['filename'].replace('.', '_') + '_cython.pyx' + for f in code['requestedFiles']: + filename = f['filename'].replace('.', '_') + '_cython.pyx' - file_code = dict(code) - file_code['nodes'] = [node for node in file_code['nodes'] if node['displayName'].startswith(f['filename'])] - with open(filename, 'w') as out: - out.write(module.render(code=file_code, file=f, include_dir=include_dir)) + file_code = dict(code) + file_code['nodes'] = [node for node in file_code['nodes'] if node['displayName'].startswith(f['filename'])] + with open(filename, 'w') as out: + out.write(module.render(code=file_code, file=f, include_dir=include_dir)) - setup = env.get_template('setup.py.tmpl') - with open('setup_capnp.py', 'w') as out: - out.write(setup.render(code=code)) - print('You now need to build the cython module by running `python setup_capnp.py build_ext --inplace`.') - print() + setup = env.get_template('setup.py.tmpl') + with open('setup_capnp.py', 'w') as out: + out.write(setup.render(code=code)) + print('You now need to build the cython module by running `python setup_capnp.py build_ext --inplace`.') + print() diff --git a/docs/conf.py b/docs/conf.py index 08eed2d..948267a 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -1,3 +1,6 @@ +''' +Docs configuration +''' # -*- coding: utf-8 -*- # # capnp documentation build configuration file, created by @@ -11,17 +14,19 @@ # All configuration values have a default; values that are commented out # serve to show the default. -import sys, os, string +import string +# import sys, os +import capnp # If extensions (or modules to document with autodoc) are in another directory, # add these directories to sys.path here. If the directory is relative to the # documentation root, use os.path.abspath to make it absolute, like shown here. -#sys.path.insert(0, os.path.abspath('.')) +# sys.path.insert(0, os.path.abspath('.')) # -- General configuration ----------------------------------------------------- # If your documentation needs a minimal Sphinx version, state it here. -#needs_sphinx = '1.0' +# needs_sphinx = '1.0' # Add any Sphinx extension module names here, as strings. They can be extensions # coming with Sphinx (named 'sphinx.ext.*') or your custom ones. @@ -34,7 +39,7 @@ templates_path = ['_templates'] source_suffix = '.rst' # The encoding of source files. -#source_encoding = 'utf-8-sig' +# source_encoding = 'utf-8-sig' # The master toctree document. master_doc = 'index' @@ -48,47 +53,46 @@ copyright = u'2013, Author' # built documents. # # The short X.Y version. -import capnp vs = capnp.__version__ # The short X.Y version. -version = vs.rstrip(string.letters) +version = vs.rstrip(string.ascii_letters) # The full version, including alpha/beta/rc tags. release = vs # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. -#language = None +# language = None # There are two options for replacing |today|: either, you set today to some # non-false value, then it is used: -#today = '' +# today = '' # Else, today_fmt is used as the format for a strftime call. -#today_fmt = '%B %d, %Y' +# today_fmt = '%B %d, %Y' # List of patterns, relative to source directory, that match files and # directories to ignore when looking for source files. exclude_patterns = ['_build'] # The reST default role (used for this markup: `text`) to use for all documents. -#default_role = None +# default_role = None # If true, '()' will be appended to :func: etc. cross-reference text. -#add_function_parentheses = True +# add_function_parentheses = True # If true, the current module name will be prepended to all description # unit titles (such as .. function::). -#add_module_names = True +# add_module_names = True # If true, sectionauthor and moduleauthor directives will be shown in the # output. They are ignored by default. -#show_authors = False +# show_authors = False # The name of the Pygments (syntax highlighting) style to use. pygments_style = 'sphinx' # A list of ignored prefixes for module index sorting. -#modindex_common_prefix = [] +# modindex_common_prefix = [] # -- Options for HTML output --------------------------------------------------- @@ -100,26 +104,26 @@ html_theme = 'nature' # Theme options are theme-specific and customize the look and feel of a theme # further. For a list of options available for each theme, see the # documentation. -#html_theme_options = {} +# html_theme_options = {} # Add any paths that contain custom themes here, relative to this directory. -#html_theme_path = [] +# html_theme_path = [] # The name for this set of Sphinx documents. If None, it defaults to # " v documentation". -#html_title = None +# html_title = None # A shorter title for the navigation bar. Default is the same as html_title. -#html_short_title = None +# html_short_title = None # The name of an image file (relative to this directory) to place at the top # of the sidebar. -#html_logo = None +# html_logo = None # The name of an image file (within the static path) to use as favicon of the # docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 # pixels large. -#html_favicon = None +# html_favicon = None # Add any paths that contain custom static files (such as style sheets) here, # relative to this directory. They are copied after the builtin static files, @@ -128,44 +132,44 @@ html_static_path = ['_static'] # If not '', a 'Last updated on:' timestamp is inserted at every page bottom, # using the given strftime format. -#html_last_updated_fmt = '%b %d, %Y' +# html_last_updated_fmt = '%b %d, %Y' # If true, SmartyPants will be used to convert quotes and dashes to # typographically correct entities. -#html_use_smartypants = True +# html_use_smartypants = True # Custom sidebar templates, maps document names to template names. -#html_sidebars = {} +# html_sidebars = {} # Additional templates that should be rendered to pages, maps page names to # template names. -#html_additional_pages = {} +# html_additional_pages = {} # If false, no module index is generated. -#html_domain_indices = True +# html_domain_indices = True # If false, no index is generated. -#html_use_index = True +# html_use_index = True # If true, the index is split into individual pages for each letter. -#html_split_index = False +# html_split_index = False # If true, links to the reST sources are added to the pages. -#html_show_sourcelink = True +# html_show_sourcelink = True # If true, "Created using Sphinx" is shown in the HTML footer. Default is True. -#html_show_sphinx = True +# html_show_sphinx = True # If true, "(C) Copyright ..." is shown in the HTML footer. Default is True. -#html_show_copyright = True +# html_show_copyright = True # If true, an OpenSearch description file will be output, and all pages will # contain a tag referring to it. The value of this option must be the # base URL from which the finished HTML is served. -#html_use_opensearch = '' +# html_use_opensearch = '' # This is the file name suffix for HTML files (e.g. ".xhtml"). -#html_file_suffix = None +# html_file_suffix = None # Output file base name for HTML help builder. htmlhelp_basename = 'capnpdoc' @@ -173,43 +177,43 @@ htmlhelp_basename = 'capnpdoc' # -- Options for LaTeX output -------------------------------------------------- -latex_elements = { # The paper size ('letterpaper' or 'a4paper'). -#'papersize': 'letterpaper', +# 'papersize': 'letterpaper', # The font size ('10pt', '11pt' or '12pt'). -#'pointsize': '10pt', +# 'pointsize': '10pt', # Additional stuff for the LaTeX preamble. -#'preamble': '', +# 'preamble': '', +latex_elements = { } # Grouping the document tree into LaTeX files. List of tuples # (source start file, target name, title, author, documentclass [howto/manual]). latex_documents = [ - ('index', 'capnp.tex', u'capnp Documentation', - u'Author', 'manual'), + ('index', 'capnp.tex', u'capnp Documentation', + u'Author', 'manual'), ] # The name of an image file (relative to this directory) to place at the top of # the title page. -#latex_logo = None +# latex_logo = None # For "manual" documents, if this is true, then toplevel headings are parts, # not chapters. -#latex_use_parts = False +# latex_use_parts = False # If true, show page references after internal links. -#latex_show_pagerefs = False +# latex_show_pagerefs = False # If true, show URL addresses after external links. -#latex_show_urls = False +# latex_show_urls = False # Documents to append as an appendix to all manuals. -#latex_appendices = [] +# latex_appendices = [] # If false, no module index is generated. -#latex_domain_indices = True +# latex_domain_indices = True # -- Options for manual page output -------------------------------------------- @@ -222,7 +226,7 @@ man_pages = [ ] # If true, show URL addresses after external links. -#man_show_urls = False +# man_show_urls = False # -- Options for Texinfo output ------------------------------------------------ @@ -231,19 +235,19 @@ man_pages = [ # (source start file, target name, title, author, # dir menu entry, description, category) texinfo_documents = [ - ('index', 'capnp', u'capnp Documentation', - u'Author', 'capnp', 'One line description of project.', - 'Miscellaneous'), + ('index', 'capnp', u'capnp Documentation', + u'Author', 'capnp', 'One line description of project.', + 'Miscellaneous'), ] # Documents to append as an appendix to all manuals. -#texinfo_appendices = [] +# texinfo_appendices = [] # If false, no module index is generated. -#texinfo_domain_indices = True +# texinfo_domain_indices = True # How to display URL addresses: 'footnote', 'no', or 'inline'. -#texinfo_show_urls = 'footnote' +# texinfo_show_urls = 'footnote' # -- Options for Epub output --------------------------------------------------- @@ -256,36 +260,36 @@ epub_copyright = u'2013, Author' # The language of the text. It defaults to the language option # or en if the language is not set. -#epub_language = '' +# epub_language = '' # The scheme of the identifier. Typical schemes are ISBN or URL. -#epub_scheme = '' +# epub_scheme = '' # The unique identifier of the text. This can be a ISBN number # or the project homepage. -#epub_identifier = '' +# epub_identifier = '' # A unique identification for the text. -#epub_uid = '' +# epub_uid = '' # A tuple containing the cover image and cover page html template filenames. -#epub_cover = () +# epub_cover = () # HTML files that should be inserted before the pages created by sphinx. # The format is a list of tuples containing the path and title. -#epub_pre_files = [] +# epub_pre_files = [] # HTML files shat should be inserted after the pages created by sphinx. # The format is a list of tuples containing the path and title. -#epub_post_files = [] +# epub_post_files = [] # A list of files that should not be packed into the epub file. -#epub_exclude_files = [] +# epub_exclude_files = [] # The depth of the table of contents in toc.ncx. -#epub_tocdepth = 3 +# epub_tocdepth = 3 # Allow duplicate toc entries. -#epub_tocdup = True +# epub_tocdup = True intersphinx_mapping = {'http://docs.python.org/': None} diff --git a/examples/addressbook.py b/examples/addressbook.py index c1ca793..b6ae64f 100755 --- a/examples/addressbook.py +++ b/examples/addressbook.py @@ -1,6 +1,5 @@ from __future__ import print_function -import os -import capnp +import capnp # noqa: F401 import addressbook_capnp diff --git a/examples/async_client.py b/examples/async_client.py index df70f27..6808faa 100755 --- a/examples/async_client.py +++ b/examples/async_client.py @@ -4,7 +4,6 @@ from __future__ import print_function import asyncio import argparse -import threading import time import capnp import socket @@ -16,15 +15,14 @@ capnp.create_event_loop(threaded=True) def parse_args(): - parser = argparse.ArgumentParser(usage='Connects to the Example thread server \ + parser = argparse.ArgumentParser(usage='Connects to the Example thread server \ at the given address and does some RPCs') - parser.add_argument("host", help="HOST:PORT") + parser.add_argument("host", help="HOST:PORT") - return parser.parse_args() + return parser.parse_args() class StatusSubscriber(thread_capnp.Example.StatusSubscriber.Server): - '''An implementation of the StatusSubscriber interface''' def status(self, value, **kwargs): @@ -32,61 +30,61 @@ class StatusSubscriber(thread_capnp.Example.StatusSubscriber.Server): async def myreader(client, reader): - while True: - data = await reader.read(4096) - client.write(data) + while True: + data = await reader.read(4096) + client.write(data) async def mywriter(client, writer): - while True: - data = await client.read(4096) - writer.write(data.tobytes()) - await writer.drain() + while True: + data = await client.read(4096) + writer.write(data.tobytes()) + await writer.drain() async def background(cap): - subscriber = StatusSubscriber() - promise = cap.subscribeStatus(subscriber) - await promise.a_wait() + subscriber = StatusSubscriber() + promise = cap.subscribeStatus(subscriber) + await promise.a_wait() async def main(host): - host = host.split(':') - addr = host[0] - port = host[1] - # Handle both IPv4 and IPv6 cases - try: - print("Try IPv4") - reader, writer = await asyncio.open_connection( - addr, port, - ) - except: - print("Try IPv6") - reader, writer = await asyncio.open_connection( - addr, port, - family=socket.AF_INET6 - ) + host = host.split(':') + addr = host[0] + port = host[1] + # Handle both IPv4 and IPv6 cases + try: + print("Try IPv4") + reader, writer = await asyncio.open_connection( + addr, port, + ) + except Exception: + print("Try IPv6") + reader, writer = await asyncio.open_connection( + addr, port, + family=socket.AF_INET6 + ) - # Start TwoPartyClient using TwoWayPipe (takes no arguments in this mode) - client = capnp.TwoPartyClient() - cap = client.bootstrap().cast_as(thread_capnp.Example) + # Start TwoPartyClient using TwoWayPipe (takes no arguments in this mode) + client = capnp.TwoPartyClient() + cap = client.bootstrap().cast_as(thread_capnp.Example) - # Assemble reader and writer tasks, run in the background - coroutines = [myreader(client, reader), mywriter(client, writer)] - asyncio.gather(*coroutines, return_exceptions=True) + # Assemble reader and writer tasks, run in the background + coroutines = [myreader(client, reader), mywriter(client, writer)] + asyncio.gather(*coroutines, return_exceptions=True) - # Start background task for subscriber - tasks = [background(cap)] - asyncio.gather(*tasks, return_exceptions=True) + # Start background task for subscriber + tasks = [background(cap)] + asyncio.gather(*tasks, return_exceptions=True) - # Run blocking tasks - print('main: {}'.format(time.time())) - await cap.longRunning().a_wait() - print('main: {}'.format(time.time())) - await cap.longRunning().a_wait() - print('main: {}'.format(time.time())) - await cap.longRunning().a_wait() - print('main: {}'.format(time.time())) + # Run blocking tasks + print('main: {}'.format(time.time())) + await cap.longRunning().a_wait() + print('main: {}'.format(time.time())) + await cap.longRunning().a_wait() + print('main: {}'.format(time.time())) + await cap.longRunning().a_wait() + print('main: {}'.format(time.time())) if __name__ == '__main__': asyncio.run(main(parse_args().host)) diff --git a/examples/async_server.py b/examples/async_server.py index 1c6d81e..5030ec3 100755 --- a/examples/async_server.py +++ b/examples/async_server.py @@ -72,7 +72,7 @@ async def main(): myserver, addr, port, ) - except: + except Exception: print("Try IPv6") server = await asyncio.start_server( myserver, @@ -83,5 +83,6 @@ async def main(): async with server: await server.serve_forever() + if __name__ == '__main__': asyncio.run(main()) diff --git a/examples/async_ssl_client.py b/examples/async_ssl_client.py index 6534219..a95d03a 100755 --- a/examples/async_ssl_client.py +++ b/examples/async_ssl_client.py @@ -4,7 +4,6 @@ from __future__ import print_function import asyncio import argparse -import threading import time import capnp import socket @@ -17,87 +16,86 @@ capnp.create_event_loop(threaded=True) def parse_args(): - parser = argparse.ArgumentParser(usage='Connects to the Example thread server \ + parser = argparse.ArgumentParser(usage='Connects to the Example thread server \ at the given address and does some RPCs') - parser.add_argument("host", help="HOST:PORT") + parser.add_argument("host", help="HOST:PORT") - return parser.parse_args() + return parser.parse_args() class StatusSubscriber(thread_capnp.Example.StatusSubscriber.Server): + '''An implementation of the StatusSubscriber interface''' - '''An implementation of the StatusSubscriber interface''' - - def status(self, value, **kwargs): - print('status: {}'.format(time.time())) + def status(self, value, **kwargs): + print('status: {}'.format(time.time())) async def myreader(client, reader): - while True: - data = await reader.read(4096) - client.write(data) + while True: + data = await reader.read(4096) + client.write(data) async def mywriter(client, writer): - while True: - data = await client.read(4096) - writer.write(data.tobytes()) - await writer.drain() + while True: + data = await client.read(4096) + writer.write(data.tobytes()) + await writer.drain() async def background(cap): - subscriber = StatusSubscriber() - promise = cap.subscribeStatus(subscriber) - await promise.a_wait() + subscriber = StatusSubscriber() + promise = cap.subscribeStatus(subscriber) + await promise.a_wait() async def main(host): - host = host.split(':') - addr = host[0] - port = host[1] + host = host.split(':') + addr = host[0] + port = host[1] - # Setup SSL context - ctx = ssl.create_default_context(ssl.Purpose.SERVER_AUTH, cafile='selfsigned.cert') + # Setup SSL context + ctx = ssl.create_default_context(ssl.Purpose.SERVER_AUTH, cafile='selfsigned.cert') - # Handle both IPv4 and IPv6 cases - try: - print("Try IPv4") - reader, writer = await asyncio.open_connection( - addr, port, - ssl=ctx, - ) - except: - print("Try IPv6") - reader, writer = await asyncio.open_connection( - addr, port, - ssl=ctx, - family=socket.AF_INET6 - ) + # Handle both IPv4 and IPv6 cases + try: + print("Try IPv4") + reader, writer = await asyncio.open_connection( + addr, port, + ssl=ctx, + ) + except Exception: + print("Try IPv6") + reader, writer = await asyncio.open_connection( + addr, port, + ssl=ctx, + family=socket.AF_INET6 + ) - # Start TwoPartyClient using TwoWayPipe (takes no arguments in this mode) - client = capnp.TwoPartyClient() - cap = client.bootstrap().cast_as(thread_capnp.Example) + # Start TwoPartyClient using TwoWayPipe (takes no arguments in this mode) + client = capnp.TwoPartyClient() + cap = client.bootstrap().cast_as(thread_capnp.Example) - # Assemble reader and writer tasks, run in the background - coroutines = [myreader(client, reader), mywriter(client, writer)] - asyncio.gather(*coroutines, return_exceptions=True) + # Assemble reader and writer tasks, run in the background + coroutines = [myreader(client, reader), mywriter(client, writer)] + asyncio.gather(*coroutines, return_exceptions=True) - # Start background task for subscriber - tasks = [background(cap)] - asyncio.gather(*tasks, return_exceptions=True) + # Start background task for subscriber + tasks = [background(cap)] + asyncio.gather(*tasks, return_exceptions=True) - # Run blocking tasks - print('main: {}'.format(time.time())) - await cap.longRunning().a_wait() - print('main: {}'.format(time.time())) - await cap.longRunning().a_wait() - print('main: {}'.format(time.time())) - await cap.longRunning().a_wait() - print('main: {}'.format(time.time())) + # Run blocking tasks + print('main: {}'.format(time.time())) + await cap.longRunning().a_wait() + print('main: {}'.format(time.time())) + await cap.longRunning().a_wait() + print('main: {}'.format(time.time())) + await cap.longRunning().a_wait() + print('main: {}'.format(time.time())) if __name__ == '__main__': - # Using asyncio.run hits an asyncio ssl bug - # https://bugs.python.org/issue36709 - #asyncio.run(main(parse_args().host), loop=loop, debug=True) - loop = asyncio.get_event_loop() - loop.run_until_complete(main(parse_args().host)) + # Using asyncio.run hits an asyncio ssl bug + # https://bugs.python.org/issue36709 + # asyncio.run(main(parse_args().host), loop=loop, debug=True) + loop = asyncio.get_event_loop() + loop.run_until_complete(main(parse_args().host)) diff --git a/examples/async_ssl_server.py b/examples/async_ssl_server.py index 2fcad3b..ebbcf47 100755 --- a/examples/async_ssl_server.py +++ b/examples/async_ssl_server.py @@ -78,7 +78,7 @@ async def main(): addr, port, ssl=ctx, ) - except: + except Exception: print("Try IPv6") server = await asyncio.start_server( myserver, diff --git a/examples/calculator_client.py b/examples/calculator_client.py index de246c3..f6569e4 100755 --- a/examples/calculator_client.py +++ b/examples/calculator_client.py @@ -2,7 +2,6 @@ from __future__ import print_function import argparse -import socket import capnp import calculator_capnp @@ -302,5 +301,6 @@ def main(host): print("PASS") + if __name__ == '__main__': main(parse_args().host) diff --git a/examples/calculator_server.py b/examples/calculator_server.py index f072f58..32af680 100755 --- a/examples/calculator_server.py +++ b/examples/calculator_server.py @@ -2,8 +2,6 @@ from __future__ import print_function import argparse -import socket -import random import capnp import calculator_capnp @@ -136,5 +134,6 @@ def main(): server = capnp.TwoPartyServer(address, bootstrap=CalculatorImpl()) server.run_forever() + if __name__ == '__main__': main() diff --git a/examples/thread_client.py b/examples/thread_client.py index 459550b..fdd50ad 100755 --- a/examples/thread_client.py +++ b/examples/thread_client.py @@ -14,11 +14,11 @@ capnp.create_event_loop(threaded=True) def parse_args(): - parser = argparse.ArgumentParser(usage='Connects to the Example thread server \ + parser = argparse.ArgumentParser(usage='Connects to the Example thread server \ at the given address and does some RPCs') - parser.add_argument("host", help="HOST:PORT") + parser.add_argument("host", help="HOST:PORT") - return parser.parse_args() + return parser.parse_args() class StatusSubscriber(thread_capnp.Example.StatusSubscriber.Server): @@ -30,29 +30,30 @@ class StatusSubscriber(thread_capnp.Example.StatusSubscriber.Server): def start_status_thread(host): - client = capnp.TwoPartyClient(host) - cap = client.bootstrap().cast_as(thread_capnp.Example) + client = capnp.TwoPartyClient(host) + cap = client.bootstrap().cast_as(thread_capnp.Example) - subscriber = StatusSubscriber() - promise = cap.subscribeStatus(subscriber) - promise.wait() + subscriber = StatusSubscriber() + promise = cap.subscribeStatus(subscriber) + promise.wait() def main(host): - client = capnp.TwoPartyClient(host) - cap = client.bootstrap().cast_as(thread_capnp.Example) + client = capnp.TwoPartyClient(host) + cap = client.bootstrap().cast_as(thread_capnp.Example) - status_thread = threading.Thread(target=start_status_thread, args=(host,)) - status_thread.daemon = True - status_thread.start() + status_thread = threading.Thread(target=start_status_thread, args=(host,)) + status_thread.daemon = True + status_thread.start() + + print('main: {}'.format(time.time())) + cap.longRunning().wait() + print('main: {}'.format(time.time())) + cap.longRunning().wait() + print('main: {}'.format(time.time())) + cap.longRunning().wait() + print('main: {}'.format(time.time())) - print('main: {}'.format(time.time())) - cap.longRunning().wait() - print('main: {}'.format(time.time())) - cap.longRunning().wait() - print('main: {}'.format(time.time())) - cap.longRunning().wait() - print('main: {}'.format(time.time())) if __name__ == '__main__': main(parse_args().host) diff --git a/examples/thread_server.py b/examples/thread_server.py index a61a767..142bd1f 100755 --- a/examples/thread_server.py +++ b/examples/thread_server.py @@ -37,5 +37,6 @@ def main(): server = capnp.TwoPartyServer(address, bootstrap=ExampleImpl()) server.run_forever() + if __name__ == '__main__': main() diff --git a/scripts/capnp-json.py b/scripts/capnp-json.py index f41a05e..cc385d7 100755 --- a/scripts/capnp-json.py +++ b/scripts/capnp-json.py @@ -18,7 +18,7 @@ def encode(schema_file, struct_name, **kwargs): schema = capnp.load(schema_file) struct_schema = getattr(schema, struct_name) - + struct_dict = json.load(sys.stdin) struct = struct_schema.from_dict(struct_dict) @@ -29,7 +29,7 @@ def decode(schema_file, struct_name, defaults): struct_schema = getattr(schema, struct_name) struct = struct_schema.read(sys.stdin) - + json.dump(struct.to_dict(defaults), sys.stdout) def main(): @@ -41,4 +41,5 @@ def main(): globals()[command](**kwargs) # hacky way to get defined functions, and call function with name=command -main() \ No newline at end of file + +main() diff --git a/scripts/capnp_test_pycapnp.py b/scripts/capnp_test_pycapnp.py index 5a02600..7f6b046 100755 --- a/scripts/capnp_test_pycapnp.py +++ b/scripts/capnp_test_pycapnp.py @@ -1,12 +1,13 @@ #!/usr/bin/env python from __future__ import print_function -import capnp import os +import sys + +import capnp capnp.add_import_hook([os.getcwd(), "/usr/local/include/"]) # change this to be auto-detected? -import test_capnp +import test_capnp # noqa: E402 -import sys def decode(name): class_name = name[0].upper() + name[1:] @@ -18,6 +19,7 @@ def encode(name): message = getattr(test_capnp, class_name).from_dict(val.to_dict()) print(message.to_bytes()) + if sys.argv[1] == 'decode': decode(sys.argv[2]) else: diff --git a/setup.py b/setup.py index db60d82..5bef173 100644 --- a/setup.py +++ b/setup.py @@ -1,15 +1,23 @@ #!/usr/bin/env python +''' +pycapnp distutils setup.py +''' + from __future__ import print_function -use_cython = False - -from setuptools import setup import os import sys -from buildutils import test_build, fetch_libcapnp, build_libcapnp, info + +from distutils.command.clean import clean as _clean from distutils.errors import CompileError from distutils.extension import Extension +from setuptools import setup + +from buildutils import test_build, fetch_libcapnp, build_libcapnp, info + +use_cython = False + _this_dir = os.path.dirname(__file__) MAJOR = 0 @@ -20,10 +28,14 @@ VERSION = '%d.%d.%d' % (MAJOR, MINOR, MICRO) # Write version info def write_version_py(filename=None): + ''' + Generate pycapnp version + ''' cnt = """\ version = '%s' short_version = '%s' +# flake8: noqa E402 F401 from .lib.capnp import _CAPNP_VERSION_MAJOR as LIBCAPNP_VERSION_MAJOR from .lib.capnp import _CAPNP_VERSION_MINOR as LIBCAPNP_VERSION_MINOR from .lib.capnp import _CAPNP_VERSION_MICRO as LIBCAPNP_VERSION_MICRO @@ -39,6 +51,7 @@ from .lib.capnp import _CAPNP_VERSION as LIBCAPNP_VERSION finally: a.close() + write_version_py() # Try to convert README using pandoc @@ -49,13 +62,14 @@ try: changelog = '\nChangelog\n=============\n' + changelog long_description += changelog except (IOError, ImportError): - if len(sys.argv) and sys.argv[-1] == 'sdist': + if sys.argv and sys.argv[-1] == 'sdist': raise long_description = '' -# Clean command, invoked with `python setup.py clean` -from distutils.command.clean import clean as _clean class clean(_clean): + ''' + Clean command, invoked with `python setup.py clean` + ''' def run(self): _clean.run(self) for x in [ 'capnp/lib/capnp.cpp', 'capnp/lib/capnp.h', 'capnp/version.py' ]: @@ -65,6 +79,7 @@ class clean(_clean): except OSError: pass + # set use_cython if lib/capnp.cpp is not detected capnp_compiled_file = os.path.join(os.path.dirname(__file__), 'capnp', 'lib', 'capnp.cpp') if not os.path.isfile(capnp_compiled_file): @@ -87,7 +102,7 @@ try: libcapnp_url = sys.argv[libcapnp_url_index + 1] sys.argv.remove("--libcapnp-url") sys.argv.remove(libcapnp_url) -except: +except Exception: pass if use_cython: @@ -96,6 +111,9 @@ else: from distutils.command.build_ext import build_ext as build_ext_c class build_libcapnp_ext(build_ext_c): + ''' + Build capnproto library + ''' def build_extension(self, ext): build_ext_c.build_extension(self, ext) @@ -114,7 +132,12 @@ class build_libcapnp_ext(build_ext_c): need_build = True if need_build: - info("*WARNING* no libcapnp detected or rebuild forced. Will download and build it from source now. If you have C++ Cap'n Proto installed, it may be out of date or is not being detected. Downloading and building libcapnp may take a while.") + info( + "*WARNING* no libcapnp detected or rebuild forced. " + "Will download and build it from source now. " + "If you have C++ Cap'n Proto installed, it may be out of date or is not being detected. " + "Downloading and building libcapnp may take a while." + ) bundle_dir = os.path.join(_this_dir, "bundled") if not os.path.exists(bundle_dir): os.mkdir(bundle_dir) @@ -130,9 +153,10 @@ class build_libcapnp_ext(build_ext_c): return build_ext_c.run(self) + if use_cython: from Cython.Build import cythonize - import Cython + import Cython # noqa: F401 extensions = cythonize('capnp/lib/*.pyx') else: extensions = [Extension("capnp.lib.capnp", ["capnp/lib/capnp.cpp"], @@ -145,9 +169,14 @@ setup( name="pycapnp", packages=["capnp"], version=VERSION, - package_data={'capnp': ['*.pxd', '*.h', '*.capnp', 'helpers/*.pxd', 'helpers/*.h', 'includes/*.pxd', 'lib/*.pxd', 'lib/*.py', 'lib/*.pyx', 'templates/*']}, + package_data={ + 'capnp': [ + '*.pxd', '*.h', '*.capnp', 'helpers/*.pxd', 'helpers/*.h', + 'includes/*.pxd', 'lib/*.pxd', 'lib/*.py', 'lib/*.pyx', 'templates/*' + ] + }, ext_modules=extensions, - cmdclass = { + cmdclass={ 'clean': clean, 'build_ext': build_libcapnp_ext }, @@ -161,10 +190,10 @@ setup( license='BSD', author="Jason Paryani", author_email="pypi-contact@jparyani.com", - url = 'https://github.com/jparyani/pycapnp', - download_url = 'https://github.com/jparyani/pycapnp/archive/v%s.zip' % VERSION, - keywords = ['capnp', 'capnproto', "Cap'n Proto"], - classifiers = [ + url='https://github.com/jparyani/pycapnp', + download_url='https://github.com/jparyani/pycapnp/archive/v%s.zip' % VERSION, + keywords=['capnp', 'capnproto', "Cap'n Proto"], + classifiers=[ 'Development Status :: 4 - Beta', 'Intended Audience :: Developers', 'License :: OSI Approved :: BSD License', @@ -172,12 +201,9 @@ setup( 'Operating System :: POSIX', 'Programming Language :: C++', 'Programming Language :: Cython', - 'Programming Language :: Python :: 2', - 'Programming Language :: Python :: 2.7', - 'Programming Language :: Python :: 3', - 'Programming Language :: Python :: 3.4', 'Programming Language :: Python :: 3.5', 'Programming Language :: Python :: 3.6', + 'Programming Language :: Python :: 3.7', 'Programming Language :: Python :: Implementation :: PyPy', 'Topic :: Communications'], ) diff --git a/test/test_capability.py b/test/test_capability.py index 71114ac..5ec1fdb 100644 --- a/test/test_capability.py +++ b/test/test_capability.py @@ -1,8 +1,7 @@ import pytest -import capnp -import os import time +import capnp import test_capability_capnp as capability class Server(capability.TestInterface.Server): @@ -160,6 +159,7 @@ class BadPipelineServer(capability.TestPipeline.Server): _results = _context.results _results.s = response.x + '_foo' _results.outBox.cap = Server(100) + def _error(error): raise Exception('test was a success') @@ -186,7 +186,7 @@ def test_pipeline_exception(): pipelinePromise = outCap.foo(i=10) with pytest.raises(Exception): - loop.wait(pipelinePromise) + pipelinePromise.wait() with pytest.raises(Exception): remote.wait() @@ -194,7 +194,7 @@ def test_pipeline_exception(): def test_casting(): client = capability.TestExtends._new_client(Server()) client2 = client.upcast(capability.TestInterface) - client3 = client2.cast_as(capability.TestInterface) + _ = client2.cast_as(capability.TestInterface) with pytest.raises(Exception): client.upcast(capability.TestPipeline) diff --git a/test/test_capability_context.py b/test/test_capability_context.py index 4f2c111..0ddbb85 100644 --- a/test/test_capability_context.py +++ b/test/test_capability_context.py @@ -1,12 +1,13 @@ -import pytest -import capnp import os +import pytest + +import capnp this_dir = os.path.dirname(__file__) @pytest.fixture def capability(): - return capnp.load(os.path.join(this_dir, 'test_capability.capnp')) + return capnp.load(os.path.join(this_dir, 'test_capability.capnp')) class Server: def __init__(self, val=1): @@ -150,6 +151,7 @@ class BadPipelineServer: def _then(response): context.results.s = response.x + '_foo' context.results.outBox.cap = capability().TestInterface._new_server(Server(100)) + def _error(error): raise Exception('test was a success') @@ -176,7 +178,7 @@ def test_pipeline_exception_context(capability): pipelinePromise = outCap.foo(i=10) with pytest.raises(Exception): - loop.wait(pipelinePromise) + pipelinePromise.wait() with pytest.raises(Exception): remote.wait() @@ -184,7 +186,7 @@ def test_pipeline_exception_context(capability): def test_casting_context(capability): client = capability.TestExtends._new_client(Server()) client2 = client.upcast(capability.TestInterface) - client3 = client2.cast_as(capability.TestInterface) + _ = client2.cast_as(capability.TestInterface) with pytest.raises(Exception): client.upcast(capability.TestPipeline) diff --git a/test/test_capability_old.py b/test/test_capability_old.py index beaa5ca..5eb4ef6 100644 --- a/test/test_capability_old.py +++ b/test/test_capability_old.py @@ -1,12 +1,13 @@ -import pytest -import capnp import os +import pytest + +import capnp this_dir = os.path.dirname(__file__) @pytest.fixture def capability(): - return capnp.load(os.path.join(this_dir, 'test_capability.capnp')) + return capnp.load(os.path.join(this_dir, 'test_capability.capnp')) class Server: def __init__(self, val=1): @@ -154,6 +155,7 @@ class BadPipelineServer: _results = _context.results _results.s = response.x + '_foo' _results.outBox.cap = capability().TestInterface._new_server(Server(100)) + def _error(error): raise Exception('test was a success') @@ -180,7 +182,7 @@ def test_pipeline_exception(capability): pipelinePromise = outCap.foo(i=10) with pytest.raises(Exception): - loop.wait(pipelinePromise) + pipelinePromise.wait() with pytest.raises(Exception): remote.wait() @@ -188,7 +190,7 @@ def test_pipeline_exception(capability): def test_casting(capability): client = capability.TestExtends._new_client(Server()) client2 = client.upcast(capability.TestInterface) - client3 = client2.cast_as(capability.TestInterface) + _ = client2.cast_as(capability.TestInterface) with pytest.raises(Exception): client.upcast(capability.TestPipeline) diff --git a/test/test_large_read.py b/test/test_large_read.py index e912008..d9e76c1 100644 --- a/test/test_large_read.py +++ b/test/test_large_read.py @@ -1,9 +1,10 @@ -import pytest -import platform -import capnp import os +import platform import tempfile -import sys + +import pytest + +import capnp this_dir = os.path.dirname(__file__) @@ -49,7 +50,7 @@ def get_two_adjacent_messages(test_capnp): msg2 = test_capnp.Msg.new_message() m2 = msg2.to_bytes() - return m1 + m2 + return m1 + m2 def test_large_read_multiple_bytes(test_capnp): data = get_two_adjacent_messages(test_capnp) @@ -81,19 +82,3 @@ def test_large_read_mutltiple_bytes_memoryview(test_capnp): data = get_two_adjacent_messages(test_capnp) + b' ' for m in test_capnp.Msg.read_multiple_bytes(memoryview(data)): pass - -@pytest.mark.skipif(sys.version_info[0] == 3, reason="Legacy buffer support only for python 2.7") -def test_large_read_mutltiple_bytes_buffer(test_capnp): - data = get_two_adjacent_messages(test_capnp) - for m in test_capnp.Msg.read_multiple_bytes(buffer(data)): - pass - - with pytest.raises(capnp.KjException): - data = get_two_adjacent_messages(test_capnp)[:-1] - for m in test_capnp.Msg.read_multiple_bytes(buffer(data)): - pass - - with pytest.raises(capnp.KjException): - data = get_two_adjacent_messages(test_capnp) + b' ' - for m in test_capnp.Msg.read_multiple_bytes(buffer(data)): - pass diff --git a/test/test_load.py b/test/test_load.py index 7f6d6af..f544f18 100644 --- a/test/test_load.py +++ b/test/test_load.py @@ -7,15 +7,15 @@ this_dir = os.path.dirname(__file__) @pytest.fixture def addressbook(): - return capnp.load(os.path.join(this_dir, 'addressbook.capnp')) + return capnp.load(os.path.join(this_dir, 'addressbook.capnp')) @pytest.fixture def foo(): - return capnp.load(os.path.join(this_dir, 'foo.capnp')) + return capnp.load(os.path.join(this_dir, 'foo.capnp')) @pytest.fixture def bar(): - return capnp.load(os.path.join(this_dir, 'bar.capnp')) + return capnp.load(os.path.join(this_dir, 'bar.capnp')) def test_basic_load(): capnp.load(os.path.join(this_dir, 'addressbook.capnp')) @@ -56,13 +56,13 @@ def test_failed_import(): bar.foo = foo def test_defualt_import_hook(): - import addressbook_capnp + import addressbook_capnp # noqa: F401 def test_dash_import(): - import addressbook_with_dashes_capnp + import addressbook_with_dashes_capnp # noqa: F401 def test_spaces_import(): - import addressbook_with_spaces_capnp + import addressbook_with_spaces_capnp # noqa: F401 def test_add_import_hook(): capnp.add_import_hook([this_dir]) @@ -86,4 +86,4 @@ def test_remove_import_hook(): del sys.modules['addressbook_capnp'] # hack to deal with it being imported already with pytest.raises(ImportError): - import addressbook_capnp + import addressbook_capnp # noqa: F401 diff --git a/test/test_object.py b/test/test_object.py index f87e124..3fee49a 100644 --- a/test/test_object.py +++ b/test/test_object.py @@ -7,7 +7,7 @@ this_dir = os.path.dirname(__file__) @pytest.fixture def addressbook(): - return capnp.load(os.path.join(this_dir, 'addressbook.capnp')) + return capnp.load(os.path.join(this_dir, 'addressbook.capnp')) def test_object_basic(addressbook): diff --git a/test/test_regression.py b/test/test_regression.py index 93a8a26..12bde05 100644 --- a/test/test_regression.py +++ b/test/test_regression.py @@ -1,4 +1,4 @@ - # -*- coding: utf-8 -*- +# -*- coding: utf-8 -*- import pytest import capnp @@ -16,7 +16,7 @@ else: @pytest.fixture def addressbook(): - return capnp.load(os.path.join(this_dir, 'addressbook.capnp')) + return capnp.load(os.path.join(this_dir, 'addressbook.capnp')) def test_addressbook_message_classes(addressbook): def writeAddressBook(fd): @@ -71,7 +71,7 @@ def test_addressbook_message_classes(addressbook): assert bobPhones[0].type == 'home' assert bobPhones[1].number == "555-7654" assert bobPhones[1].type == 'work' - assert bob.employment.unemployed == None + assert bob.employment.unemployed is None f = open('example', 'w') writeAddressBook(f.fileno()) @@ -130,7 +130,7 @@ def test_addressbook(addressbook): assert bobPhones[0].type == 'home' assert bobPhones[1].number == "555-7654" assert bobPhones[1].type == 'work' - assert bob.employment.unemployed == None + assert bob.employment.unemployed is None f = open('example', 'w') @@ -192,7 +192,7 @@ def test_addressbook_resizable(addressbook): assert bobPhones[0].type == 'home' assert bobPhones[1].number == "555-7654" assert bobPhones[1].type == 'work' - assert bob.employment.unemployed == None + assert bob.employment.unemployed is None f = open('example', 'w') @@ -262,7 +262,7 @@ def test_addressbook_explicit_fields(addressbook): assert bobPhones[1]._get_by_field(phone_fields['number']) == "555-7654" assert bobPhones[1]._get_by_field(phone_fields['type']) == 'work' employment = bob._get_by_field(person_fields['employment']) - employment._get_by_field(addressbook.Person.Employment.schema.fields['unemployed']) == None + employment._get_by_field(addressbook.Person.Employment.schema.fields['unemployed']) is None f = open('example', 'w') @@ -371,8 +371,8 @@ def check_list(reader, expected): assert reader[i] == v def check_all_types(reader): - assert reader.voidField == None - assert reader.boolField == True + assert reader.voidField is None + assert reader.boolField assert reader.int8Field == -123 assert reader.int16Field == -12345 assert reader.int32Field == -12345678 @@ -387,8 +387,8 @@ def check_all_types(reader): assert reader.dataField == b"bar" subReader = reader.structField - assert subReader.voidField == None - assert subReader.boolField == True + assert subReader.voidField is None + assert subReader.boolField assert subReader.int8Field == -12 assert subReader.int16Field == 3456 assert subReader.int32Field == -78901234 @@ -495,7 +495,7 @@ def test_build_first_segment_size(all_types): expectedText = open(os.path.join(this_dir, 'all-types.txt'), 'r').read() assert str(root) + '\n' == expectedText - root = all_types.TestAllTypes.new_message(1024*1024) + root = all_types.TestAllTypes.new_message(1024 * 1024) init_all_types(root) expectedText = open(os.path.join(this_dir, 'all-types.txt'), 'r').read() assert str(root) + '\n' == expectedText diff --git a/test/test_response.py b/test/test_response.py index c9bff3d..ae3eb40 100644 --- a/test/test_response.py +++ b/test/test_response.py @@ -1,8 +1,3 @@ -import pytest -import capnp -import os -import time - import test_response_capnp class FooServer(test_response_capnp.Foo.Server): diff --git a/test/test_rpc.py b/test/test_rpc.py index c51797e..a814d68 100644 --- a/test/test_rpc.py +++ b/test/test_rpc.py @@ -1,6 +1,5 @@ import pytest import capnp -import os import socket import test_capability_capnp @@ -30,7 +29,7 @@ def test_simple_rpc(): read, write = socket.socketpair(socket.AF_UNIX) restorer = SimpleRestorer() - server = capnp.TwoPartyServer(write, restorer) + _ = capnp.TwoPartyServer(write, restorer) client = capnp.TwoPartyClient(read) ref = test_capability_capnp.TestSturdyRefObjectId.new_message(tag='testInterface') @@ -47,7 +46,7 @@ def test_simple_rpc_with_options(): read, write = socket.socketpair(socket.AF_UNIX) restorer = SimpleRestorer() - server = capnp.TwoPartyServer(write, restorer) + _ = capnp.TwoPartyServer(write, restorer) # This traversal limit is too low to receive the response in, so we expect # an exception during the call. client = capnp.TwoPartyClient(read, traversal_limit_in_words=1) @@ -58,13 +57,13 @@ def test_simple_rpc_with_options(): remote = cap.foo(i=5) with pytest.raises(capnp.KjException): - response = remote.wait() + _ = remote.wait() def test_simple_rpc_restore_func(): read, write = socket.socketpair(socket.AF_UNIX) - server = capnp.TwoPartyServer(write, restore_func) + _ = capnp.TwoPartyServer(write, restore_func) client = capnp.TwoPartyClient(read) ref = test_capability_capnp.TestSturdyRefObjectId.new_message(tag='testInterface') @@ -86,7 +85,7 @@ def text_restore_func(objectId): def test_ez_rpc(): read, write = socket.socketpair(socket.AF_UNIX) - server = capnp.TwoPartyServer(write, text_restore_func) + _ = capnp.TwoPartyServer(write, text_restore_func) client = capnp.TwoPartyClient(read) cap = client.ez_restore('testInterface') @@ -108,7 +107,7 @@ def test_ez_rpc(): def test_simple_rpc_bootstrap(): read, write = socket.socketpair(socket.AF_UNIX) - server = capnp.TwoPartyServer(write, bootstrap=Server(100)) + _ = capnp.TwoPartyServer(write, bootstrap=Server(100)) client = capnp.TwoPartyClient(read) cap = client.bootstrap() diff --git a/test/test_rpc_calculator.py b/test/test_rpc_calculator.py index ecf73ec..6beea16 100644 --- a/test/test_rpc_calculator.py +++ b/test/test_rpc_calculator.py @@ -1,21 +1,23 @@ -import capnp +import gc import os import socket -import gc import subprocess +import sys # add examples dir to sys.path import time -import sys # add examples dir to sys.path +import capnp + examples_dir = os.path.join(os.path.dirname(__file__), '..', 'examples') sys.path.append(examples_dir) -import calculator_client -import calculator_server + +import calculator_client # noqa: E402 +import calculator_server # noqa: E402 def test_calculator(): read, write = socket.socketpair(socket.AF_UNIX) - server = capnp.TwoPartyServer(write, bootstrap=calculator_server.CalculatorImpl()) + _ = capnp.TwoPartyServer(write, bootstrap=calculator_server.CalculatorImpl()) calculator_client.main(read) @@ -57,7 +59,7 @@ def test_calculator_gc(): evaluate_impl_orig = calculator_server.evaluate_impl calculator_server.evaluate_impl = new_evaluate_impl(evaluate_impl_orig) - server = capnp.TwoPartyServer(write, bootstrap=calculator_server.CalculatorImpl()) + _ = capnp.TwoPartyServer(write, bootstrap=calculator_server.CalculatorImpl()) calculator_client.main(read) calculator_server.evaluate_impl = evaluate_impl_orig diff --git a/test/test_serialization.py b/test/test_serialization.py index a3ff183..1f26d15 100644 --- a/test/test_serialization.py +++ b/test/test_serialization.py @@ -42,7 +42,10 @@ def test_roundtrip_bytes(all_types): msg = all_types.TestAllTypes.from_bytes(message_bytes) test_regression.check_all_types(msg) -@pytest.mark.skipif(platform.python_implementation() == 'PyPy', reason="TODO: Investigate why this works on CPython but fails on PyPy.") +@pytest.mark.skipif( + platform.python_implementation() == 'PyPy', + reason="TODO: Investigate why this works on CPython but fails on PyPy." +) def test_roundtrip_segments(all_types): msg = all_types.TestAllTypes.new_message() test_regression.init_all_types(msg) @@ -79,7 +82,10 @@ def test_roundtrip_bytes_fail(all_types): with pytest.raises(TypeError): all_types.TestAllTypes.from_bytes(42) -@pytest.mark.skipif(platform.python_implementation() == 'PyPy', reason="This works in PyPy 4.0.1 but travisci's version of PyPy has some bug that fails this test.") +@pytest.mark.skipif( + platform.python_implementation() == 'PyPy', + reason="This works in PyPy 4.0.1 but travisci's version of PyPy has some bug that fails this test." +) def test_roundtrip_bytes_packed(all_types): msg = all_types.TestAllTypes.new_message() test_regression.init_all_types(msg) @@ -146,7 +152,10 @@ def test_roundtrip_bytes_multiple_packed(all_types): i += 1 assert i == 3 -@pytest.mark.skipif(platform.python_implementation() == 'PyPy', reason="This works on my local PyPy v2.5.0, but is for some reason broken on TravisCI. Skip for now.") +@pytest.mark.skipif( + platform.python_implementation() == 'PyPy', + reason="This works on my local PyPy v2.5.0, but is for some reason broken on TravisCI. Skip for now." +) def test_roundtrip_dict(all_types): msg = all_types.TestAllTypes.new_message() test_regression.init_all_types(msg) diff --git a/test/test_struct.py b/test/test_struct.py index 953a8be..7b23b5a 100644 --- a/test/test_struct.py +++ b/test/test_struct.py @@ -77,7 +77,10 @@ def test_which_reader(addressbook): addresses.which -@pytest.mark.skipif(capnp.version.LIBCAPNP_VERSION < 5000, reason="Using ints as enums requires v0.5.0+ of the C++ capnp library") +@pytest.mark.skipif( + capnp.version.LIBCAPNP_VERSION < 5000, + reason="Using ints as enums requires v0.5.0+ of the C++ capnp library" +) def test_enum(addressbook): addresses = addressbook.AddressBook.new_message() people = addresses.init('people', 2) @@ -188,13 +191,8 @@ def test_set_dict_union(addressbook): assert person.employment.employer.name == 'foo' -try: - basestring # attempt to evaluate basestring - def isstr(s): - return isinstance(s, basestring) -except NameError: - def isstr(s): - return isinstance(s, str) +def isstr(s): + return isinstance(s, str) def test_to_dict_enum(addressbook): @@ -227,7 +225,12 @@ def test_to_dict_verbose(addressbook): def test_to_dict_ordered(addressbook): - person = addressbook.Person.new_message(**{'name': 'Alice', 'phones': [{'type': 'mobile', 'number': '555-1212'}], 'id': 123, 'employment': {'school': 'MIT'}, 'email': 'alice@example.com'}) + person = addressbook.Person.new_message(**{ + 'name': 'Alice', + 'phones': [{'type': 'mobile', 'number': '555-1212'}], + 'id': 123, + 'employment': {'school': 'MIT'}, 'email': 'alice@example.com' + }) if sys.version_info >= (2, 7): assert list(person.to_dict(ordered=True).keys()) == ['id', 'name', 'email', 'phones', 'employment'] @@ -246,4 +249,4 @@ def test_nested_list(addressbook): struct.list[1][0] = 2 struct.list[1][1] = 3 - assert struct.to_dict()["list"] == [[1], [2,3]] + assert struct.to_dict()["list"] == [[1], [2, 3]] diff --git a/test/test_threads.py b/test/test_threads.py index 8604ecf..218557b 100644 --- a/test/test_threads.py +++ b/test/test_threads.py @@ -1,20 +1,38 @@ -import capnp -import pytest -import test_capability_capnp +''' +thread test +''' + +import platform import socket import threading -import platform -@pytest.mark.skipif(platform.python_implementation() == 'PyPy', reason="pycapnp's GIL handling isn't working properly at the moment for PyPy") +import pytest + +import capnp +import test_capability_capnp + +@pytest.mark.skipif( + platform.python_implementation() == 'PyPy', + reason="pycapnp's GIL handling isn't working properly at the moment for PyPy" +) def test_making_event_loop(): + ''' + Event loop test + ''' capnp.remove_event_loop(True) capnp.create_event_loop() capnp.remove_event_loop() capnp.create_event_loop() -@pytest.mark.skipif(platform.python_implementation() == 'PyPy', reason="pycapnp's GIL handling isn't working properly at the moment for PyPy") +@pytest.mark.skipif( + platform.python_implementation() == 'PyPy', + reason="pycapnp's GIL handling isn't working properly at the moment for PyPy" +) def test_making_threaded_event_loop(): + ''' + Threaded event loop test + ''' capnp.remove_event_loop(True) capnp.create_event_loop(True) @@ -23,23 +41,40 @@ def test_making_threaded_event_loop(): class Server(test_capability_capnp.TestInterface.Server): - + ''' + Server + ''' def __init__(self, val=1): self.val = val def foo(self, i, j, **kwargs): + ''' + foo + ''' return str(i * 5 + self.val) class SimpleRestorer(test_capability_capnp.TestSturdyRefObjectId.Restorer): + ''' + SimpleRestorer + ''' def restore(self, ref_id): + ''' + Restore + ''' assert ref_id.tag == 'testInterface' return Server(100) -@pytest.mark.skipif(platform.python_implementation() == 'PyPy', reason="pycapnp's GIL handling isn't working properly at the moment for PyPy") +@pytest.mark.skipif( + platform.python_implementation() == 'PyPy', + reason="pycapnp's GIL handling isn't working properly at the moment for PyPy" +) def test_using_threads(): + ''' + Thread test + ''' capnp.remove_event_loop(True) capnp.create_event_loop(True) @@ -47,7 +82,7 @@ def test_using_threads(): def run_server(): restorer = SimpleRestorer() - server = capnp.TwoPartyServer(write, restorer) + _ = capnp.TwoPartyServer(write, restorer) capnp.wait_forever() server_thread = threading.Thread(target=run_server)