diff --git a/doc/conf.py b/doc/conf.py index a7a5caa603a67098fbf79fa59ada6a122c1c90c1..d8627bf2d9e13c4f50fb6c9b6aa3bcdb35617fa5 100644 --- a/doc/conf.py +++ b/doc/conf.py @@ -3,6 +3,7 @@ import os import time + from importlib.metadata import version as package_version import sphinx_rtd_theme diff --git a/doc/data/second_config.py b/doc/data/second_config.py index 21abd01b385338741042deb0c5a554810c2fdde8..c908703b9f352b20f38d60353257f8ca4513f1a3 100644 --- a/doc/data/second_config.py +++ b/doc/data/second_config.py @@ -1,3 +1,3 @@ # the b variable from the last config file is available here -c = b + 1 -b = b + 3 +c = b + 1 # noqa: F821 +b = b + 3 # noqa: F821 diff --git a/doc/example_alias.py b/doc/example_alias.py index 2ee06ca82c0b72cb363f1019358e6b74f9e94410..4c780608bc2140e82c614866d6521de6f5e2955b 100644 --- a/doc/example_alias.py +++ b/doc/example_alias.py @@ -9,17 +9,21 @@ import click import expose.click + @click.group(cls=expose.click.AliasedGroup) def main(): pass + @main.command() def push(): click.echo("push was called") + @main.command() def pop(): click.echo("pop was called") + if __name__ == "__main__": main() diff --git a/doc/example_cli.py b/doc/example_cli.py index a7324b1784754857e75b8fd2923b6147f1b361dd..2f40daeb622f8ab2ba26e0ac55ec96aba8d1f723 100644 --- a/doc/example_cli.py +++ b/doc/example_cli.py @@ -7,14 +7,12 @@ import click -from expose.click import ( - verbosity_option, - ConfigCommand, - ResourceOption, -) +from expose.click import ConfigCommand, ResourceOption, verbosity_option from expose.logging import setup + logger = setup(__name__.split(".", 1)[0]) + @click.command( context_settings={ "show_default": True, @@ -42,8 +40,7 @@ Examples: @click.version_option(package_name="expose") @click.pass_context def main(ctx, **_): - """Tests our Click interfaces - """ + """Tests our Click interfaces""" # Add imports needed for your code here, and avoid spending time loading! @@ -54,5 +51,6 @@ def main(ctx, **_): continue click.echo(f"{k}: {v}") + if __name__ == "__main__": main() diff --git a/doc/example_defaults.py b/doc/example_defaults.py index 2ba0ef0f1baeeef41f4f7a80a342350b271908a6..86750d16d7a76819380e0241071be53ab5bc3e1f 100644 --- a/doc/example_defaults.py +++ b/doc/example_defaults.py @@ -1,14 +1,16 @@ -from expose.rc import UserDefaults from expose.click import user_defaults_group from expose.logging import setup +from expose.rc import UserDefaults logger = setup(__name__.split(".", 1)[0]) rc = UserDefaults(".myapprc", logger=logger) + @user_defaults_group(logger=logger, config=rc) def main(**kwargs): - '''Use this command to affect the global user defaults.''' + """Use this command to affect the global user defaults.""" pass + if __name__ == "__main__": main() diff --git a/doc/example_logging.py b/doc/example_logging.py index fdc98667d16217029296502f8165e66d0c339d19..c03d97a109767afe06a117330cb22428be94d996 100644 --- a/doc/example_logging.py +++ b/doc/example_logging.py @@ -1,5 +1,7 @@ import logging + from expose.logging import setup + logger = setup(__name__.split(".", 1)[0], format="%(levelname)s: %(message)s") logger.setLevel(logging.INFO) logger.info("test message") diff --git a/expose/click.py b/expose/click.py index cf9e62ce1010041915a0df737d3326747c8a7ddf..fe87582470717321286f077659d3900c58540bb9 100644 --- a/expose/click.py +++ b/expose/click.py @@ -1,18 +1,15 @@ """Helpers to build command-line interfaces (CLI) via :py:mod:`click`.""" -import time +import functools import logging +import time import typing -import traceback -import functools -import configparser import click + from click.core import ParameterSource -from .config import load -from .config import mod_to_context -from .config import resource_keys +from .config import load, mod_to_context, resource_keys from .rc import UserDefaults logger = logging.getLogger(__name__) @@ -237,7 +234,7 @@ will override the values of configuration files. You can run this command with begin, dflt = "Required parameter", "" else: begin, dflt = ( - f"Optional parameter", + "Optional parameter", f" [default: {param.default}]", ) @@ -541,7 +538,6 @@ def user_defaults_group( def group_decorator( func: typing.Callable[..., typing.Any] ) -> typing.Callable[..., typing.Any]: - @click.group(cls=AliasedGroup) @verbosity_option(logger=logger) @functools.wraps(func) diff --git a/expose/config.py b/expose/config.py index 714b2aed8242eea0c2c2d2d600a99b057a5dc039..2389a865a6f6668f04e0baa9205fab76180404a2 100644 --- a/expose/config.py +++ b/expose/config.py @@ -3,13 +3,14 @@ """Functionality to implement python-based config file parsing and loading. """ -import types -import pkgutil -import typing -import os.path import logging +import os.path import pathlib -from importlib.metadata import entry_points, EntryPoint +import pkgutil +import types +import typing + +from importlib.metadata import EntryPoint, entry_points logger = logging.getLogger(__name__) diff --git a/expose/logging.py b/expose/logging.py index 7137efd0ace19f1567aea99dcad85ab614314e4e..9b1bfcad209c901dd7c2e2ec0c55bfba99d8cc36 100644 --- a/expose/logging.py +++ b/expose/logging.py @@ -1,8 +1,9 @@ """:py:class:`logging.Logger` setup and stream separation""" +import logging import sys import typing -import logging + # debug and info messages are written to sys.stdout class _InfoFilter(logging.Filter): diff --git a/expose/rc.py b/expose/rc.py index b9128226d53561c3b7e47287765946b2daac4661..6797e5ad962b99cfda066a0b340c6c11480e3b0a 100644 --- a/expose/rc.py +++ b/expose/rc.py @@ -2,12 +2,12 @@ """Implements a global configuration system setup and readout.""" -import os +import configparser import io +import logging +import os import pathlib import typing -import logging -import configparser class UserDefaults(configparser.ConfigParser): @@ -76,16 +76,18 @@ class UserDefaults(configparser.ConfigParser): """Reads configuraiton file""" if self.path.exists(): - self.logger.debug(f"User configuration file exists, reading contents...") + self.logger.debug( + "User configuration file exists, reading contents..." + ) self.read_file(self.path.open("rt")) else: - self.logger.debug(f"Initializing empty user configuration...") + self.logger.debug("Initializing empty user configuration...") def write(self) -> None: """Stores any modifications done on the user configuration""" if self.path.exists(): - backup = pathlib.Path(str(self.path)+ "~") + backup = pathlib.Path(str(self.path) + "~") self.logger.debug(f"Backing-up {str(self.path)} -> {str(backup)}") self.path.rename(backup) diff --git a/setup.py b/setup.py index 34f94fa96b133696abd6d9d56e31d6d60355bca1..b18151c27304e692bca86ced38073353341ea1b9 100644 --- a/setup.py +++ b/setup.py @@ -1,19 +1,19 @@ -from setuptools import setup, find_packages +from setuptools import find_packages, setup setup( name="expose", version=open("version.txt").read().rstrip(), description="Configuration Support for Python Packages and CLIs", - url='http://gitlab.idiap.ch/bob/expose', + url="http://gitlab.idiap.ch/bob/expose", license="BSD", - author='Andre Anjos', - author_email='andre.anjos@idiap.ch', - long_description=open('README.rst').read(), + author="Andre Anjos", + author_email="andre.anjos@idiap.ch", + long_description=open("README.rst").read(), packages=find_packages(), include_package_data=True, zip_safe=True, - install_requires=['click >= 8'], - entry_points = { + install_requires=["click >= 8"], + entry_points={ # these are just test entry-points (not distributed) "expose.test.config": [ "first = tests.data.basic_config", @@ -26,15 +26,15 @@ setup( "complex-var = tests.data.complex:cplx", "verbose-config = tests.data.verbose_config", "error-config = tests.data.doesnt_exist", - ] - }, + ] + }, classifiers=[ - 'Framework :: Bob', - 'Development Status :: 4 - Beta', - 'Intended Audience :: Developers', - 'License :: OSI Approved :: BSD License', - 'Natural Language :: English', - 'Programming Language :: Python :: 3', - 'Topic :: Software Development :: Libraries :: Python Modules', + "Framework :: Bob", + "Development Status :: 4 - Beta", + "Intended Audience :: Developers", + "License :: OSI Approved :: BSD License", + "Natural Language :: English", + "Programming Language :: Python :: 3", + "Topic :: Software Development :: Libraries :: Python Modules", ], ) diff --git a/tests/conftest.py b/tests/conftest.py index 57a0968948217f306696127896d4eed605909e4d..72e993e08032b387d6eb766b9e00fc1ff2b290de 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -1,12 +1,12 @@ +import contextlib import io import pathlib import warnings -import contextlib import pytest -from pytest import fixture from click.testing import CliRunner +from pytest import fixture """ @@ -43,7 +43,6 @@ def pytest_addoption(parser) -> None: class MyCliRunner(CliRunner): - def __init__(self, *args, in_pdb=False, **kwargs) -> None: self._in_pdb = in_pdb super().__init__(*args, **kwargs) diff --git a/tests/data/second_config.py b/tests/data/second_config.py index 21abd01b385338741042deb0c5a554810c2fdde8..c908703b9f352b20f38d60353257f8ca4513f1a3 100644 --- a/tests/data/second_config.py +++ b/tests/data/second_config.py @@ -1,3 +1,3 @@ # the b variable from the last config file is available here -c = b + 1 -b = b + 3 +c = b + 1 # noqa: F821 +b = b + 3 # noqa: F821 diff --git a/tests/test_click.py b/tests/test_click.py index a445847426c51f60f0f206d039e85ef468c1398f..5d23af16c96b3c9575ef90833623d3c1e43e73a5 100644 --- a/tests/test_click.py +++ b/tests/test_click.py @@ -1,15 +1,15 @@ -import time -import logging import difflib +import logging import click + from click.testing import CliRunner from expose.click import ( - verbosity_option, + AliasedGroup, ConfigCommand, ResourceOption, - AliasedGroup, + verbosity_option, ) @@ -109,9 +109,7 @@ def test_commands_with_config_3(): def _assert_config_dump(output, ref, ref_date): - today = time.strftime("%d/%m/%Y") - # uncomment below to re-write tests - # open(ref, 'wt').write(open('TEST_CONF').read()) + with output.open("rt") as f, open(ref, "rt") as f2: diff = difflib.ndiff(f.readlines(), f2.readlines()) important_diffs = [k for k in diff if k.startswith(("+", "-"))] diff --git a/tests/test_config.py b/tests/test_config.py index 370b23a3cdc77859b842e6af3aaf7d7e1f3cd061..e0cd13ae4fadbd26e5342937ecaeb003741cff2e 100644 --- a/tests/test_config.py +++ b/tests/test_config.py @@ -1,5 +1,3 @@ -import os - import pytest from expose.config import load, mod_to_context @@ -66,7 +64,7 @@ def test_config_with_entry_point(): def test_config_with_entry_point_file_missing(): with pytest.raises(ValueError): - c = load(["error-config"], entry_point_group="expose.test.config") + load(["error-config"], entry_point_group="expose.test.config") def test_config_with_mixture(datadir): @@ -83,7 +81,7 @@ def test_config_with_mixture(datadir): def test_config_not_found(datadir): with pytest.raises(ValueError): - c = load([datadir / "basic_config.pz"]) + load([datadir / "basic_config.pz"]) def test_config_load_attribute(): diff --git a/tests/test_logging.py b/tests/test_logging.py index de18191fca4c45948442606de44262f72b852ac2..576efbab7553fa23b595aa2af013510c9f811342 100644 --- a/tests/test_logging.py +++ b/tests/test_logging.py @@ -2,9 +2,11 @@ import io import logging import click + from click.testing import CliRunner import expose.logging + from expose.click import verbosity_option @@ -179,7 +181,7 @@ def test_logger_click_3x_verbose(): logger.error("error message") runner = CliRunner() - result = runner.invoke(cli, 3*["--verbose"]) + result = runner.invoke(cli, 3 * ["--verbose"]) assert result.exit_code == 0 lo.seek(0) @@ -210,7 +212,7 @@ def test_logger_click_3x_verb(): logger.error("error message") runner = CliRunner() - result = runner.invoke(cli, 3*["--verb"]) + result = runner.invoke(cli, 3 * ["--verb"]) assert result.exit_code == 0 lo.seek(0) diff --git a/tests/test_rc.py b/tests/test_rc.py index dd45f171deb4490937babfb786ea4993668f9bce..f45ba677b6ccc74e6e47cf1d2928eac961e2d01f 100644 --- a/tests/test_rc.py +++ b/tests/test_rc.py @@ -1,12 +1,12 @@ -import os -import shutil import filecmp import logging +import os +import shutil from click.testing import CliRunner -from expose.rc import UserDefaults from expose.click import user_defaults_group +from expose.rc import UserDefaults def _check_userdefaults_ex1_contents(rc): @@ -21,14 +21,14 @@ def _check_userdefaults_ex1_contents(rc): assert rc["foo"]["blue_red"] == "blue,red" assert rc.getint("foo", "integer") == 42 assert rc["foo"]["only_blue"] == "blue" - assert rc.getboolean("foo", "boolean") == True + assert rc.getboolean("foo", "boolean") is True assert "bar" in rc assert len(rc["bar"]) == 4 # includes default section entries assert rc["bar"]["blue_yellow"] == "blue,yellow" assert rc.getfloat("bar", "float") == 3.14 assert rc["bar"]["only_blue"] == "blue" - assert rc.getboolean("bar", "boolean") == False + assert rc.getboolean("bar", "boolean") is False def test_rc_basic_loading(datadir):