diff --git a/doc/example_cli.py b/doc/example_cli.py index 4182e1495e9ef977204a90b7debad0afb8437bc3..ec1af4317b13874cdbb1ec7534166c1de99429ac 100644 --- a/doc/example_cli.py +++ b/doc/example_cli.py @@ -44,7 +44,6 @@ Examples: @click.pass_context def main(ctx, **_): """Tests our Click interfaces.""" - # Add imports needed for your code here, and avoid spending time loading! # In this example, we just print the loaded options to demonstrate loading diff --git a/src/exposed/click.py b/src/exposed/click.py index 4af43ad101b315bc56cb22bde83491d8933ad51f..057076536c47df4fe398e0e70ba1a0650c34d158 100644 --- a/src/exposed/click.py +++ b/src/exposed/click.py @@ -25,10 +25,10 @@ from .config import load, mod_to_context, resource_keys from .rc import UserDefaults module_logger = logging.getLogger(__name__) -"""Module logger""" +"""Module logger.""" _COMMON_CONTEXT_SETTINGS = dict(help_option_names=["-h", "--help"]) -"""Common click context settings""" +"""Common click context settings.""" def verbosity_option( @@ -84,7 +84,6 @@ def verbosity_option( def custom_verbosity_option(f): def callback(ctx, param, value): - ctx.meta[name] = value log_level: int = { 0: logging.ERROR, @@ -144,10 +143,10 @@ class ConfigCommand(click.Command): """ config_argument_name: str - """The name of the config argument""" + """The name of the config argument.""" entry_point_group: str - """The name of entry point that will be used to load the config files""" + """The name of entry point that will be used to load the config files.""" def __init__( self, @@ -157,7 +156,6 @@ class ConfigCommand(click.Command): entry_point_group: str | None = None, **kwargs: typing.Any, ) -> None: - self.entry_point_group = entry_point_group configs_argument_name = "CONFIG" @@ -318,8 +316,10 @@ class ResourceOption(click.Option): entry_point_group: str | None """If provided, the strings values to this option are assumed to be entry - points from ``entry_point_group`` that need to be loaded. This may be - different than the wrapping :py:class:`ConfigCommand`.""" + points from ``entry_point_group`` that need to be loaded. + + This may be different than the wrapping :py:class:`ConfigCommand`. + """ string_exceptions: list[str] | None """If provided and ``entry_point_group`` is provided, the code will not @@ -345,7 +345,6 @@ class ResourceOption(click.Option): string_exceptions=None, **kwargs, ) -> None: - # By default, if unspecified, click options are converted to strings. # By using ResourceOption's, however, we allow for complex user types # to be set into options. So, if no specific ``type``, a ``default``, @@ -574,7 +573,6 @@ def user_defaults_group( The KEY may contain dots (``.``) to access values from subsections in the TOML_ document. """ - try: click.echo(config[key]) except KeyError: @@ -591,15 +589,18 @@ def user_defaults_group( def set(key: str, value: str, **_: typing.Any) -> None: """Sets the value for a key on the user-defaults file. - If ``key`` contains dots (``.``), then this sets nested subsection + If ``key`` contains dots (``.``), then this sets nested + subsection variables on the configuration file. Values are parsed and translated following the rules of TOML_. .. warning:: - This command will override the current configuration file and my - erase any user comments added by hand. To avoid this, simply - edit your configuration file by hand. + This command will override the current configuration file + and my + erase any user comments added by hand. To avoid this, + simply + edit your configuration file by hand. """ try: tmp = tomli.loads(f"v = {value}") @@ -627,15 +628,19 @@ def user_defaults_group( def rm(key: str, **_: typing.Any) -> None: """Removes the given key from the configuration file. - This command will remove the KEY from the configuration file. If - the input key corresponds to a section in the configuration file, + This command will remove the KEY from the configuration + file. If + the input key corresponds to a section in the configuration + file, then the whole configuration section will be removed. .. warning:: - This command will override the current configuration file and my - erase any user comments added by hand. To avoid this, simply - edit your configuration file by hand. + This command will override the current configuration file + and my + erase any user comments added by hand. To avoid this, + simply + edit your configuration file by hand. """ try: del config[key] @@ -705,7 +710,6 @@ def config_group( @verbosity_option(logger=logger) def list(ctx, **_: typing.Any): """Lists installed configuration resources.""" - from .config import _retrieve_entry_points entry_points: dict[str, EntryPoint] = { @@ -737,7 +741,6 @@ def config_group( entry_points_by_module[k][name] = ep for config_type in sorted(entry_points_by_module): - # calculates the longest config name so we offset the printing longest_name_length = max( len(k) for k in entry_points_by_module[config_type].keys() @@ -805,7 +808,6 @@ def config_group( @verbosity_option(logger=logger) def describe(ctx, name, **_: typing.Any): """Describes a specific configuration resource.""" - from .config import _retrieve_entry_points entry_points: dict[str, EntryPoint] = { diff --git a/src/exposed/config.py b/src/exposed/config.py index ec8cdb7f59e53cfc68171de9d7389e0b97258417..8dcabc16c703e53771c3a85ba4081f809d7f9b3c 100644 --- a/src/exposed/config.py +++ b/src/exposed/config.py @@ -21,8 +21,7 @@ logger = logging.getLogger(__name__) _LOADED_CONFIGS = [] """Small gambiarra (https://www.urbandictionary.com/define.php?term=Gambiarra) -to avoid the garbage collector to collect some already imported modules. -""" +to avoid the garbage collector to collect some already imported modules.""" def _load_context(path: str, mod: types.ModuleType) -> types.ModuleType: @@ -54,7 +53,6 @@ def _load_context(path: str, mod: types.ModuleType) -> types.ModuleType: A python module with the fully resolved context """ - # executes the module code on the context of previously imported modules with open(path, "rb") as f: exec(compile(f.read(), path, "exec"), mod.__dict__) @@ -79,7 +77,6 @@ def _get_module_filename(module_name: str) -> str | None: The path that corresponds to file implementing the provided module name """ - try: loader = pkgutil.get_loader(module_name) if isinstance(loader, FileLoader): @@ -92,7 +89,6 @@ def _get_module_filename(module_name: str) -> str | None: def _object_name( path: str | pathlib.Path, common_name: str | None ) -> tuple[str, str | None]: - if isinstance(path, pathlib.Path): path = str(path) @@ -103,16 +99,19 @@ def _object_name( def _retrieve_entry_points(group: str) -> typing.Iterable[EntryPoint]: """Wraps various entry-point retrieval mechanisms. - For Python 3.9 and 3.10, :py:func:`importlib.metadata.entry_points()` - returns a dictionary keyed by entry-point group names. From Python 3.10 - onwards, one may pass the ``group`` keyword to that function to enable - pre-filtering, or use the ``select()`` method on the returned value, which + For Python 3.9 and 3.10, + :py:func:`importlib.metadata.entry_points()` + returns a dictionary keyed by entry-point group names. From Python + 3.10 + onwards, one may pass the ``group`` keyword to that function to + enable + pre-filtering, or use the ``select()`` method on the returned value, + which is no longer a dictionary. For anything before Python 3.8, you must use the backported library ``importlib_metadata``. """ - if sys.version_info[:2] < (3, 10): all_entry_points = entry_points() return all_entry_points.get(group, []) # Python 3.9 @@ -177,7 +176,6 @@ def _resolve_entry_point_or_modules( object_names = [] for path in paths: - module_name = ( "user_config" # fixed module name for files with full paths ) diff --git a/src/exposed/rc.py b/src/exposed/rc.py index 09163086f5cdd5bdcac7687985b01b0d8d10f542..3a93898cb755e1d613dd75f61d21390e438d4a3f 100644 --- a/src/exposed/rc.py +++ b/src/exposed/rc.py @@ -60,7 +60,6 @@ class UserDefaults(collections.abc.MutableMapping): path: str | pathlib.Path, logger: logging.Logger | None = None, ) -> None: - self.logger = logger or logging.getLogger(__name__) self.path = pathlib.Path(path).expanduser() @@ -74,7 +73,6 @@ class UserDefaults(collections.abc.MutableMapping): def read(self) -> None: """Reads configuration file, replaces any internal values.""" - if self.path.exists(): self.logger.debug( "User configuration file exists, reading contents..." @@ -108,7 +106,6 @@ class UserDefaults(collections.abc.MutableMapping): def write(self) -> None: """Stores any modifications done on the user configuration.""" - if self.path.exists(): backup = pathlib.Path(str(self.path) + "~") self.logger.debug(f"Backing-up {str(self.path)} -> {str(backup)}") @@ -125,7 +122,6 @@ class UserDefaults(collections.abc.MutableMapping): return t.getvalue().decode(encoding="utf-8") def __getitem__(self, k: str) -> typing.Any: - if k in self.data: return self.data[k] diff --git a/tests/conftest.py b/tests/conftest.py index b38c83dcb0dda21f65bfcd1df743fe303349c4f3..91064ebbb65540aec9bf9c6ab6d9d2042109b4fa 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -78,7 +78,6 @@ class MyCliRunner(CliRunner): @pytest.fixture def cli_runner(request) -> MyCliRunner: """A wrapper round Click's test CliRunner to improve usefulness.""" - return MyCliRunner( # workaround Click's environment isolation so debugging works. in_pdb=request.config.getoption("--pdb-trace") @@ -88,5 +87,4 @@ def cli_runner(request) -> MyCliRunner: @fixture def datadir(request) -> pathlib.Path: """Returns the directory in which the test is sitting.""" - return pathlib.Path(request.module.__file__).parents[0] / "data"