diff --git a/.github/workflows/build-and-test.yml b/.github/workflows/build-and-test.yml index 599b0943..f0f0626d 100644 --- a/.github/workflows/build-and-test.yml +++ b/.github/workflows/build-and-test.yml @@ -18,20 +18,20 @@ jobs: build_type: ['Release', 'Debug'] steps: - uses: actions/checkout@v2 - + - name: create build environment run: cmake -E make_directory ${{ runner.workspace }}/_build - + - name: configure cmake shell: bash working-directory: ${{ runner.workspace }}/_build run: cmake -DBENCHMARK_DOWNLOAD_DEPENDENCIES=ON $GITHUB_WORKSPACE -DCMAKE_BUILD_TYPE=${{ matrix.build_type }} - + - name: build shell: bash working-directory: ${{ runner.workspace }}/_build run: cmake --build . --config ${{ matrix.build_type }} - + - name: test shell: bash working-directory: ${{ runner.workspace }}/_build diff --git a/.github/workflows/pylint.yml b/.github/workflows/pylint.yml new file mode 100644 index 00000000..c8696749 --- /dev/null +++ b/.github/workflows/pylint.yml @@ -0,0 +1,26 @@ +name: pylint + +on: + push: + branches: [ master ] + pull_request: + branches: [ master ] + +jobs: + pylint: + + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v2 + - name: Set up Python 3.8 + uses: actions/setup-python@v1 + with: + python-version: 3.8 + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install pylint pylint-exit conan + - name: Run pylint + run: | + pylint `find . -name '*.py'|xargs` || pylint-exit $? diff --git a/bindings/python/google_benchmark/__init__.py b/bindings/python/google_benchmark/__init__.py index c3a93bfc..44531f99 100644 --- a/bindings/python/google_benchmark/__init__.py +++ b/bindings/python/google_benchmark/__init__.py @@ -39,27 +39,27 @@ __version__ = "0.1.0" def register(f=None, *, name=None): - if f is None: - return lambda f: register(f, name=name) - if name is None: - name = f.__name__ - _benchmark.RegisterBenchmark(name, f) - return f + if f is None: + return lambda f: register(f, name=name) + if name is None: + name = f.__name__ + _benchmark.RegisterBenchmark(name, f) + return f def _flags_parser(argv): - argv = _benchmark.Initialize(argv) - return app.parse_flags_with_usage(argv) + argv = _benchmark.Initialize(argv) + return app.parse_flags_with_usage(argv) def _run_benchmarks(argv): - if len(argv) > 1: - raise app.UsageError('Too many command-line arguments.') - return _benchmark.RunSpecifiedBenchmarks() + if len(argv) > 1: + raise app.UsageError('Too many command-line arguments.') + return _benchmark.RunSpecifiedBenchmarks() def main(argv=None): - return app.run(_run_benchmarks, argv=argv, flags_parser=_flags_parser) + return app.run(_run_benchmarks, argv=argv, flags_parser=_flags_parser) # Methods for use with custom main function. diff --git a/bindings/python/google_benchmark/example.py b/bindings/python/google_benchmark/example.py index e9684624..0dead754 100644 --- a/bindings/python/google_benchmark/example.py +++ b/bindings/python/google_benchmark/example.py @@ -25,24 +25,24 @@ import google_benchmark as benchmark @benchmark.register def empty(state): - while state: - pass + while state: + pass @benchmark.register def sum_million(state): - while state: - sum(range(1_000_000)) + while state: + sum(range(1_000_000)) @benchmark.register def skipped(state): - if True: # Test some predicate here. - state.skip_with_error('some error') - return # NOTE: You must explicitly return, or benchmark will continue. + if True: # Test some predicate here. + state.skip_with_error('some error') + return # NOTE: You must explicitly return, or benchmark will continue. - ... # Benchmark code would be here. + # Benchmark code would be here. if __name__ == '__main__': - benchmark.main() + benchmark.main() diff --git a/setup.py b/setup.py index a2b0b917..800a8794 100644 --- a/setup.py +++ b/setup.py @@ -9,89 +9,91 @@ import setuptools from setuptools.command import build_ext -here = os.path.dirname(os.path.abspath(__file__)) +HERE = os.path.dirname(os.path.abspath(__file__)) IS_WINDOWS = sys.platform.startswith('win') def _get_version(): - """Parse the version string from __init__.py.""" - with open(os.path.join(here, 'bindings', 'python', 'google_benchmark', '__init__.py')) as f: - try: - version_line = next( - line for line in f if line.startswith('__version__')) - except StopIteration: - raise ValueError('__version__ not defined in __init__.py') - else: - ns = {} - exec(version_line, ns) # pylint: disable=exec-used - return ns['__version__'] + """Parse the version string from __init__.py.""" + with open(os.path.join( + HERE, 'bindings', 'python', 'google_benchmark', '__init__.py')) as init_file: + try: + version_line = next( + line for line in init_file if line.startswith('__version__')) + except StopIteration: + raise ValueError('__version__ not defined in __init__.py') + else: + namespace = {} + exec(version_line, namespace) # pylint: disable=exec-used + return namespace['__version__'] def _parse_requirements(path): - with open(os.path.join(here, path)) as f: - return [ - line.rstrip() for line in f - if not (line.isspace() or line.startswith('#')) - ] + with open(os.path.join(HERE, path)) as requirements: + return [ + line.rstrip() for line in requirements + if not (line.isspace() or line.startswith('#')) + ] class BazelExtension(setuptools.Extension): - """A C/C++ extension that is defined as a Bazel BUILD target.""" + """A C/C++ extension that is defined as a Bazel BUILD target.""" - def __init__(self, name, bazel_target): - self.bazel_target = bazel_target - self.relpath, self.target_name = ( - posixpath.relpath(bazel_target, '//').split(':')) - setuptools.Extension.__init__(self, name, sources=[]) + def __init__(self, name, bazel_target): + self.bazel_target = bazel_target + self.relpath, self.target_name = ( + posixpath.relpath(bazel_target, '//').split(':')) + setuptools.Extension.__init__(self, name, sources=[]) class BuildBazelExtension(build_ext.build_ext): - """A command that runs Bazel to build a C/C++ extension.""" + """A command that runs Bazel to build a C/C++ extension.""" - def run(self): - for ext in self.extensions: - self.bazel_build(ext) - build_ext.build_ext.run(self) + def run(self): + for ext in self.extensions: + self.bazel_build(ext) + build_ext.build_ext.run(self) - def bazel_build(self, ext): - with open('WORKSPACE', 'r') as f: - workspace_contents = f.read() + def bazel_build(self, ext): + """Runs the bazel build to create the package.""" + with open('WORKSPACE', 'r') as workspace: + workspace_contents = workspace.read() - with open('WORKSPACE', 'w') as f: - f.write(re.sub( - r'(?<=path = ").*(?=", # May be overwritten by setup\.py\.)', - sysconfig.get_python_inc().replace(os.path.sep, posixpath.sep), - workspace_contents)) + with open('WORKSPACE', 'w') as workspace: + workspace.write(re.sub( + r'(?<=path = ").*(?=", # May be overwritten by setup\.py\.)', + sysconfig.get_python_inc().replace(os.path.sep, posixpath.sep), + workspace_contents)) - if not os.path.exists(self.build_temp): - os.makedirs(self.build_temp) + if not os.path.exists(self.build_temp): + os.makedirs(self.build_temp) - bazel_argv = [ - 'bazel', - 'build', - ext.bazel_target, - '--symlink_prefix=' + os.path.join(self.build_temp, 'bazel-'), - '--compilation_mode=' + ('dbg' if self.debug else 'opt'), - ] + bazel_argv = [ + 'bazel', + 'build', + ext.bazel_target, + '--symlink_prefix=' + os.path.join(self.build_temp, 'bazel-'), + '--compilation_mode=' + ('dbg' if self.debug else 'opt'), + ] - if IS_WINDOWS: - # Link with python*.lib. - for library_dir in self.library_dirs: - bazel_argv.append('--linkopt=/LIBPATH:' + library_dir) + if IS_WINDOWS: + # Link with python*.lib. + for library_dir in self.library_dirs: + bazel_argv.append('--linkopt=/LIBPATH:' + library_dir) - self.spawn(bazel_argv) + self.spawn(bazel_argv) - shared_lib_suffix = '.dll' if IS_WINDOWS else '.so' - ext_bazel_bin_path = os.path.join( - self.build_temp, 'bazel-bin', - ext.relpath, ext.target_name + shared_lib_suffix) - ext_dest_path = self.get_ext_fullpath(ext.name) - ext_dest_dir = os.path.dirname(ext_dest_path) - if not os.path.exists(ext_dest_dir): - os.makedirs(ext_dest_dir) - shutil.copyfile(ext_bazel_bin_path, ext_dest_path) + shared_lib_suffix = '.dll' if IS_WINDOWS else '.so' + ext_bazel_bin_path = os.path.join( + self.build_temp, 'bazel-bin', + ext.relpath, ext.target_name + shared_lib_suffix) + ext_dest_path = self.get_ext_fullpath(ext.name) + ext_dest_dir = os.path.dirname(ext_dest_path) + if not os.path.exists(ext_dest_dir): + os.makedirs(ext_dest_dir) + shutil.copyfile(ext_bazel_bin_path, ext_dest_path) setuptools.setup( @@ -106,7 +108,8 @@ setuptools.setup( packages=setuptools.find_packages('bindings/python'), install_requires=_parse_requirements('bindings/python/requirements.txt'), cmdclass=dict(build_ext=BuildBazelExtension), - ext_modules=[BazelExtension('google_benchmark._benchmark', '//bindings/python/google_benchmark:_benchmark')], + ext_modules=[BazelExtension( + 'google_benchmark._benchmark', '//bindings/python/google_benchmark:_benchmark')], zip_safe=False, # PyPI package information. classifiers=[ diff --git a/tools/gbench/util.py b/tools/gbench/util.py index 1f8e8e2c..661c4bad 100644 --- a/tools/gbench/util.py +++ b/tools/gbench/util.py @@ -158,7 +158,6 @@ def run_or_load_benchmark(filename, benchmark_flags): ftype = check_input_file(filename) if ftype == IT_JSON: return load_benchmark_results(filename) - elif ftype == IT_Executable: + if ftype == IT_Executable: return run_benchmark(filename, benchmark_flags) - else: - assert False # This branch is unreachable + raise ValueError('Unknown file type %s' % ftype)