Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package python-click-extra for openSUSE:Factory checked in at 2026-03-02 17:41:49 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/python-click-extra (Old) and /work/SRC/openSUSE:Factory/.python-click-extra.new.29461 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-click-extra" Mon Mar 2 17:41:49 2026 rev:15 rq:1335820 version:7.6.3 Changes: -------- --- /work/SRC/openSUSE:Factory/python-click-extra/python-click-extra.changes 2026-02-27 17:14:04.746481758 +0100 +++ /work/SRC/openSUSE:Factory/.python-click-extra.new.29461/python-click-extra.changes 2026-03-02 17:42:08.795877323 +0100 @@ -1,0 +2,22 @@ +Mon Mar 2 12:10:37 UTC 2026 - Johannes Kastl <[email protected]> + +- update to 7.6.3: + * Fix test_default_pattern_roaming_force_posix test failures when + XDG_CONFIG_HOME is set. Closes {issue}1541. + +------------------------------------------------------------------- +Mon Mar 2 06:40:13 UTC 2026 - Johannes Kastl <[email protected]> + +- update to 7.6.2: + * Add ExtraVersionOption.prebake_version() static method to pre-bake + __version__ strings with Git hashes at compile time, complementing + the runtime version property for Nuitka/PyInstaller binaries. + +------------------------------------------------------------------- +Fri Feb 27 12:34:49 UTC 2026 - Johannes Kastl <[email protected]> + +- update to 7.6.1: + * Fix test failures when optional config format dependencies are not + installed. Closes {issue}1538. + +------------------------------------------------------------------- Old: ---- click-extra-7.6.0.tar.gz New: ---- click-extra-7.6.3.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ python-click-extra.spec ++++++ --- /var/tmp/diff_new_pack.f9FwQA/_old 2026-03-02 17:42:09.271897185 +0100 +++ /var/tmp/diff_new_pack.f9FwQA/_new 2026-03-02 17:42:09.275897352 +0100 @@ -27,7 +27,7 @@ %{?sle15_python_module_pythons} Name: python-click-extra -Version: 7.6.0 +Version: 7.6.3 Release: 0 Summary: Drop-in replacement for Click to make user-friendly and colorful CLI License: GPL-2.0-or-later @@ -126,9 +126,6 @@ IGNORED_CHECKS+=" or test_enum_choice_show_aliases[Status-ChoiceSource.NAME-True-result2]" IGNORED_CHECKS+=" or test_enum_choice_show_aliases[Status-ChoiceSource.VALUE-True-result3]" IGNORED_CHECKS+=" or test_enum_choice_show_aliases[Color-ChoiceSource.NAME-True-result4]" -# -# https://github.com/kdeldycke/click-extra/issues/1538 -IGNORED_CHECKS+=" or test_file_pattern" %pytest -k "not (${IGNORED_CHECKS})" ++++++ click-extra-7.6.0.tar.gz -> click-extra-7.6.3.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/click-extra-7.6.0/.github/workflows/tests.yaml new/click-extra-7.6.3/.github/workflows/tests.yaml --- old/click-extra-7.6.0/.github/workflows/tests.yaml 2026-02-26 09:42:28.000000000 +0100 +++ new/click-extra-7.6.3/.github/workflows/tests.yaml 2026-03-02 10:52:22.000000000 +0100 @@ -58,7 +58,6 @@ - released - stable - main - - hide-unset-in-lookup_default cloup-version: - released - master @@ -110,24 +109,18 @@ - os: ubuntu-slim click-version: main - os: ubuntu-slim - click-version: hide-unset-in-lookup_default - - os: ubuntu-slim cloup-version: master - os: macos-15-intel click-version: stable - os: macos-15-intel click-version: main - os: macos-15-intel - click-version: hide-unset-in-lookup_default - - os: macos-15-intel cloup-version: master - os: windows-2025 click-version: stable - os: windows-2025 click-version: main - os: windows-2025 - click-version: hide-unset-in-lookup_default - - os: windows-2025 cloup-version: master # Exclude old Python version. Only test on latest stable release. - python-version: "3.10" @@ -135,8 +128,6 @@ - python-version: "3.10" click-version: main - python-version: "3.10" - click-version: hide-unset-in-lookup_default - - python-version: "3.10" cloup-version: master # Exclude Python's dev version. - python-version: "3.15" @@ -144,16 +135,12 @@ - python-version: "3.15" click-version: main - python-version: "3.15" - click-version: hide-unset-in-lookup_default - - python-version: "3.15" cloup-version: master - python-version: "3.15t" click-version: stable - python-version: "3.15t" click-version: main - python-version: "3.15t" - click-version: hide-unset-in-lookup_default - - python-version: "3.15t" cloup-version: master include: # Default all jobs as stable, unless marked otherwise below. @@ -207,9 +194,7 @@ - name: Unittests run: > uv --no-progress run --frozen - ${{ matrix.click-version == 'hide-unset-in-lookup_default' - && '--with "git+https://github.com/kdeldycke/click.git@hide-unset-in-lookup_default"' - || matrix.click-version != 'released' + ${{ matrix.click-version != 'released' && format('--with "git+https://github.com/pallets/click.git@{0}"', matrix.click-version) || '' }} ${{ matrix.cloup-version != 'released' && format('--with "git+https://github.com/janluke/cloup.git@{0}"', matrix.cloup-version) || ''}} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/click-extra-7.6.0/changelog.md new/click-extra-7.6.3/changelog.md --- old/click-extra-7.6.0/changelog.md 2026-02-26 09:42:28.000000000 +0100 +++ new/click-extra-7.6.3/changelog.md 2026-03-02 10:52:22.000000000 +0100 @@ -1,5 +1,17 @@ # Changelog +## [7.6.3 (2026-03-02)](https://github.com/kdeldycke/click-extra/compare/v7.6.2...v7.6.3) + +- Fix `test_default_pattern_roaming_force_posix` test failures when `XDG_CONFIG_HOME` is set. Closes {issue}`1541`. + +## [7.6.2 (2026-02-27)](https://github.com/kdeldycke/click-extra/compare/v7.6.1...v7.6.2) + +- Add `ExtraVersionOption.prebake_version()` static method to pre-bake `__version__` strings with Git hashes at compile time, complementing the runtime `version` property for Nuitka/PyInstaller binaries. + +## [7.6.1 (2026-02-27)](https://github.com/kdeldycke/click-extra/compare/v7.6.0...v7.6.1) + +- Fix test failures when optional config format dependencies are not installed. Closes {issue}`1538`. + ## [7.6.0 (2026-02-26)](https://github.com/kdeldycke/click-extra/compare/v7.5.3...v7.6.0) - Add `_default_subcommands` reserved configuration key to auto-invoke subcommands when none are provided on the CLI. Closes {issue}`1405`. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/click-extra-7.6.0/citation.cff new/click-extra-7.6.3/citation.cff --- old/click-extra-7.6.0/citation.cff 2026-02-26 09:42:28.000000000 +0100 +++ new/click-extra-7.6.3/citation.cff 2026-03-02 10:52:22.000000000 +0100 @@ -8,8 +8,8 @@ email: [email protected] orcid: "https://orcid.org/0000-0001-9748-9014" doi: 10.5281/zenodo.7116050 -version: 7.6.0 +version: 7.6.3 # The release date is kept up to date by the external workflows. See: # https://github.com/kdeldycke/workflows/blob/33b704b489c1aa18b7b7efbf963e153e91e1c810/.github/workflows/changelog.yaml#L135-L137 -date-released: 2026-02-26 +date-released: 2026-03-02 url: "https://github.com/kdeldycke/click-extra" \ No newline at end of file diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/click-extra-7.6.0/click_extra/__init__.py new/click-extra-7.6.3/click_extra/__init__.py --- old/click-extra-7.6.0/click_extra/__init__.py 2026-02-26 09:42:28.000000000 +0100 +++ new/click-extra-7.6.3/click_extra/__init__.py 2026-03-02 10:52:22.000000000 +0100 @@ -242,7 +242,7 @@ """ -__version__ = "7.6.0" +__version__ = "7.6.3" def __getattr__(name: str) -> object: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/click-extra-7.6.0/click_extra/commands.py new/click-extra-7.6.3/click_extra/commands.py --- old/click-extra-7.6.0/click_extra/commands.py 2026-02-26 09:42:28.000000000 +0100 +++ new/click-extra-7.6.3/click_extra/commands.py 2026-03-02 10:52:22.000000000 +0100 @@ -566,8 +566,7 @@ # Prepend subcommands only work with chained groups. if not self.chain: raise click.UsageError( - f"{PREPEND_SUBCOMMANDS_KEY} requires chain=True on group" - f" {self.name!r}." + f"{PREPEND_SUBCOMMANDS_KEY} requires chain=True on group {self.name!r}." ) # Deduplicate, keeping first occurrence, and warn on duplicates. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/click-extra-7.6.0/click_extra/version.py new/click-extra-7.6.3/click_extra/version.py --- old/click-extra-7.6.0/click_extra/version.py 2026-02-26 09:42:28.000000000 +0100 +++ new/click-extra-7.6.3/click_extra/version.py 2026-03-02 10:52:22.000000000 +0100 @@ -17,6 +17,7 @@ from __future__ import annotations +import ast import importlib import inspect import logging @@ -459,6 +460,89 @@ return f"{ver}+{git_hash}" return ver or None + @staticmethod + def prebake_version( + file_path: Path, + local_version: str, + ) -> str | None: + """Pre-bake a ``__version__`` string with a `PEP 440 local version + identifier + <https://peps.python.org/pep-0440/#local-version-identifiers>`_. + + Reads *file_path*, finds the ``__version__`` assignment via + :mod:`ast`, and — if the version contains ``.dev`` and does not + already contain ``+`` — appends ``+<local_version>``. + + This is the compile-time complement to the runtime ``version`` + property: Nuitka/PyInstaller binaries cannot run ``git`` at runtime, + so the hash must be baked into ``__version__`` in the source file + **before** compilation. + + Returns the new version string on success, or ``None`` if no change + was made (release version, already pre-baked, or no ``__version__`` + found). + """ + source = file_path.read_text(encoding="utf-8") + + tree = ast.parse(source, filename=str(file_path)) + for node in ast.iter_child_nodes(tree): + # Look for top-level: __version__ = "<value>". + if not ( + isinstance(node, ast.Assign) + and len(node.targets) == 1 + and isinstance(node.targets[0], ast.Name) + and node.targets[0].id == "__version__" + and isinstance(node.value, ast.Constant) + and isinstance(node.value.value, str) + ): + continue + + version = node.value.value + + if ".dev" not in version: + logging.info( + "Release version %r in %s — skipping.", + version, + file_path, + ) + return None + + if "+" in version: + logging.info( + "Version %r in %s already has a local identifier — skipping.", + version, + file_path, + ) + return None + + new_version = f"{version}+{local_version}" + + # Replace only the string literal in-place using AST + # positions, preserving surrounding content and quoting. + lines = source.splitlines(keepends=True) + line = lines[node.value.end_lineno - 1] + # end_col_offset points past the closing quote. + col_end = node.value.end_col_offset + # The closing quote character. + quote = line[col_end - 1] + # Insert the local version just before the closing quote. + new_line = ( + line[: col_end - 1] + "+" + local_version + quote + line[col_end:] + ) + lines[node.value.end_lineno - 1] = new_line + file_path.write_text("".join(lines), encoding="utf-8") + + logging.info( + "Pre-baked %s: %r → %r", + file_path, + version, + new_version, + ) + return new_version + + logging.warning("No __version__ found in %s", file_path) + return None + @cached_property def git_repo_path(self) -> Path | None: """Find the Git repository root directory.""" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/click-extra-7.6.0/docs/colorize.md new/click-extra-7.6.3/docs/colorize.md --- old/click-extra-7.6.0/docs/colorize.md 2026-02-26 09:42:28.000000000 +0100 +++ new/click-extra-7.6.3/docs/colorize.md 2026-03-02 10:52:22.000000000 +0100 @@ -30,6 +30,10 @@ Write examples and tutorial. ``` +```{note} +When choices are `Enum` members, Click Extra colorizes their `name` attribute (not their `value`), matching [Click's own behavior](types.md#limits-of-click-choice). Use [`EnumChoice`](types.md#enumchoice) if you need user-friendly choice strings based on values or custom representations. +``` + ## Why not use `rich-click`? [`rich-click`](https://github.com/ewels/rich-click) is a good project that aims to integrate [Rich](https://github.com/Textualize/rich) with Click. Like Click Extra, it provides a ready-to-use help formatter for Click. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/click-extra-7.6.0/docs/config.md new/click-extra-7.6.3/docs/config.md --- old/click-extra-7.6.0/docs/config.md 2026-02-26 09:42:28.000000000 +0100 +++ new/click-extra-7.6.3/docs/config.md 2026-03-02 10:52:22.000000000 +0100 @@ -749,8 +749,11 @@ ```{click:run} :emphasize-lines: 6 +from boltons.iterutils import flatten, unique +from click_extra import ConfigFormat result = invoke(cli, args=["--help"]) -assert "~/.cli/{*.toml,*.yaml,*.yml,*.json,*.json5,*.jsonc,*.hjson,*.ini,*.xml,pyproject.toml}]" in result.stdout.replace("\n ", "") +fp = ",".join(unique(flatten(f.patterns for f in ConfigFormat if f.enabled))) +assert f"~/.cli/{{{fp}}}]" in result.stdout.replace("\n ", "") ``` ```{seealso} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/click-extra-7.6.0/docs/version.md new/click-extra-7.6.3/docs/version.md --- old/click-extra-7.6.0/docs/version.md 2026-02-26 09:42:28.000000000 +0100 +++ new/click-extra-7.6.3/docs/version.md 2026-03-02 10:52:22.000000000 +0100 @@ -246,6 +246,10 @@ assert result.output == "\x1b[97mprebaked-cli\x1b[0m, version \x1b[32m1.2.3.dev0+abc1234\x1b[0m\n" ``` +```{hint} +Click Extra ships {meth}`ExtraVersionOption.prebake_version() <click_extra.version.ExtraVersionOption.prebake_version>`, a utility to automate this injection. It parses a Python source file with {mod}`ast`, locates the `__version__` assignment, and appends a `+<local_version>` suffix in place. Call it in your build step before Nuitka/PyInstaller compilation. +``` + ### Version lifecycle The version resolution adapts to the runtime environment: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/click-extra-7.6.0/pyproject.toml new/click-extra-7.6.3/pyproject.toml --- old/click-extra-7.6.0/pyproject.toml 2026-02-26 09:42:28.000000000 +0100 +++ new/click-extra-7.6.3/pyproject.toml 2026-03-02 10:52:22.000000000 +0100 @@ -5,7 +5,7 @@ [project] # Docs: https://packaging.python.org/en/latest/guides/writing-pyproject-toml/ name = "click-extra" -version = "7.6.0" +version = "7.6.3" description = "🌈 Drop-in replacement for Click to make user-friendly and colorful CLI" readme = "readme.md" keywords = [ @@ -180,7 +180,7 @@ [project.urls] "Homepage" = "https://github.com/kdeldycke/click-extra" -"Download" = "https://github.com/kdeldycke/click-extra/releases/tag/v7.6.0" +"Download" = "https://github.com/kdeldycke/click-extra/releases/tag/v7.6.3" "Changelog" = "https://github.com/kdeldycke/click-extra/blob/main/changelog.md" "Issues" = "https://github.com/kdeldycke/click-extra/issues" "Repository" = "https://github.com/kdeldycke/click-extra" @@ -325,7 +325,7 @@ report.precision = 2 [tool.bumpversion] -current_version = "7.6.0" +current_version = "7.6.3" allow_dirty = true ignore_missing_files = true # Parse versions with an optional .devN suffix (PEP 440). diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/click-extra-7.6.0/tests/test_config.py new/click-extra-7.6.3/tests/test_config.py --- old/click-extra-7.6.0/tests/test_config.py 2026-02-26 09:42:28.000000000 +0100 +++ new/click-extra-7.6.3/tests/test_config.py 2026-03-02 10:52:22.000000000 +0100 @@ -25,12 +25,14 @@ import click import pytest +from boltons.iterutils import flatten, unique from boltons.pathutils import shrinkuser from extra_platforms import ( # type: ignore[attr-defined] is_macos, is_unix_not_macos, is_windows, ) +from extra_platforms.pytest import unless_unix_not_macos # type: ignore[attr-defined] from click_extra import ( NO_CONFIG, @@ -392,10 +394,8 @@ line.strip() for line in result.stdout.split("--config CONFIG_PATH")[1].splitlines() ) - assert ( - "{*.toml,*.yaml,*.yml,*.json,*.json5,*.jsonc,*.hjson,*.ini,*.xml,pyproject.toml}]" - in help_screen - ) + fp = ",".join(unique(flatten(f.patterns for f in ConfigFormat if f.enabled))) + assert f"{{{fp}}}]" in help_screen assert not result.stderr assert result.exit_code == 0 @@ -1143,7 +1143,9 @@ [ pytest.param( None, - "*.toml,*.yaml,*.yml,*.json,*.json5,*.jsonc,*.hjson,*.ini,*.xml,pyproject.toml", + ",".join( + unique(flatten(fmt.patterns for fmt in ConfigFormat if fmt.enabled)) + ), id="default_all_formats", ), pytest.param(ConfigFormat.TOML, "*.toml", id="single_format"), @@ -1195,12 +1197,15 @@ ], ) def test_default_pattern_roaming_force_posix( - roaming, force_posix, current_platform, expected_path + roaming, force_posix, current_platform, expected_path, monkeypatch ): """Test that roaming and force_posix affect the default pattern generation.""" if not current_platform: pytest.skip("Platform-specific test.") + # Ensure XDG_CONFIG_HOME doesn't override the default config directory. + monkeypatch.delenv("XDG_CONFIG_HOME", raising=False) + @click.command @config_option(roaming=roaming, force_posix=force_posix) def test_cli(): @@ -1217,6 +1222,33 @@ ) +@unless_unix_not_macos [email protected]("force_posix", [True, False]) +def test_default_pattern_xdg_config_home(force_posix, tmp_path, monkeypatch): + """Test that default_pattern respects XDG_CONFIG_HOME on Linux.""" + custom_config = tmp_path / "custom-config" + custom_config.mkdir() + monkeypatch.setenv("XDG_CONFIG_HOME", str(custom_config)) + + @click.command + @config_option(force_posix=force_posix) + def test_cli(): + pass + + with click.Context(test_cli, info_name="test-cli"): + config_opt = search_params(test_cli.params, ConfigOption) + pattern = config_opt.default_pattern() + + if force_posix: + # force_posix ignores XDG_CONFIG_HOME and uses ~/.test-cli/. + assert pattern.startswith( + str(Path("~/.test-cli").expanduser().resolve()) + ) + else: + # XDG_CONFIG_HOME is resolved into the pattern. + assert pattern.startswith(str(custom_config.resolve() / "test-cli")) + + @pytest.mark.parametrize( ("search_parents", "subdirs", "create_file", "expected_start"), [ @@ -2596,9 +2628,7 @@ def sub(int_param): echo(f"int_parameter = {int_param!r}") - result = invoke( - validate_ps_cli, "--validate-config", str(conf_path), color=False - ) + result = invoke(validate_ps_cli, "--validate-config", str(conf_path), color=False) assert result.exit_code == 0 assert "is valid" in result.stderr diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/click-extra-7.6.0/tests/test_parameters.py new/click-extra-7.6.3/tests/test_parameters.py --- old/click-extra-7.6.0/tests/test_parameters.py 2026-02-26 09:42:28.000000000 +0100 +++ new/click-extra-7.6.3/tests/test_parameters.py 2026-03-02 10:52:22.000000000 +0100 @@ -25,6 +25,7 @@ import click import pytest +from boltons.iterutils import flatten, unique from boltons.strutils import strip_ansi from extra_platforms import is_windows @@ -37,6 +38,7 @@ UNSET, UUID, Choice, + ConfigFormat, DateTime, File, FloatRange, @@ -329,12 +331,12 @@ # On Windows, backslashes are double-escaped in Path string repr. ( f"'{Path(get_app_dir('show-params-cli')).resolve()}{sep}" - "{*.toml,*.yaml,*.yml,*.json,*.json5,*.jsonc,*.hjson,*.ini,*.xml,pyproject.toml}'" + f"{{{','.join(unique(flatten(f.patterns for f in ConfigFormat if f.enabled)))}}}'" ).replace("\\", "\\\\") if is_windows else ( f"'{Path(get_app_dir('show-params-cli')).resolve()}{sep}" - "{*.toml,*.yaml,*.yml,*.json,*.json5,*.jsonc,*.hjson,*.ini,*.xml,pyproject.toml}'" + f"{{{','.join(unique(flatten(f.patterns for f in ConfigFormat if f.enabled)))}}}'" ), repr(str(conf_path)), "COMMANDLINE", diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/click-extra-7.6.0/tests/test_version.py new/click-extra-7.6.3/tests/test_version.py --- old/click-extra-7.6.0/tests/test_version.py 2026-02-26 09:42:28.000000000 +0100 +++ new/click-extra-7.6.3/tests/test_version.py 2026-03-02 10:52:22.000000000 +0100 @@ -91,8 +91,7 @@ default_debug_colored_logging + default_debug_colored_version_details + r"\x1b\[97mdebug-output\x1b\[0m, " - rf"version \x1b\[32m{_ver}\x1b\[0m\n" - + default_debug_colored_log_end + rf"version \x1b\[32m{_ver}\x1b\[0m\n" + default_debug_colored_log_end ), ) @@ -222,7 +221,7 @@ r"module = <module 'click_extra\.testing' from '.+testing\.py'>\n" r"module_name = click_extra\.testing\n" r"module_file = .+testing\.py\n" - rf"module_version = None\n" + r"module_version = None\n" r"package_name = click_extra\n" r"package_version = \S+\n" r"exec_name = click_extra\.testing\n" @@ -340,6 +339,96 @@ assert result.exit_code == 0 +# --- prebake_version tests --- + + [email protected] +def init_file(tmp_path): + """Helper that creates a temporary __init__.py with the given content.""" + + def _make(content: str): + p = tmp_path / "__init__.py" + p.write_text(content, encoding="utf-8") + return p + + return _make + + +def test_prebake_dev_version(init_file): + """A ``.dev`` version gets ``+hash`` appended in the file.""" + p = init_file('__version__ = "1.0.0.dev0"\n') + result = ExtraVersionOption.prebake_version(p, local_version="abc1234") + assert result == "1.0.0.dev0+abc1234" + assert '__version__ = "1.0.0.dev0+abc1234"' in p.read_text() + + +def test_prebake_single_quotes(init_file): + """Single-quoted ``__version__`` is also handled.""" + p = init_file("__version__ = '2.0.0.dev5'\n") + result = ExtraVersionOption.prebake_version(p, local_version="f00baa") + assert result == "2.0.0.dev5+f00baa" + assert "__version__ = '2.0.0.dev5+f00baa'" in p.read_text() + + +def test_prebake_already_baked_skipped(init_file): + """A version with existing ``+`` is left untouched.""" + p = init_file('__version__ = "1.0.0.dev0+existing"\n') + result = ExtraVersionOption.prebake_version(p, local_version="abc1234") + assert result is None + assert '__version__ = "1.0.0.dev0+existing"' in p.read_text() + + +def test_prebake_release_skipped(init_file): + """A release version (no ``.dev``) is not modified.""" + p = init_file('__version__ = "3.2.1"\n') + result = ExtraVersionOption.prebake_version(p, local_version="abc1234") + assert result is None + assert '__version__ = "3.2.1"' in p.read_text() + + +def test_prebake_no_version_in_file(init_file): + """A file without ``__version__`` returns ``None``.""" + p = init_file('"""Just a docstring."""\n') + result = ExtraVersionOption.prebake_version(p, local_version="abc1234") + assert result is None + + +def test_prebake_missing_local_version_raises(init_file): + """Calling without ``local_version`` raises ``TypeError``.""" + p = init_file('__version__ = "1.0.0.dev0"\n') + with pytest.raises(TypeError): + ExtraVersionOption.prebake_version(p) + + +def test_prebake_idempotent(init_file): + """Running prebake twice does not double-suffix.""" + p = init_file('__version__ = "1.0.0.dev0"\n') + first = ExtraVersionOption.prebake_version(p, local_version="abc1234") + assert first == "1.0.0.dev0+abc1234" + second = ExtraVersionOption.prebake_version(p, local_version="def5678") + assert second is None + assert '__version__ = "1.0.0.dev0+abc1234"' in p.read_text() + + +def test_prebake_preserves_surrounding_content(init_file): + """Content around ``__version__`` is not disturbed.""" + content = ( + '"""My package."""\n' + "\n" + "from __future__ import annotations\n" + "\n" + '__version__ = "4.0.0.dev0"\n' + "\n" + "API_URL = 'https://example.com'\n" + ) + p = init_file(content) + ExtraVersionOption.prebake_version(p, local_version="cafe123") + result = p.read_text() + assert '__version__ = "4.0.0.dev0+cafe123"' in result + assert "from __future__ import annotations" in result + assert "API_URL = 'https://example.com'" in result + + def __test_inplace_context(): @click.command @version_option diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/click-extra-7.6.0/uv.lock new/click-extra-7.6.3/uv.lock --- old/click-extra-7.6.0/uv.lock 2026-02-26 09:42:28.000000000 +0100 +++ new/click-extra-7.6.3/uv.lock 2026-03-02 10:52:22.000000000 +0100 @@ -9,7 +9,7 @@ ] [options] -exclude-newer = "2026-02-17T06:20:34.657648Z" +exclude-newer = "2026-02-20T15:19:31.896200888Z" exclude-newer-span = "P1W" [[package]] @@ -194,7 +194,7 @@ [[package]] name = "click-extra" -version = "7.6.0.dev0" +version = "7.6.3.dev0" source = { editable = "." } dependencies = [ { name = "boltons" }, @@ -532,7 +532,7 @@ version = "1.3.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "typing-extensions", marker = "python_full_version < '3.13'" }, + { name = "typing-extensions", marker = "python_full_version < '3.11'" }, ] sdist = { url = "https://files.pythonhosted.org/packages/50/79/66800aadf48771f6b62f7eb014e352e5d06856655206165d775e675a02c9/exceptiongroup-1.3.1.tar.gz", hash = "sha256:8b412432c6055b0b7d14c310000ae93352ed6754f70fa8f7c34141f91c4e3219", size = 30371, upload-time = "2025-11-21T23:01:54.787Z" } wheels = [
