Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package python-cloup for openSUSE:Factory checked in at 2023-05-15 16:54:38 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/python-cloup (Old) and /work/SRC/openSUSE:Factory/.python-cloup.new.1533 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-cloup" Mon May 15 16:54:38 2023 rev:2 rq:1087197 version:2.1.0 Changes: -------- --- /work/SRC/openSUSE:Factory/python-cloup/python-cloup.changes 2023-02-01 16:51:53.250023921 +0100 +++ /work/SRC/openSUSE:Factory/.python-cloup.new.1533/python-cloup.changes 2023-05-15 16:54:52.732358018 +0200 @@ -1,0 +2,20 @@ +Mon May 15 10:05:34 UTC 2023 - Jan Engelhardt <[email protected]> + +- Restore summary noun phrase. + +------------------------------------------------------------------- +Mon May 15 08:39:44 UTC 2023 - Eyad Issa <[email protected]> + +- Version 2.1.0 + New features and enhancements + + - Feature: theming support for list of subcommand aliases by @janluke in #152 + - Use the same (Deprecated) label as in Click by @kdeldycke in #153 + - Standardize formats of further error messages by @alexreg in #143 + + Other Changes + + - Fix type of auto_envvar_prefix param to Context.settings method by @alexreg in #147 + - Miscellaneous fixes/improvements to docs by @alexreg in #144 + +------------------------------------------------------------------- Old: ---- cloup-2.0.0.post1.tar.gz New: ---- cloup-2.1.0.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ python-cloup.spec ++++++ --- /var/tmp/diff_new_pack.2jvwfe/_old 2023-05-15 16:54:53.196360578 +0200 +++ /var/tmp/diff_new_pack.2jvwfe/_new 2023-05-15 16:54:53.200360601 +0200 @@ -17,15 +17,15 @@ Name: python-cloup -Version: 2.0.0.post1 +Version: 2.1.0 Release: 0 -Summary: Python packages that adds features to Click +Summary: Option groups, constraints, subcommand sections and help themes for Click License: BSD-3-Clause URL: https://github.com/janLuke/cloup Source: https://files.pythonhosted.org/packages/source/c/cloup/cloup-%{version}.tar.gz -BuildRequires: python-rpm-macros -BuildRequires: %{python_module setuptools} BuildRequires: %{python_module setuptools_scm} +BuildRequires: %{python_module setuptools} +BuildRequires: python-rpm-macros # SECTION test requirements BuildRequires: %{python_module click >= 8.0} BuildRequires: %{python_module pytest} @@ -37,10 +37,11 @@ %python_subpackages %description -Adds features to Click: option groups, constraints, subcommand sections and help themes. +This module adds features to python-click: option groups, +constraints, subcommand sections and help themes. %prep -%setup -q -n cloup-%{version} +%autosetup -n cloup-%{version} %build %python_build ++++++ cloup-2.0.0.post1.tar.gz -> cloup-2.1.0.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cloup-2.0.0.post1/.github/workflows/tests.yaml new/cloup-2.1.0/.github/workflows/tests.yaml --- old/cloup-2.0.0.post1/.github/workflows/tests.yaml 2022-11-13 22:29:13.000000000 +0100 +++ new/cloup-2.1.0/.github/workflows/tests.yaml 2023-05-15 03:54:09.000000000 +0200 @@ -40,12 +40,12 @@ python -m pip install -U pip pip install -U wheel pip install -U setuptools - pip install tox + pip install "tox < 4" - name: Run tox -e ${{ matrix.tox }} run: tox -e ${{ matrix.tox }} - - name: Install and run codecov (py38-click7 only) + - name: Install and run codecov (py38-click8 only) if: ${{ matrix.tox == 'py38-click8' }} run: | pip install codecov diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cloup-2.0.0.post1/PKG-INFO new/cloup-2.1.0/PKG-INFO --- old/cloup-2.0.0.post1/PKG-INFO 2022-11-13 22:29:31.000000000 +0100 +++ new/cloup-2.1.0/PKG-INFO 2023-05-15 03:54:24.000000000 +0200 @@ -1,6 +1,6 @@ Metadata-Version: 2.1 Name: cloup -Version: 2.0.0.post1 +Version: 2.1.0 Summary: Adds features to Click: option groups, constraints, subcommand sections and help themes. Home-page: https://github.com/janLuke/cloup Author: Gianluca Gippetto @@ -32,7 +32,7 @@ .. |coverage| image:: https://codecov.io/github/janLuke/cloup/coverage.svg?branch=master :alt: Coverage Status - :target: https://codecov.io/github/janLuke/cloup?branch=master + :target: https://app.codecov.io/github/janluke/cloup/tree/master .. |python-versions| image:: https://img.shields.io/pypi/pyversions/cloup.svg :alt: Supported versions @@ -70,7 +70,7 @@ - **subcommand aliases** -- **subcommands sections**, i.e. the possibility to organize the subcommands of a +- **subcommands sections**, i.e. the possibility of organizing the subcommands of a ``Group`` in multiple help sections - a **themeable HelpFormatter** that: @@ -86,8 +86,8 @@ type hints and adding the static methods ``Context.settings()`` and ``HelpFormatter.settings()`` for creating dictionaries of settings. -Cloup is **statically type-checked** with MyPy in strict mode and extensively **tested** -against multiple versions of Python with nearly 100% coverage. +Cloup is **statically type-checked** with MyPy in strict mode and extensively **tested** +against multiple versions of Python with nearly 100% coverage. A simple example diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cloup-2.0.0.post1/README.rst new/cloup-2.1.0/README.rst --- old/cloup-2.0.0.post1/README.rst 2022-11-13 22:29:13.000000000 +0100 +++ new/cloup-2.1.0/README.rst 2023-05-15 03:54:09.000000000 +0200 @@ -31,7 +31,7 @@ .. |coverage| image:: https://codecov.io/github/janLuke/cloup/coverage.svg?branch=master :alt: Coverage Status - :target: https://codecov.io/github/janLuke/cloup?branch=master + :target: https://app.codecov.io/github/janluke/cloup/tree/master .. |python-versions| image:: https://img.shields.io/pypi/pyversions/cloup.svg :alt: Supported versions @@ -69,7 +69,7 @@ - **subcommand aliases** -- **subcommands sections**, i.e. the possibility to organize the subcommands of a +- **subcommands sections**, i.e. the possibility of organizing the subcommands of a ``Group`` in multiple help sections - a **themeable HelpFormatter** that: @@ -85,8 +85,8 @@ type hints and adding the static methods ``Context.settings()`` and ``HelpFormatter.settings()`` for creating dictionaries of settings. -Cloup is **statically type-checked** with MyPy in strict mode and extensively **tested** -against multiple versions of Python with nearly 100% coverage. +Cloup is **statically type-checked** with MyPy in strict mode and extensively **tested** +against multiple versions of Python with nearly 100% coverage. A simple example diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cloup-2.0.0.post1/cloup/_commands.py new/cloup-2.1.0/cloup/_commands.py --- old/cloup-2.0.0.post1/cloup/_commands.py 2022-11-13 22:29:13.000000000 +0100 +++ new/cloup-2.1.0/cloup/_commands.py 2023-05-15 03:54:09.000000000 +0200 @@ -24,8 +24,8 @@ """ import inspect from typing import ( - Any, Callable, Dict, Iterable, List, NamedTuple, Optional, Tuple, Type, - TypeVar, Union, cast, overload, + Any, Callable, Dict, Iterable, List, NamedTuple, Optional, Sequence, Tuple, + Type, TypeVar, Union, cast, overload, ) import click @@ -36,6 +36,7 @@ from ._sections import Section, SectionMixin from ._util import click_version_ge_8_1, first_bool, reindent from .constraints import ConstraintMixin +from .styling import DEFAULT_THEME from .typing import AnyCallable ClickCommand = TypeVar('ClickCommand', bound=click.Command) @@ -163,7 +164,7 @@ self.alias2name[alias] = name def resolve_command_name(self, ctx: click.Context, name: str) -> Optional[str]: - """Maps a string supposed to be a command name or an alias to a normalized + """Map a string supposed to be a command name or an alias to a normalized command name. If no match is found, it returns ``None``.""" if ctx.token_normalize_func: name = ctx.token_normalize_func(name) @@ -227,10 +228,26 @@ ) -> str: aliases = getattr(cmd, 'aliases', None) if aliases and self.must_show_subcommand_aliases(ctx): - alias_list = ', '.join(aliases) - return f"{name} ({alias_list})" + assert isinstance(ctx, cloup.Context) + theme = cast( + cloup.HelpTheme, ctx.formatter_settings.get("theme", DEFAULT_THEME) + ) + alias_list = self.format_subcommand_aliases(aliases, theme) + return f"{name} {alias_list}" return name + @staticmethod + def format_subcommand_aliases(aliases: Sequence[str], theme: cloup.HelpTheme) -> str: + secondary_style = theme.alias_secondary + if secondary_style is None or secondary_style == theme.alias: + return theme.alias(f"({', '.join(aliases)})") + else: + return ( + secondary_style("(") + + secondary_style(", ").join(theme.alias(alias) for alias in aliases) + + secondary_style(")") + ) + # MyPy complains because "Signature of "group" incompatible with supertype". # The supertype signature is (*args, **kwargs), which is compatible with # this provided that you pass all arguments (expect "name") as keyword arg. @@ -285,7 +302,7 @@ section: Optional[Section] = None, **kwargs: Any ) -> Callable[[AnyCallable], Union[Command, ClickCommand]]: - """Returns a decorator that creates a new subcommand of this ``Group`` + """Return a decorator that creates a new subcommand of this ``Group`` using the decorated function as callback. It takes the same arguments of :func:`command` plus: @@ -364,7 +381,7 @@ section: Optional[Section] = None, **kwargs: Any ) -> Callable[[AnyCallable], Union["Group", ClickGroup]]: - """Returns a decorator that creates a new subcommand of this ``Group`` + """Return a decorator that creates a new subcommand of this ``Group`` using the decorated function as callback. It takes the same argument of :func:`group` plus: @@ -438,7 +455,7 @@ **kwargs: Any ) -> Callable[[AnyCallable], Union[Command, ClickCommand]]: """ - Returns a decorator that creates a new command using the decorated function + Return a decorator that creates a new command using the decorated function as callback. The only differences with respect to ``click.command`` are: @@ -597,7 +614,7 @@ name: Optional[str] = None, *, cls: Optional[Type[ClickGroup]] = None, **kwargs: Any ) -> Callable[[AnyCallable], click.Group]: """ - Returns a decorator that instantiates a ``Group`` (or a subclass of it) + Return a decorator that instantiates a ``Group`` (or a subclass of it) using the decorated function as callback. .. versionchanged:: 0.10.0 @@ -698,7 +715,7 @@ def _process_unexpected_kwarg_error( error: TypeError, args_info: Dict[str, _ArgInfo], cls: Type[Command] ) -> TypeError: - """Checks if the developer tried to pass a Cloup-specific argument to a ``cls`` + """Check if the developer tried to pass a Cloup-specific argument to a ``cls`` that doesn't support it and if that's the case, augments the error message to provide useful more info about the error.""" import re diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cloup-2.0.0.post1/cloup/_context.py new/cloup-2.1.0/cloup/_context.py --- old/cloup-2.0.0.post1/cloup/_context.py 2022-11-13 22:29:13.000000000 +0100 +++ new/cloup-2.1.0/cloup/_context.py 2023-05-15 03:54:09.000000000 +0200 @@ -129,7 +129,7 @@ @staticmethod def settings( - *, auto_envvar_prefix: Possibly[bool] = MISSING, + *, auto_envvar_prefix: Possibly[str] = MISSING, default_map: Possibly[Dict[str, Any]] = MISSING, terminal_width: Possibly[int] = MISSING, max_content_width: Possibly[int] = MISSING, diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cloup-2.0.0.post1/cloup/_option_groups.py new/cloup-2.1.0/cloup/_option_groups.py --- old/cloup-2.0.0.post1/cloup/_option_groups.py 2022-11-13 22:29:13.000000000 +0100 +++ new/cloup-2.1.0/cloup/_option_groups.py 2023-05-15 03:54:09.000000000 +0200 @@ -91,7 +91,7 @@ # noinspection PyMethodMayBeStatic class OptionGroupMixin: - """Implements support to: + """Implements support for: - option groups - the "Positional arguments" help section; this section is shown only if @@ -174,7 +174,7 @@ return arguments, option_groups, ungrouped_options def get_ungrouped_options(self, ctx: click.Context) -> Sequence[click.Option]: - """Returns options not explicitly assigned to an option group + """Return options not explicitly assigned to an option group (eventually including the ``--help`` option), i.e. options that will be part of the "default option group".""" help_option = ctx.command.get_help_option(ctx) @@ -198,13 +198,13 @@ heading="Positional arguments", definitions=[ self.get_argument_help_record(arg, ctx) for arg in self.arguments - ] + ], ) def make_option_group_help_section( self, group: OptionGroup, ctx: click.Context ) -> HelpSection: - """Returns a HelpSection for an OptionGroup, i.e. an object containing + """Return a ``HelpSection`` for an ``OptionGroup``, i.e. an object containing the title, the optional description and the options' definitions for this option group. @@ -221,7 +221,7 @@ self, ctx: Optional[click.Context], default: bool = True ) -> bool: """ - Returns ``True`` if the help sections of all options groups should have + Return ``True`` if the help sections of all options groups should have their columns aligned. .. versionadded:: 0.8.0 @@ -236,7 +236,7 @@ self, ctx: click.Context, is_the_only_visible_option_group: bool = False ) -> OptionGroup: """ - Returns an ``OptionGroup`` instance for the options not explicitly + Return an ``OptionGroup`` instance for the options not explicitly assigned to an option group, eventually including the ``--help`` option. .. versionadded:: 0.8.0 @@ -304,7 +304,7 @@ # noinspection PyIncorrectDocstring def option_group(title: str, *args: Any, **kwargs: Any) -> Callable[[F], F]: """ - Returns a decorator that annotates a function with an option group. + Return a decorator that annotates a function with an option group. The ``help`` argument is an optional description and can be provided either as keyword argument or as 2nd positional argument after the ``name`` of diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cloup-2.0.0.post1/cloup/_params.py new/cloup-2.1.0/cloup/_params.py --- old/cloup-2.0.0.post1/cloup/_params.py 2022-11-13 22:29:13.000000000 +0100 +++ new/cloup-2.1.0/cloup/_params.py 2023-05-15 03:54:09.000000000 +0200 @@ -3,6 +3,8 @@ class Argument(click.Argument): + """A :class:`click.Argument` with help text.""" + def __init__(self, *args, help=None, **attrs): super().__init__(*args, **attrs) self.help = help @@ -12,7 +14,7 @@ class Option(click.Option): - """A click.Option with an extra field ``group`` of type ``OptionGroup``.""" + """A :class:`click.Option` with an extra field ``group`` of type ``OptionGroup``.""" def __init__(self, *args, group=None, **attrs): super().__init__(*args, **attrs) @@ -34,7 +36,7 @@ def option(*param_decls, cls=None, group=None, **attrs): - """Attaches an ``Option`` to the command. + """Attach an ``Option`` to the command. Refer to :class:`click.Option` and :class:`click.Parameter` for more info about the accepted parameters. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cloup-2.0.0.post1/cloup/_sections.py new/cloup-2.1.0/cloup/_sections.py --- old/cloup-2.0.0.post1/cloup/_sections.py 2022-11-13 22:29:13.000000000 +0100 +++ new/cloup-2.1.0/cloup/_sections.py 2023-05-15 03:54:09.000000000 +0200 @@ -78,8 +78,8 @@ class SectionMixin: """ - Adds to a click.MultiCommand the possibility to organize its subcommands - in multiple help sections. + Adds to a :class:`click.MultiCommand` the possibility of organizing its subcommands + into multiple help sections. Sections can be specified in the following ways: @@ -135,7 +135,7 @@ name: Optional[str] = None, section: Optional[Section] = None ) -> None: - """Adds a command to the section (if specified) or to the default section.""" + """Add a command to the section (if specified) or to the default section.""" name = name or cmd.name if section is None: section = self._default_section @@ -145,8 +145,8 @@ self._section_set.add(section) def add_section(self, section: Section) -> None: - """ Adds a :class:`Section` to this group. You can add the same - section object a single time. """ + """Add a :class:`Section` to this group. You can add the same + section object a single time.""" if section in self._section_set: raise ValueError(f'section "{section}" was already added') self._user_sections.append(section) @@ -157,7 +157,7 @@ self.add_command(cmd, name, fallback_to_default_section=False) def section(self, title: str, *commands: click.Command, **attrs: Any) -> Section: - """ Creates a new :class:`Section`, adds it to this group and returns it.""" + """Create a new :class:`Section`, adds it to this group and returns it.""" section = Section(title, commands, **attrs) self.add_section(section) return section @@ -169,7 +169,7 @@ fallback_to_default_section: bool = True, ) -> None: """ - Adds a subcommand to this ``Group``. + Add a subcommand to this ``Group``. **Implementation note:** ``fallback_to_default_section`` looks not very clean but, even if it's not immediate to see (it wasn't for me), I chose @@ -193,9 +193,12 @@ def list_sections( self, ctx: click.Context, include_default_section: bool = True ) -> List[Section]: - """ Returns the list of all sections in the "correct order". - if ``include_default_section=True`` and the default section is non-empty, - it will be included at the end of the list. """ + """ + Return the list of all sections in the "correct order". + + If ``include_default_section=True`` and the default section is non-empty, + it will be included at the end of the list. + """ section_list = list(self._user_sections) if include_default_section and len(self._default_section) > 0: default_section = Section.sorted( diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cloup-2.0.0.post1/cloup/_util.py new/cloup-2.1.0/cloup/_util.py --- old/cloup-2.0.0.post1/cloup/_util.py 2022-11-13 22:29:13.000000000 +0100 +++ new/cloup-2.1.0/cloup/_util.py 2023-05-15 03:54:09.000000000 +0200 @@ -89,12 +89,13 @@ def coalesce(*values: Optional[T]) -> Optional[T]: - """Returns the first value that is not None (or None if no such value exists).""" + """Return the first value that is not ``None`` + (or ``None`` if no such value exists).""" return next((val for val in values if val is not None), None) def first_bool(*values: Any) -> bool: - """Returns the first bool (or raises StopIteration if no bool is found).""" + """Return the first bool (or raises ``StopIteration`` if no bool is found).""" return next(val for val in values if isinstance(val, bool)) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cloup-2.0.0.post1/cloup/_version.py new/cloup-2.1.0/cloup/_version.py --- old/cloup-2.0.0.post1/cloup/_version.py 2022-11-13 22:29:31.000000000 +0100 +++ new/cloup-2.1.0/cloup/_version.py 2023-05-15 03:54:24.000000000 +0200 @@ -1,5 +1,4 @@ -# coding: utf-8 # file generated by setuptools_scm # don't change, don't track in version control -__version__ = version = '2.0.0.post1' -__version_tuple__ = version_tuple = (2, 0, 0) +__version__ = version = '2.1.0' +__version_tuple__ = version_tuple = (2, 1, 0) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cloup-2.0.0.post1/cloup/constraints/_conditional.py new/cloup-2.1.0/cloup/constraints/_conditional.py --- old/cloup-2.0.0.post1/cloup/constraints/_conditional.py 2022-11-13 22:29:13.000000000 +0100 +++ new/cloup-2.1.0/cloup/constraints/_conditional.py 2023-05-15 03:54:09.000000000 +0200 @@ -1,5 +1,5 @@ """ -This modules contains classes to create conditional constraints. +This modules contains classes for creating conditional constraints. """ from typing import Optional, Sequence, Union @@ -19,31 +19,33 @@ elif isinstance(arg, Sequence): return AllSet(*arg) else: - raise TypeError('`arg` should be a string, a list of strings or a `Predicate`') + raise TypeError("`arg` should be a string, a list of strings or a `Predicate`") class If(Constraint): + """ + Checks one constraint or another depending on the truth value of the condition. + + .. versionadded:: 0.8.0 + you can now pass a sequence of parameter names as condition, which + corresponds to the predicate ``AllSet(*param_names)``. + + :param condition: + can be either an instance of ``Predicate`` or (more often) the name of a + parameter or a list/tuple of parameters that must be all set for the + condition to be true. + :param then: + a constraint checked if the condition is true. + :param else_: + an (optional) constraint checked if the condition is false. + """ + def __init__( - self, condition: Union[str, Sequence[str], Predicate], + self, + condition: Union[str, Sequence[str], Predicate], then: Constraint, - else_: Optional[Constraint] = None + else_: Optional[Constraint] = None, ): - """ - Checks one constraint or another depending on the truth value of the condition. - - .. versionadded:: 0.8.0 - you can now pass a sequence of parameter names as condition, which - corresponds to the predicate ``AllSet(*param_names)``. - - :param condition: - can be either an instance of ``Predicate`` or (more often) the name of a - parameter or a list/tuple of parameters that must be all set for the - condition to be true. - :param then: - a constraint checked if the condition is true. - :param else_: - an (optional) constraint checked if the condition is false. - """ self._condition = as_predicate(condition) self._then = then self._else = else_ @@ -53,9 +55,9 @@ then_help = self._then.help(ctx) else_help = self._else.help(ctx) if self._else else None if not self._else: - return f'{then_help} if {condition}' + return f"{then_help} if {condition}" else: - return f'{then_help} if {condition}, otherwise {else_help}' + return f"{then_help} if {condition}, otherwise {else_help}" def check_consistency(self, params: Sequence[Parameter]) -> None: self._then.check_consistency(params) @@ -71,10 +73,14 @@ try: branch.check_values(params, ctx=ctx) except ConstraintViolated as err: - desc = (condition.description(ctx) if condition_is_true - else condition.negated_description(ctx)) + desc = ( + condition.description(ctx) + if condition_is_true + else condition.negated_description(ctx) + ) raise ConstraintViolated( - f"when {desc}, {err}", ctx=ctx, constraint=self, params=params) + f"when {desc}, {err}", ctx=ctx, constraint=self, params=params + ) def __repr__(self) -> str: if self._else: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cloup-2.0.0.post1/cloup/constraints/_core.py new/cloup-2.1.0/cloup/constraints/_core.py --- old/cloup-2.0.0.post1/cloup/constraints/_core.py 2022-11-13 22:29:13.000000000 +0100 +++ new/cloup-2.1.0/cloup/constraints/_core.py 2023-05-15 03:54:09.000000000 +0200 @@ -39,7 +39,7 @@ @staticmethod def must_check_consistency(ctx: click.Context) -> bool: - """Returns True if consistency checks are enabled. + """Return ``True`` if consistency checks are enabled. .. versionchanged:: 0.9.0 this method now a static method and takes a ``click.Context`` in input. @@ -65,7 +65,7 @@ def check_consistency(self, params: Sequence[click.Parameter]) -> None: """ - Performs some sanity checks that detect inconsistencies between these + Perform some sanity checks that detect inconsistencies between these constraints and the properties of the input parameters (e.g. required). For example, a constraint that requires the parameters to be mutually @@ -88,7 +88,7 @@ @abc.abstractmethod def check_values(self, params: Sequence[click.Parameter], ctx: click.Context) -> None: """ - Checks that the constraint is satisfied by the input parameters in the + Check that the constraint is satisfied by the input parameters in the given context, which (among other things) contains the values assigned to the parameters in ``ctx.params``. @@ -116,7 +116,7 @@ ctx: Optional[click.Context] = None ) -> None: """ - Raises an exception if the constraint is not satisfied by the input + Raise an exception if the constraint is not satisfied by the input parameters in the given (or current) context. This method calls both :meth:`check_consistency` (if enabled) and @@ -162,7 +162,7 @@ error: Union[None, str, ErrorRephraser] = None, ) -> 'Rephraser': """ - Overrides the help string and/or the error message of this constraint + Override the help string and/or the error message of this constraint wrapping it with a :class:`Rephraser`. :param help: @@ -184,7 +184,7 @@ return Rephraser(self, help=help, error=error) def hidden(self) -> 'Rephraser': - """Hides this constraint from the command help.""" + """Hide this constraint from the command help.""" return Rephraser(self, help='') def __call__(self, *param_adders: Decorator) -> Callable[[F], F]: @@ -301,7 +301,7 @@ class Rephraser(Constraint): - """A Constraint decorator that can override the help and/or the error + """A constraint decorator that can override the help and/or the error message of the wrapped constraint. You'll rarely (if ever) use this class directly. In most cases, you'll use @@ -321,7 +321,7 @@ error: Union[None, str, ErrorRephraser] = None, ): if help is None and error is None: - raise ValueError('at least one between [help] and [error] must not be None') + raise ValueError('`help` and `error` cannot both be `None`') self.constraint = constraint self._help = help self._error = error diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cloup-2.0.0.post1/cloup/constraints/_support.py new/cloup-2.1.0/cloup/constraints/_support.py --- old/cloup-2.0.0.post1/cloup/constraints/_support.py 2022-11-13 22:29:13.000000000 +0100 +++ new/cloup-2.1.0/cloup/constraints/_support.py 2023-05-15 03:54:09.000000000 +0200 @@ -36,7 +36,7 @@ def constraint(constr: Constraint, params: Iterable[str]) -> Callable[[F], F]: - """Registers a constraint on a list of parameters specified by (destination) name + """Register a constraint on a list of parameters specified by (destination) name (e.g. the default name of ``--input-file`` is ``input_file``).""" spec = BoundConstraintSpec(constr, tuple(params)) @@ -52,7 +52,7 @@ *param_adders: Decorator, ) -> Callable[[F], F]: """ - Returns a decorator that adds the given parameters and applies a constraint + Return a decorator that adds the given parameters and applies a constraint to them. Equivalent to:: @param_adders[0] @@ -119,7 +119,7 @@ class ConstraintMixin: - """Provides support to constraints.""" + """Provides support for constraints.""" def __init__( self, *args: Any, diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cloup-2.0.0.post1/cloup/constraints/common.py new/cloup-2.1.0/cloup/constraints/common.py --- old/cloup-2.0.0.post1/cloup/constraints/common.py 2022-11-13 22:29:13.000000000 +0100 +++ new/cloup-2.1.0/cloup/constraints/common.py 2023-05-15 03:54:09.000000000 +0200 @@ -7,7 +7,7 @@ def param_value_is_set(param: Parameter, value: Any) -> bool: - """Defines what it means for a parameter of a specific kind to be "set". + """Define what it means for a parameter of a specific kind to be "set". All cases are obvious besides that of boolean options: - (common rule) if the value is ``None``, the parameter is unset; @@ -27,7 +27,7 @@ def get_param_name(param: Parameter) -> str: - """Returns the name of a parameter casted to ``str``. + """Return the name of a parameter casted to ``str``. Use this function to avoid typing errors in places where you expect a parameter having a name. """ @@ -43,7 +43,7 @@ def get_params_whose_value_is_set( params: Iterable[Parameter], values: Dict[str, Any] ) -> List[Parameter]: - """Filters ``params`` returning only the parameters that have a value. + """Filter ``params``, returning only the parameters that have a value. Boolean flags are considered "set" if their value is ``True``.""" return [p for p in params if param_value_is_set(p, values[get_param_name(p)])] diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cloup-2.0.0.post1/cloup/constraints/exceptions.py new/cloup-2.1.0/cloup/constraints/exceptions.py --- old/cloup-2.0.0.post1/cloup/constraints/exceptions.py 2022-11-13 22:29:13.000000000 +0100 +++ new/cloup-2.1.0/cloup/constraints/exceptions.py 2023-05-15 03:54:09.000000000 +0200 @@ -43,9 +43,9 @@ class UnsatisfiableConstraint(Exception): - """ Raised if a constraint cannot be satisfied by a group of parameters - independently from their values at runtime; e.g. mutually_exclusive cannot - be satisfied if multiple of the parameters are required. """ + """Raised if a constraint cannot be satisfied by a group of parameters + independently from their values at runtime; e.g. ``mutually_exclusive`` cannot + be satisfied if multiple of the parameters are required.""" def __init__( self, constraint: 'Constraint', params: Iterable[Parameter], reason: str diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cloup-2.0.0.post1/cloup/formatting/_formatter.py new/cloup-2.1.0/cloup/formatting/_formatter.py --- old/cloup-2.0.0.post1/cloup/formatting/_formatter.py 2022-11-13 22:29:13.000000000 +0100 +++ new/cloup-2.1.0/cloup/formatting/_formatter.py 2023-05-15 03:54:09.000000000 +0200 @@ -185,7 +185,9 @@ if help_text and click_version_ge_8_1: help_text = inspect.cleandoc(help_text) if cmd.deprecated: - help_text = "(DEPRECATED) " + help_text + # Use the same label as Click: + # https://github.com/pallets/click/blob/b0538df/src/click/core.py#L1331 + help_text = "(Deprecated) " + help_text if help_text: self.write_paragraph() with self.indentation(): @@ -208,7 +210,7 @@ self.write_section(s) def write_aligned_sections(self, sections: Sequence[HelpSection]) -> None: - """Writes multiple aligned definition lists.""" + """Write multiple aligned definition lists.""" all_rows = chain.from_iterable(dl.definitions for dl in sections) col1_width = self.compute_col1_width(all_rows, self.col1_max_width) for s in sections: @@ -255,7 +257,7 @@ col_spacing: Optional[int] = None, # default changed to None wrt parent class col1_width: Optional[int] = None, ) -> None: - """Writes a definition list into the buffer. This is how options + """Write a definition list into the buffer. This is how options and commands are usually formatted. If there's enough space, definition lists are rendered as a 2-column @@ -322,7 +324,7 @@ self, rows: Sequence[Definition], col1_width: int, col_spacing: int, col2_width: int, ) -> None: - """Formats a definition list as a 2-column "pseudo-table". If the first + """Format a definition list as a 2-column "pseudo-table". If the first column of a row exceeds ``col1_width``, the 2nd column is written on the subsequent line. This is the standard way of formatting definition lists and it's the default if there's enough space.""" @@ -367,7 +369,7 @@ write_row(row) def write_linear_dl(self, dl: Sequence[Definition]) -> None: - """Formats a definition list as a "linear list". This is the default when + """Format a definition list as a "linear list". This is the default when the available width for the definitions (2nd column) is below ``self.col2_min_width``.""" help_extra_indent = max(3, self.indent_increment) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cloup-2.0.0.post1/cloup/formatting/_util.py new/cloup-2.1.0/cloup/formatting/_util.py --- old/cloup-2.0.0.post1/cloup/formatting/_util.py 2022-11-13 22:29:13.000000000 +0100 +++ new/cloup-2.1.0/cloup/formatting/_util.py 2023-05-15 03:54:09.000000000 +0200 @@ -6,13 +6,13 @@ import cloup FORMATTER_TYPE_ERROR = """ -since cloup v0.8.0, this class relies on cloup.HelpFormatter to align help -sections. So, you need to make sure your command class uses cloup.HelpFormatter +since Cloup v0.8, this class relies on `cloup.HelpFormatter` to align help +sections. So, you need to make sure your command class uses `cloup.HelpFormatter` as formatter class. -If you have your own custom HelpFormatter, know that cloup.HelpFormatter is +If you have your own custom `HelpFormatter`, know that `cloup.HelpFormatter` is more easily customizable then Click's one, so consider extending it instead -of extending click.HelpFormatter. +of extending `click.HelpFormatter`. """ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cloup-2.0.0.post1/cloup/formatting/sep.py new/cloup-2.1.0/cloup/formatting/sep.py --- old/cloup-2.0.0.post1/cloup/formatting/sep.py 2022-11-13 22:29:13.000000000 +0100 +++ new/cloup-2.1.0/cloup/formatting/sep.py 2023-05-15 03:54:09.000000000 +0200 @@ -19,7 +19,7 @@ class SepGenerator(Protocol): - """Generates a separator given a width. When used as ``row_sep``, this ``width` + """Generate a separator given a width. When used as ``row_sep``, this ``width`` corresponds to ``HelpFormatter.available_width``, i.e. the line width excluding the current indentation width. @@ -54,7 +54,7 @@ col_widths: Sequence[int], col_spacing: int, ) -> Optional[str]: - """Decides which row separator to use (eventually none) in the given + """Decide which row separator to use (eventually none) in the given definition list.""" @@ -67,34 +67,35 @@ col_widths: Sequence[int], col_spacing: int, ) -> bool: - """Returns ``True`` if the input definition list should use a row + """Return ``True`` if the input definition list should use a row separator (in addition to the usual ``\\n``).""" class RowSepIf(RowSepPolicy): + """ + Inserts a row separator between the rows of a definition list only if a + condition is satisfied. This class implements the ``RowSepPolicy`` + protocol and does two things: + + - enforces the use of a single row separator for all rows of a + definition lists and for all definition lists; note that + ``RowSepPolicy`` doesn't for implementation reasons but it's probably + what you want; + - allows you to implement different conditions (see type + :data:`RowSepCondition`) without worrying about the generation part, + which is always the same. + + :param condition: + a :class:`RowSepCondition` that determines when to add the (extra) + row separator. + :param sep: + either a string or a ``SepGenerator``, + i.e. a function ``(width: int) -> str`` (e.g. :class:`Hline`). + The empty string corresponds to an empty line separator. + """ + def __init__(self, condition: RowSepCondition, sep: Union[str, SepGenerator] = ''): - """ - Inserts a row separator between the rows of a definition list only if a - condition is satisfied. This class implements the ``RowSepPolicy`` - protocol and does two things: - - - enforces the use of a single row separator for all rows of a - definition lists and for all definition lists; note that - ``RowSepPolicy`` doesn't for implementation reasons but it's probably - what you want; - - allows you to implement different conditions (see type - :data:`RowSepCondition`) without worrying about the generation part, - which is always the same. - - :param condition: - a :class:`RowSepCondition` that determines when to add the (extra) - row separator. - :param sep: - either a string or a ``SepGenerator``, - i.e. a function ``(width: int) -> str`` (e.g. :class:`Hline`). - The empty string corresponds to an empty line separator. - """ if isinstance(sep, str) and sep.endswith('\n'): raise ValueError( "sep must not end with '\\n'. The formatter writes a '\\n' after it; " @@ -117,7 +118,7 @@ # Conditions & related utils def get_total_width(col_widths: Sequence[int], col_spacing: int) -> int: - """Returns the total width of a definition list (or, more generally, a table). + """Return the total width of a definition list (or, more generally, a table). Useful when implementing a RowSepStrategy.""" return sum(col_widths) + col_spacing * (len(col_widths) - 1) @@ -137,7 +138,7 @@ count_or_percentage: Union[int, float] ) -> RowSepCondition: """ - Returns a ``RowSepStrategy`` that returns a row separator between all rows + Return a ``RowSepStrategy`` that returns a row separator between all rows of a definition list, only if the number of rows taking multiple lines is greater than or equal to a certain threshold. @@ -183,6 +184,17 @@ class Hline(SepGenerator): + """Returns a function that generates an horizontal line of a given length. + + This class has different static members for different line styles + like ``Hline.solid``, ``Hline.dashed``, ``Hline.densely_dashed`` + and ``Hline.dotted``. + + :param pattern: + a string (usually a single character) that is repeated to generate + the line. + """ + # Workaround: PyCharm auto-completion doesn't work without these declarations solid: 'Hline' dashed: 'Hline' @@ -190,16 +202,6 @@ dotted: 'Hline' def __init__(self, pattern: str): - """Returns a function that generates an horizontal line of a given length. - - This class has different static members for different line styles - like ``Hline.solid``, ``Hline.dashed``, ``Hline.densely_dashed`` - and ``Hline.dotted``. - - :param pattern: - a string (usually a single character) that is repeated to generate - the line. - """ self.pattern = pattern def __call__(self, width: int) -> str: @@ -211,13 +213,13 @@ Hline.solid = Hline("â") -"""Returns a line like ``ââââââââ``.""" +"""Return a line like ``ââââââââ``.""" Hline.dashed = Hline('-') -"""Returns a line like ``--------``.""" +"""Return a line like ``--------``.""" Hline.densely_dashed = Hline('â') -"""Returns a line like ``ââââââââ``.""" +"""Return a line like ``ââââââââ``.""" Hline.dotted = Hline("â") -"""Returns a line like ``ââââââââ``.""" +"""Return a line like ``ââââââââ``.""" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cloup-2.0.0.post1/cloup/styling.py new/cloup-2.1.0/cloup/styling.py --- old/cloup-2.0.0.post1/cloup/styling.py 2022-11-13 22:29:13.000000000 +0100 +++ new/cloup-2.1.0/cloup/styling.py 2023-05-15 03:54:09.000000000 +0200 @@ -8,6 +8,7 @@ import click from cloup._util import FrozenSpace, click_version_tuple, delete_keys, identity +from cloup.typing import MISSING, Possibly IStyle = Callable[[str], str] """A callable that takes a string and returns a styled version of it.""" @@ -39,6 +40,11 @@ Style of the second column of a definition list (help text). :param epilog: Style of the epilog. + :param alias: + Style of subcommand aliases in a definition lists. + :param alias_secondary: + Style of separator and eventual parenthesis/brackets in subcommand alias lists. + If not provided, the ``alias`` style will be used. """ invoked_command: IStyle = identity @@ -62,6 +68,13 @@ col2: IStyle = identity """Style of the second column of a definition list (help text).""" + alias: IStyle = identity + """Style of subcommand aliases in a definition lists.""" + + alias_secondary: Optional[IStyle] = None + """Style of separator and eventual parenthesis/brackets in subcommand alias lists. + If not provided, the ``alias`` style will be used.""" + epilog: IStyle = identity """Style of the epilog.""" @@ -73,9 +86,13 @@ section_help: Optional[IStyle] = None, col1: Optional[IStyle] = None, col2: Optional[IStyle] = None, + alias: Optional[IStyle] = None, + alias_secondary: Possibly[Optional[IStyle]] = MISSING, epilog: Optional[IStyle] = None, ) -> 'HelpTheme': kwargs = {key: val for key, val in locals().items() if val is not None} + if alias_secondary is MISSING: + del kwargs["alias_secondary"] kwargs.pop('self') if kwargs: return self._replace(**kwargs) @@ -89,6 +106,8 @@ heading=Style(fg='bright_white', bold=True), constraint=Style(fg='magenta'), col1=Style(fg='bright_yellow'), + alias=Style(fg='yellow'), + alias_secondary=Style(fg='white'), ) @staticmethod @@ -184,3 +203,6 @@ bright_magenta = "bright_magenta" bright_cyan = "bright_cyan" bright_white = "bright_white" + + +DEFAULT_THEME = HelpTheme() diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cloup-2.0.0.post1/cloup/types.py new/cloup-2.1.0/cloup/types.py --- old/cloup-2.0.0.post1/cloup/types.py 2022-11-13 22:29:13.000000000 +0100 +++ new/cloup-2.1.0/cloup/types.py 2023-05-15 03:54:09.000000000 +0200 @@ -1,5 +1,5 @@ """ -Parameter types and "shortcuts" to create commonly used types. +Parameter types and "shortcuts" for creating commonly used types. """ import pathlib diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cloup-2.0.0.post1/cloup.egg-info/PKG-INFO new/cloup-2.1.0/cloup.egg-info/PKG-INFO --- old/cloup-2.0.0.post1/cloup.egg-info/PKG-INFO 2022-11-13 22:29:31.000000000 +0100 +++ new/cloup-2.1.0/cloup.egg-info/PKG-INFO 2023-05-15 03:54:24.000000000 +0200 @@ -1,6 +1,6 @@ Metadata-Version: 2.1 Name: cloup -Version: 2.0.0.post1 +Version: 2.1.0 Summary: Adds features to Click: option groups, constraints, subcommand sections and help themes. Home-page: https://github.com/janLuke/cloup Author: Gianluca Gippetto @@ -32,7 +32,7 @@ .. |coverage| image:: https://codecov.io/github/janLuke/cloup/coverage.svg?branch=master :alt: Coverage Status - :target: https://codecov.io/github/janLuke/cloup?branch=master + :target: https://app.codecov.io/github/janluke/cloup/tree/master .. |python-versions| image:: https://img.shields.io/pypi/pyversions/cloup.svg :alt: Supported versions @@ -70,7 +70,7 @@ - **subcommand aliases** -- **subcommands sections**, i.e. the possibility to organize the subcommands of a +- **subcommands sections**, i.e. the possibility of organizing the subcommands of a ``Group`` in multiple help sections - a **themeable HelpFormatter** that: @@ -86,8 +86,8 @@ type hints and adding the static methods ``Context.settings()`` and ``HelpFormatter.settings()`` for creating dictionaries of settings. -Cloup is **statically type-checked** with MyPy in strict mode and extensively **tested** -against multiple versions of Python with nearly 100% coverage. +Cloup is **statically type-checked** with MyPy in strict mode and extensively **tested** +against multiple versions of Python with nearly 100% coverage. A simple example diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cloup-2.0.0.post1/docs/pages/constraints.rst new/cloup-2.1.0/docs/pages/constraints.rst --- old/cloup-2.0.0.post1/docs/pages/constraints.rst 2022-11-13 22:29:13.000000000 +0100 +++ new/cloup-2.1.0/docs/pages/constraints.rst 2023-05-15 03:54:09.000000000 +0200 @@ -222,8 +222,8 @@ ) -The @constraint decorator -~~~~~~~~~~~~~~~~~~~~~~~~~ +The ``@constraint`` decorator +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Using the :func:`cloup.constraint` decorator, you can apply a constraint to any group of parameters (arguments and options) providing their **destination names**, i.e. the names of the function arguments they are mapped to (by Click). @@ -316,7 +316,7 @@ In Python < 3.9, the expression on the right of the operator ``@`` is required to be a "dotted name, optionally followed by a single call" - (see `PEP 614 <https://www.python.org/dev/peps/pep-0614/#motivation>`_). + (see `PEP 614 <https://peps.python.org/pep-0614/#motivation>`_). This means that you can't instantiate a parametric constraint on the right of ``@``, because the resultant expressions would make two calls, e.g.: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cloup-2.0.0.post1/docs/pages/formatting.rst new/cloup-2.1.0/docs/pages/formatting.rst --- old/cloup-2.0.0.post1/docs/pages/formatting.rst 2022-11-13 22:29:13.000000000 +0100 +++ new/cloup-2.1.0/docs/pages/formatting.rst 2023-05-15 03:54:09.000000000 +0200 @@ -36,7 +36,7 @@ .. tip:: In Cloup, you can use the static methods :meth:`Context.settings` and :meth:`HelpFormatter.settings` to create dictionaries without leaving your - IDE (to check the docs). + IDE to check the docs. .. code-block:: python diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cloup-2.0.0.post1/docs/pages/option-groups.rst new/cloup-2.1.0/docs/pages/option-groups.rst --- old/cloup-2.0.0.post1/docs/pages/option-groups.rst 2022-11-13 22:29:13.000000000 +0100 +++ new/cloup-2.1.0/docs/pages/option-groups.rst 2023-05-15 03:54:09.000000000 +0200 @@ -66,7 +66,7 @@ @option("--seven", help="1st uncategorized option") @option("--height", help="2nd uncategorized option") def cli(**kwargs): - """ A CLI that does nothing. """ + """A CLI that does nothing.""" print(kwargs) cli() @@ -222,7 +222,7 @@ @output_grp.option('--three') @output_grp.option('--four') def cli_flat(one, two, three, four): - """ A CLI that does nothing. """ + """A CLI that does nothing.""" print(kwargs) The above notation is just syntax sugar on top of ``@cloup.option``: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cloup-2.0.0.post1/docs/pages/sections.rst new/cloup-2.1.0/docs/pages/sections.rst --- old/cloup-2.0.0.post1/docs/pages/sections.rst 2022-11-13 22:29:13.000000000 +0100 +++ new/cloup-2.1.0/docs/pages/sections.rst 2023-05-15 03:54:09.000000000 +0200 @@ -3,7 +3,7 @@ Subcommand sections =================== -Cloup allows to organize the subcommand of a ``Group`` (or, more in general, of +Cloup allows you to organize the subcommand of a ``Group`` (or, more in general, of a ``MultiCommand``) in multiple help sections. Each such help section is represented by a :class:`~cloup.Section` instance, which is just a titled container for commands. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cloup-2.0.0.post1/examples/flat_option_groups.py new/cloup-2.1.0/examples/flat_option_groups.py --- old/cloup-2.0.0.post1/examples/flat_option_groups.py 2022-11-13 22:29:13.000000000 +0100 +++ new/cloup-2.1.0/examples/flat_option_groups.py 2023-05-15 03:54:09.000000000 +0200 @@ -32,7 +32,7 @@ type=click.Choice('yes no ask'.split())) @option('--height', help='second uncategorized option') def main(**kwargs): - """ A CLI that does nothing. """ + """A CLI that does nothing.""" print(kwargs) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cloup-2.0.0.post1/examples/git_sections.py new/cloup-2.1.0/examples/git_sections.py --- old/cloup-2.0.0.post1/examples/git_sections.py 2022-11-13 22:29:13.000000000 +0100 +++ new/cloup-2.1.0/examples/git_sections.py 2023-05-15 03:54:09.000000000 +0200 @@ -1,9 +1,9 @@ """ -This example shows how to use cloup.Section to organize the subcommands of -a multi-command in many --help sections. +This example shows how to use ``cloup.Section`` to organize the subcommands of +a multi-command in many ``--help`` sections. -The code was generated by parsing "git --help" and taking -- the first 3 sections +The code was generated by parsing ``git --help`` and taking +- the first 3 sections; - for each section, the first 3 commands after shuffling them. """ # flake8: noqa E128 @@ -11,7 +11,7 @@ def f(**kwargs): - """ Dummy command callback """ + """Dummy command callback.""" print(**kwargs) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cloup-2.0.0.post1/examples/manim/config.py new/cloup-2.1.0/examples/manim/config.py --- old/cloup-2.0.0.post1/examples/manim/config.py 2022-11-13 22:29:13.000000000 +0100 +++ new/cloup-2.1.0/examples/manim/config.py 2023-05-15 03:54:09.000000000 +0200 @@ -9,8 +9,7 @@ no_args_is_help=True, ) def config(): - """Manages Manim configuration files.""" - pass + """Manage Manim configuration files.""" @config.command(no_args_is_help=True) @@ -21,14 +20,12 @@ ) @cloup.option("-o", "--open", "openfile", is_flag=True) def write(level: str, openfile: bool) -> None: - """Writes configurations.""" - pass + """Write configurations.""" @config.command() def show(): - """Shows current configuration.""" - pass + """Show current configuration.""" @config.command() diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cloup-2.0.0.post1/examples/manim/main.py new/cloup-2.1.0/examples/manim/main.py --- old/cloup-2.0.0.post1/examples/manim/main.py 2022-11-13 22:29:13.000000000 +0100 +++ new/cloup-2.1.0/examples/manim/main.py 2023-05-15 03:54:09.000000000 +0200 @@ -41,6 +41,8 @@ # col1=Style(...), col2=Style(dim=True), epilog=Style(fg=Color.bright_white, italic=True), + alias=Style(fg=Color.yellow), + alias_secondary=Style(fg=Color.white), ), ), ) @@ -55,7 +57,6 @@ @cloup.version_option(version=VERSION) def main(): """Animation engine for explanatory math videos.""" - pass main.add_command(render) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cloup-2.0.0.post1/scripts/generate_git_example.py new/cloup-2.1.0/scripts/generate_git_example.py --- old/cloup-2.0.0.post1/scripts/generate_git_example.py 2022-11-13 22:29:13.000000000 +0100 +++ new/cloup-2.1.0/scripts/generate_git_example.py 2023-05-15 03:54:09.000000000 +0200 @@ -39,8 +39,8 @@ CODE_TEMPLATE = """ \"\"\" -This example shows how to use cloup.Section to organize the subcommands of -a multi-command in many --help sections. +This example shows how to use ``cloup.Section`` to organize the subcommands of +a multi-command in many ``--help`` sections. The code was generated by parsing "git --help" and taking - the first {max_section_count} sections diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cloup-2.0.0.post1/tests/constraints/test_constraints.py new/cloup-2.1.0/tests/constraints/test_constraints.py --- old/cloup-2.0.0.post1/tests/constraints/test_constraints.py 2022-11-13 22:29:13.000000000 +0100 +++ new/cloup-2.1.0/tests/constraints/test_constraints.py 2023-05-15 03:54:09.000000000 +0200 @@ -25,7 +25,7 @@ class FakeConstraint(Constraint): - """Sometimes it's useful to use:: + """Sometimes it's useful to use Mock(wraps=FakeConstraint(...)) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cloup-2.0.0.post1/tests/example_command.py new/cloup-2.1.0/tests/example_command.py --- old/cloup-2.0.0.post1/tests/example_command.py 2022-11-13 22:29:13.000000000 +0100 +++ new/cloup-2.1.0/tests/example_command.py 2023-05-15 03:54:09.000000000 +0200 @@ -49,7 +49,7 @@ @option('--height', help='Second uncategorized option.') @option('--nine', help='Third uncategorized option.', hidden=True) def cmd(**kwargs): - """ A CLI that does nothing. """ + """A CLI that does nothing.""" print(kwargs) if tabular_help: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cloup-2.0.0.post1/tests/test_aliases.py new/cloup-2.1.0/tests/test_aliases.py --- old/cloup-2.0.0.post1/tests/test_aliases.py 2022-11-13 22:29:13.000000000 +0100 +++ new/cloup-2.1.0/tests/test_aliases.py 2023-05-15 03:54:09.000000000 +0200 @@ -1,9 +1,12 @@ +from typing import Optional + import click import pytest import cloup -from cloup import Group -from cloup._util import first_bool, reindent +from cloup import Color, Group, HelpTheme, Style +from cloup._util import first_bool, identity, reindent +from cloup.styling import IStyle from cloup.typing import MISSING @@ -12,7 +15,6 @@ @cloup.group() def cli(): """A package installer.""" - pass @cloup.command(aliases=['i', 'add']) @cloup.argument('pkg') @@ -169,3 +171,28 @@ --help Show this message and exit. """) assert res.output == expected + + +def test_alias_are_correctly_styled(runner): + red = Style(fg=Color.red) + green = Style(fg=Color.green) + + def fmt(alias: IStyle = identity, alias_secondary: Optional[IStyle] = None): + theme = HelpTheme(alias=alias, alias_secondary=alias_secondary) + return Group.format_subcommand_aliases(["i", "add"], theme) + + # No styles (default theme) + assert fmt() == "(i, add)" + + # Only theme.alias + assert fmt(alias=green) == f"{green('(i, add)')}" + + # Only theme.alias_secondary + assert fmt(alias_secondary=green) == ( + green("(") + "i" + green(", ") + "add" + green(")") + ) + + # Both + assert fmt(alias=red, alias_secondary=green) == ( + green("(") + red("i") + green(", ") + red("add") + green(")") + ) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cloup-2.0.0.post1/tests/test_formatting.py new/cloup-2.1.0/tests/test_formatting.py --- old/cloup-2.0.0.post1/tests/test_formatting.py 2022-11-13 22:29:13.000000000 +0100 +++ new/cloup-2.1.0/tests/test_formatting.py 2023-05-15 03:54:09.000000000 +0200 @@ -9,12 +9,12 @@ import pytest from cloup import HelpFormatter -from cloup.typing import Possibly from cloup.formatting import HelpSection, unstyled_len from cloup.formatting.sep import ( Hline, RowSepIf, RowSepPolicy, multiline_rows_are_at_least ) from cloup.styling import HelpTheme, Style +from cloup.typing import Possibly from tests.util import parametrize LOREM = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor." diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cloup-2.0.0.post1/tests/test_option_groups.py new/cloup-2.1.0/tests/test_option_groups.py --- old/cloup-2.0.0.post1/tests/test_option_groups.py 2022-11-13 22:29:13.000000000 +0100 +++ new/cloup-2.1.0/tests/test_option_groups.py 2023-05-15 03:54:09.000000000 +0200 @@ -1,4 +1,4 @@ -"""Tests for the "option groups" feature/module.""" +"""Test for the "option groups" feature/module.""" from textwrap import dedent from typing import cast diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cloup-2.0.0.post1/tests/test_sections.py new/cloup-2.1.0/tests/test_sections.py --- old/cloup-2.0.0.post1/tests/test_sections.py 2022-11-13 22:29:13.000000000 +0100 +++ new/cloup-2.1.0/tests/test_sections.py 2023-05-15 03:54:09.000000000 +0200 @@ -1,4 +1,4 @@ -"""Tests for the "subcommand sections" feature/module.""" +"""Test for the "subcommand sections" feature/module.""" import click import pytest from click import pass_context diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cloup-2.0.0.post1/tests/util.py new/cloup-2.1.0/tests/util.py --- old/cloup-2.0.0.post1/tests/util.py 2022-11-13 22:29:13.000000000 +0100 +++ new/cloup-2.1.0/tests/util.py 2023-05-15 03:54:09.000000000 +0200 @@ -52,7 +52,7 @@ cls=Context, **ctx_kwargs ) -> Context: - """Creates a simple instance of Command with the specified parameters, + """Create a simple instance of Command with the specified parameters, then create a fake context without actually invoking the command.""" return cls( command_cls('fake', params=params, callback=new_dummy_func()), **ctx_kwargs
