Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package python-hatch for openSUSE:Factory checked in at 2026-05-27 16:14:10 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/python-hatch (Old) and /work/SRC/openSUSE:Factory/.python-hatch.new.1937 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-hatch" Wed May 27 16:14:10 2026 rev:26 rq:1355147 version:1.16.5 Changes: -------- --- /work/SRC/openSUSE:Factory/python-hatch/python-hatch.changes 2026-02-13 13:58:35.166810131 +0100 +++ /work/SRC/openSUSE:Factory/.python-hatch.new.1937/python-hatch.changes 2026-05-27 16:14:29.210825003 +0200 @@ -1,0 +2,13 @@ +Mon May 25 09:00:32 UTC 2026 - Markéta Machová <[email protected]> + +- Update to 1.16.5 + * Fixes hatch shell type error for keep_env. + * SBOM documentation for including SBOM files in sdist + * Fixes workspace member detection to properly handle shared path + prefixes. + * Handle a breaking change in virtualenv by only supporting the + latest version and adding python-discovery as a dependency. +- Add fix-pth-editables06.patch to fix test failure +- Drop upstream shell.patch and packaging26.patch + +------------------------------------------------------------------- Old: ---- hatch-v1.16.3.tar.gz packaging26.patch shell.patch New: ---- fix-pth-editables06.patch hatch-v1.16.5.tar.gz ----------(Old B)---------- Old:- Add fix-pth-editables06.patch to fix test failure - Drop upstream shell.patch and packaging26.patch Old:- Add fix-pth-editables06.patch to fix test failure - Drop upstream shell.patch and packaging26.patch ----------(Old E)---------- ----------(New B)---------- New: latest version and adding python-discovery as a dependency. - Add fix-pth-editables06.patch to fix test failure - Drop upstream shell.patch and packaging26.patch ----------(New E)---------- ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ python-hatch.spec ++++++ --- /var/tmp/diff_new_pack.nenGqA/_old 2026-05-27 16:14:30.390873619 +0200 +++ /var/tmp/diff_new_pack.nenGqA/_new 2026-05-27 16:14:30.390873619 +0200 @@ -31,7 +31,7 @@ %endif %{?sle15_python_module_pythons} Name: python-hatch%{psuffix} -Version: 1.16.3 +Version: 1.16.5 Release: 0 Summary: Modern, extensible Python project management License: MIT @@ -53,10 +53,8 @@ Source22: https://files.pythonhosted.org/packages/py3/s/setuptools/setuptools-80.9.0-py3-none-any.whl Source23: https://files.pythonhosted.org/packages/py3/t/trove_classifiers/trove_classifiers-2025.12.1.14-py3-none-any.whl Source24: https://files.pythonhosted.org/packages/py3/u/urllib3/urllib3-2.6.2-py3-none-any.whl -# PATCH-FIX-UPSTREAM https://github.com/pypa/hatch/pull/2165 keep_env TypeError -Patch0: shell.patch -# PATCH-FIX-UPSTREAM https://github.com/pypa/hatch/pull/2159 Fix warning and tests with packaging 26.0 -Patch1: packaging26.patch +# PATCH-FIX-UPSTREAM https://github.com/pypa/hatch/pull/2248 Update editable-exact test templates for editables 0.6 .pth file rename +Patch0: fix-pth-editables06.patch BuildRequires: %{python_module base >= 3.10} BuildRequires: %{python_module hatch-vcs >= 0.3} BuildRequires: %{python_module hatchling >= 1.27} @@ -72,12 +70,13 @@ Requires: python-packaging >= 24.2 Requires: python-platformdirs >= 2.5.0 Requires: python-pyproject-hooks +Requires: python-python-discovery >= 1.1 Requires: python-rich >= 11.2.0 Requires: python-shellingham >= 1.4.0 Requires: python-tomli-w >= 1.0 Requires: python-tomlkit >= 0.11.1 Requires: python-uv >= 0.5.23 -Requires: python-virtualenv >= 20.26.1 +Requires: python-virtualenv >= 21 Requires: (python-backports.zstd > 1 if python-base < 3.14) Requires: (python-pexpect >= 4.8 with python-pexpect < 5) Requires: (python-userpath >= 1.7 with python-userpath < 2) ++++++ fix-pth-editables06.patch ++++++ >From 34dba22e5e3c7b7468b67f53f93b7340e54609b8 Mon Sep 17 00:00:00 2001 From: Cary Hawkins <[email protected]> Date: Thu, 23 Apr 2026 00:41:48 -0400 Subject: [PATCH] Annotate relevant_config as dict[str, Any] to prevent mypy from narrowing its key type and rejecting valid "dirs" access (#2248) * Annotate relevant_config as dict[str, Any] to prevent mypy from narrowing its key type and rejecting valid "dirs" access * Update editable-exact test templates for editables 0.6 .pth file rename * Fix tests impacted by pth name changes in editables release --- src/hatch/cli/self/report.py | 4 ++-- tests/backend/builders/test_wheel.py | 1 + tests/helpers/templates/wheel/standard_editable_exact.py | 2 +- .../wheel/standard_editable_exact_extra_dependencies.py | 2 +- .../templates/wheel/standard_editable_exact_force_include.py | 2 +- tests/helpers/templates/wheel/standard_editable_pth.py | 2 +- .../wheel/standard_editable_pth_extra_dependencies.py | 2 +- .../templates/wheel/standard_editable_pth_force_include.py | 2 +- 8 files changed, 9 insertions(+), 8 deletions(-) diff --git a/src/hatch/cli/self/report.py b/src/hatch/cli/self/report.py index 49fe79b45..925ef83af 100644 --- a/src/hatch/cli/self/report.py +++ b/src/hatch/cli/self/report.py @@ -1,6 +1,6 @@ from __future__ import annotations -from typing import TYPE_CHECKING +from typing import TYPE_CHECKING, Any import click @@ -80,7 +80,7 @@ def report(app: Application, *, no_open: bool) -> None: # Retain the config that would be most useful full_config = load_toml_data(app.config_file.read_scrubbed()) - relevant_config = {} + relevant_config: dict[str, Any] = {} for setting in ("mode", "shell"): if setting in full_config: relevant_config[setting] = full_config[setting] diff --git a/tests/backend/builders/test_wheel.py b/tests/backend/builders/test_wheel.py index eeada10d0..28b98456f 100644 --- a/tests/backend/builders/test_wheel.py +++ b/tests/backend/builders/test_wheel.py @@ -3224,6 +3224,7 @@ def test_editable_pth(self, hatch, helpers, temp_dir): project_name, metadata_directory=metadata_directory, package_paths=[str(project_path)], + pth_file_name=f"_{builder.metadata.core.name.replace('-', '_')}.pth", ) helpers.assert_files(extraction_directory, expected_files) diff --git a/tests/helpers/templates/wheel/standard_editable_exact.py b/tests/helpers/templates/wheel/standard_editable_exact.py index 491be227d..442d92230 100644 --- a/tests/helpers/templates/wheel/standard_editable_exact.py +++ b/tests/helpers/templates/wheel/standard_editable_exact.py @@ -17,7 +17,7 @@ def get_files(**kwargs): if str(f.path) == "LICENSE.txt" ] - pth_file_name = f"_{kwargs['package_name']}.pth" + pth_file_name = f"_editable_impl_{kwargs['package_name']}.pth" loader_file_name = f"_editable_impl_{kwargs['package_name']}.py" files.extend(( File(Path(pth_file_name), f"import _editable_impl_{kwargs['package_name']}"), diff --git a/tests/helpers/templates/wheel/standard_editable_exact_extra_dependencies.py b/tests/helpers/templates/wheel/standard_editable_exact_extra_dependencies.py index 817a643eb..6a4158828 100644 --- a/tests/helpers/templates/wheel/standard_editable_exact_extra_dependencies.py +++ b/tests/helpers/templates/wheel/standard_editable_exact_extra_dependencies.py @@ -17,7 +17,7 @@ def get_files(**kwargs): if str(f.path) == "LICENSE.txt" ] - pth_file_name = f"_{kwargs['package_name']}.pth" + pth_file_name = f"_editable_impl_{kwargs['package_name']}.pth" loader_file_name = f"_editable_impl_{kwargs['package_name']}.py" files.extend(( File(Path(pth_file_name), f"import _editable_impl_{kwargs['package_name']}"), diff --git a/tests/helpers/templates/wheel/standard_editable_exact_force_include.py b/tests/helpers/templates/wheel/standard_editable_exact_force_include.py index e9de6159c..72bf7a58f 100644 --- a/tests/helpers/templates/wheel/standard_editable_exact_force_include.py +++ b/tests/helpers/templates/wheel/standard_editable_exact_force_include.py @@ -18,7 +18,7 @@ def get_files(**kwargs): elif f.path.parts[-1] == "__about__.py": files.append(File(Path("zfoo.py"), f.contents)) - pth_file_name = f"_{kwargs['package_name']}.pth" + pth_file_name = f"_editable_impl_{kwargs['package_name']}.pth" loader_file_name = f"_editable_impl_{kwargs['package_name']}.py" files.extend(( File(Path(pth_file_name), f"import _editable_impl_{kwargs['package_name']}"), diff --git a/tests/helpers/templates/wheel/standard_editable_pth.py b/tests/helpers/templates/wheel/standard_editable_pth.py index 5a170cc6a..c78915cf6 100644 --- a/tests/helpers/templates/wheel/standard_editable_pth.py +++ b/tests/helpers/templates/wheel/standard_editable_pth.py @@ -17,7 +17,7 @@ def get_files(**kwargs): if str(f.path) == "LICENSE.txt" ] - pth_file_name = f"_{kwargs['package_name']}.pth" + pth_file_name = kwargs.get("pth_file_name", f"_editable_impl_{kwargs['package_name']}.pth") files.extend(( File(Path(pth_file_name), "\n".join(package_paths)), File( diff --git a/tests/helpers/templates/wheel/standard_editable_pth_extra_dependencies.py b/tests/helpers/templates/wheel/standard_editable_pth_extra_dependencies.py index 834383259..cdc9f2ea9 100644 --- a/tests/helpers/templates/wheel/standard_editable_pth_extra_dependencies.py +++ b/tests/helpers/templates/wheel/standard_editable_pth_extra_dependencies.py @@ -17,7 +17,7 @@ def get_files(**kwargs): if str(f.path) == "LICENSE.txt" ] - pth_file_name = f"_{kwargs['package_name']}.pth" + pth_file_name = kwargs.get("pth_file_name", f"_editable_impl_{kwargs['package_name']}.pth") files.extend(( File(Path(pth_file_name), "\n".join(package_paths)), File( diff --git a/tests/helpers/templates/wheel/standard_editable_pth_force_include.py b/tests/helpers/templates/wheel/standard_editable_pth_force_include.py index 003954027..00e0af96a 100644 --- a/tests/helpers/templates/wheel/standard_editable_pth_force_include.py +++ b/tests/helpers/templates/wheel/standard_editable_pth_force_include.py @@ -18,7 +18,7 @@ def get_files(**kwargs): elif f.path.parts[-1] == "__about__.py": files.append(File(Path("zfoo.py"), f.contents)) - pth_file_name = f"_{kwargs['package_name']}.pth" + pth_file_name = kwargs.get("pth_file_name", f"_editable_impl_{kwargs['package_name']}.pth") files.extend(( File(Path(pth_file_name), "\n".join(package_paths)), File( ++++++ hatch-v1.16.3.tar.gz -> hatch-v1.16.5.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hatch-hatch-v1.16.3/.github/workflows/build-hatch.yml new/hatch-hatch-v1.16.5/.github/workflows/build-hatch.yml --- old/hatch-hatch-v1.16.3/.github/workflows/build-hatch.yml 2026-01-21 02:32:44.000000000 +0100 +++ new/hatch-hatch-v1.16.5/.github/workflows/build-hatch.yml 2026-02-27 18:59:39.000000000 +0100 @@ -582,7 +582,7 @@ path: installers merge-multiple: true - - name: Add assets to current release + - name: Add assets to draft release uses: softprops/action-gh-release@v2 with: files: |- diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hatch-hatch-v1.16.3/.github/workflows/build-hatchling.yml new/hatch-hatch-v1.16.5/.github/workflows/build-hatchling.yml --- old/hatch-hatch-v1.16.3/.github/workflows/build-hatchling.yml 2026-01-21 02:32:44.000000000 +0100 +++ new/hatch-hatch-v1.16.5/.github/workflows/build-hatchling.yml 2026-02-27 18:59:39.000000000 +0100 @@ -43,6 +43,7 @@ runs-on: ubuntu-latest permissions: + contents: write id-token: write steps: @@ -55,3 +56,8 @@ uses: pypa/[email protected] with: skip-existing: true + + - name: Add assets to draft release + uses: softprops/action-gh-release@v2 + with: + files: dist/* diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hatch-hatch-v1.16.3/backend/src/hatchling/__about__.py new/hatch-hatch-v1.16.5/backend/src/hatchling/__about__.py --- old/hatch-hatch-v1.16.3/backend/src/hatchling/__about__.py 2026-01-21 02:32:44.000000000 +0100 +++ new/hatch-hatch-v1.16.5/backend/src/hatchling/__about__.py 2026-02-27 18:59:39.000000000 +0100 @@ -1 +1 @@ -__version__ = "1.28.0" +__version__ = "1.29.0" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hatch-hatch-v1.16.3/backend/src/hatchling/builders/wheel.py new/hatch-hatch-v1.16.5/backend/src/hatchling/builders/wheel.py --- old/hatch-hatch-v1.16.3/backend/src/hatchling/builders/wheel.py 2026-01-21 02:32:44.000000000 +0100 +++ new/hatch-hatch-v1.16.5/backend/src/hatchling/builders/wheel.py 2026-02-27 18:59:39.000000000 +0100 @@ -88,7 +88,9 @@ def get_reproducible_time_tuple() -> TIME_TUPLE: from datetime import datetime, timezone - d = datetime.fromtimestamp(get_reproducible_timestamp(), timezone.utc) + # `zipfile.ZipInfo` does not support timestamps before 1980 + min_ts = 315532800 # 1980-01-01T00:00:00Z + d = datetime.fromtimestamp(max(get_reproducible_timestamp(), min_ts), timezone.utc) return d.year, d.month, d.day, d.hour, d.minute, d.second def add_file(self, included_file: IncludedFile) -> tuple[str, str, str]: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hatch-hatch-v1.16.3/backend/src/hatchling/version/scheme/standard.py new/hatch-hatch-v1.16.5/backend/src/hatchling/version/scheme/standard.py --- old/hatch-hatch-v1.16.3/backend/src/hatchling/version/scheme/standard.py 2026-01-21 02:32:44.000000000 +0100 +++ new/hatch-hatch-v1.16.5/backend/src/hatchling/version/scheme/standard.py 2026-02-27 18:59:39.000000000 +0100 @@ -1,6 +1,6 @@ from __future__ import annotations -from typing import TYPE_CHECKING, Any, cast +from typing import TYPE_CHECKING, Any, Literal, cast from hatchling.version.scheme.plugin.interface import VersionSchemeInterface @@ -28,13 +28,15 @@ for version in versions: if version == "release": - reset_version_parts(original, release=original.release) + original = reset_version_parts(original, release=original.release) elif version == "major": - reset_version_parts(original, release=update_release(original, [original.major + 1])) + original = reset_version_parts(original, release=update_release(original, [original.major + 1])) elif version == "minor": - reset_version_parts(original, release=update_release(original, [original.major, original.minor + 1])) + original = reset_version_parts( + original, release=update_release(original, [original.major, original.minor + 1]) + ) elif version in {"micro", "patch", "fix"}: - reset_version_parts( + original = reset_version_parts( original, release=update_release(original, [original.major, original.minor, original.micro + 1]) ) elif version in {"a", "b", "c", "rc", "alpha", "beta", "pre", "preview"}: @@ -44,13 +46,13 @@ if phase == current_phase: number = current_number + 1 - reset_version_parts(original, pre=(phase, number)) + original = reset_version_parts(original, pre=(phase, number)) elif version in {"post", "rev", "r"}: number = 0 if original.post is None else original.post + 1 - reset_version_parts(original, post=parse_letter_version(version, number)) + original = reset_version_parts(original, post=number) elif version == "dev": number = 0 if original.dev is None else original.dev + 1 - reset_version_parts(original, dev=(version, number)) + original = reset_version_parts(original, dev=number) else: if len(versions) > 1: message = "Cannot specify multiple update operations with an explicit version" @@ -66,9 +68,13 @@ return str(original) -def reset_version_parts(version: Version, **kwargs: Any) -> None: - # https://github.com/pypa/packaging/blob/20.9/packaging/version.py#L301-L310 - internal_version = version._version # noqa: SLF001 +def reset_version_parts(version: Version, **kwargs: Any) -> Version: + """ + Update version parts and clear all subsequent parts in the sequence. + + When __replace__ is available (packaging 26.0+), returns a new Version instance. + Otherwise mutates version via private ._version and returns the same instance. + """ parts: dict[str, Any] = {} ordered_part_names = ("epoch", "release", "pre", "post", "dev", "local") @@ -80,9 +86,16 @@ parts[part_name] = kwargs[part_name] reset = True else: - parts[part_name] = getattr(internal_version, part_name) + parts[part_name] = getattr(version, part_name) + + # Use __replace__ if available for efficiency + if hasattr(version, "__replace__"): + return version.__replace__(**parts) + # Reference: https://github.com/pypa/packaging/blob/20.9/packaging/version.py#L301-L310 + internal_version = version._version # noqa: SLF001 version._version = type(internal_version)(**parts) # noqa: SLF001 + return version def update_release(original_version: Version, new_release_parts: list[int]) -> tuple[int, ...]: @@ -92,7 +105,7 @@ return tuple(new_release_parts) -def parse_letter_version(*args: Any, **kwargs: Any) -> tuple[str, int]: +def parse_letter_version(*args: Any, **kwargs: Any) -> tuple[Literal["a", "b", "rc"], int]: from packaging.version import _parse_letter_version # noqa: PLC2701 - return cast(tuple[str, int], _parse_letter_version(*args, **kwargs)) + return cast(tuple[Literal["a", "b", "rc"], int], _parse_letter_version(*args, **kwargs)) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hatch-hatch-v1.16.3/backend/tests/downstream/requirements.txt new/hatch-hatch-v1.16.5/backend/tests/downstream/requirements.txt --- old/hatch-hatch-v1.16.3/backend/tests/downstream/requirements.txt 2026-01-21 02:32:44.000000000 +0100 +++ new/hatch-hatch-v1.16.5/backend/tests/downstream/requirements.txt 2026-02-27 18:59:39.000000000 +0100 @@ -2,4 +2,4 @@ packaging requests tomli -virtualenv>=20.13.1 +virtualenv>=21 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hatch-hatch-v1.16.3/docs/history/hatch.md new/hatch-hatch-v1.16.5/docs/history/hatch.md --- old/hatch-hatch-v1.16.3/docs/history/hatch.md 2026-01-21 02:32:44.000000000 +0100 +++ new/hatch-hatch-v1.16.5/docs/history/hatch.md 2026-02-27 18:59:39.000000000 +0100 @@ -8,6 +8,20 @@ ## Unreleased +## [1.16.5](https://github.com/pypa/hatch/releases/tag/hatch-v1.16.5) - 2026-02-26 ## {: #hatch-v1.16.5 } + +***Fixed:*** + +- Handle a breaking change in `virtualenv` by only supporting the latest version and adding `python-discovery` as a dependency. + +## [1.16.4](https://github.com/pypa/hatch/releases/tag/hatch-v1.16.4) - 2026-02-23 ## {: #hatch-v1.16.4 } + +***Fixed:*** + +- Fixes hatch shell type error for keep_env. +- SBOM documentation for including SBOM files in `sdist` +- Fixes workspace member detection to properly handle shared path prefixes. + ## [1.16.3](https://github.com/pypa/hatch/releases/tag/hatch-v1.16.3) - 2026-01-20 ## {: #hatch-v1.16.3 } ***Added:*** @@ -16,10 +30,10 @@ ***Fixed:*** -- Fix issue with self-referential dependencies not being recognized. +- Fix issue with self-referential dependencies not being recognized. - Fix incomplete environments created when an exception occurs during creation. -- Fix dependency-groups not working with when environment is not marked as builder. -- Change Keyring to take expect repository URL instead of repository name. +- Fix dependency-groups not working with when environment is not marked as builder. +- Change Keyring to take expect repository URL instead of repository name. ## [1.16.2](https://github.com/pypa/hatch/releases/tag/hatch-v1.16.2) - 2025-12-06 ## {: #hatch-v1.16.2 } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hatch-hatch-v1.16.3/docs/history/hatchling.md new/hatch-hatch-v1.16.5/docs/history/hatchling.md --- old/hatch-hatch-v1.16.3/docs/history/hatchling.md 2026-01-21 02:32:44.000000000 +0100 +++ new/hatch-hatch-v1.16.5/docs/history/hatchling.md 2026-02-27 18:59:39.000000000 +0100 @@ -8,6 +8,12 @@ ## Unreleased +## [1.29.0](https://github.com/pypa/hatch/releases/tag/hatchling-v1.29.0) - 2026-02-21 ## {: #hatchling-v1.29.0 } + +***Fixed:*** + +- Source Date Epoch no longer fails when set to date before 1980. + ## [1.28.0](https://github.com/pypa/hatch/releases/tag/hatchling-v1.28.0) - 2025-11-26 ## {: #hatchling-v1.28.0 } ***Changed:*** diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hatch-hatch-v1.16.3/docs/plugins/builder/wheel.md new/hatch-hatch-v1.16.5/docs/plugins/builder/wheel.md --- old/hatch-hatch-v1.16.3/docs/plugins/builder/wheel.md 2026-01-21 02:32:44.000000000 +0100 +++ new/hatch-hatch-v1.16.5/docs/plugins/builder/wheel.md 2026-02-27 18:59:39.000000000 +0100 @@ -25,6 +25,8 @@ | `bypass-selection` | `false` | Whether or not to suppress the error when one has not defined any file selection options and all heuristics have failed to determine what to ship | | `sbom-files` | | A list of paths to [Software Bill of Materials](https://peps.python.org/pep-0770/) files that will be included in the `.dist-info/sboms/` directory of the wheel | +!!! note + Many build frontends will build the wheel from a source distribution. This is the recommended approach, but it means you need to ensure the SBOM files passed to `sbom-files` are also [included in the source distribution](https://hatch.pypa.io/latest/config/build/#file-selection). ## Versions diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hatch-hatch-v1.16.3/pyproject.toml new/hatch-hatch-v1.16.5/pyproject.toml --- old/hatch-hatch-v1.16.3/pyproject.toml 2026-01-21 02:32:44.000000000 +0100 +++ new/hatch-hatch-v1.16.5/pyproject.toml 2026-02-27 18:59:39.000000000 +0100 @@ -46,6 +46,7 @@ "keyring>=23.5.0", "packaging>=24.2", "pexpect~=4.8", + "python-discovery>=1.1", "platformdirs>=2.5.0", "pyproject-hooks", "rich>=11.2.0", @@ -54,7 +55,7 @@ "tomlkit>=0.11.1", "userpath~=1.7", "uv>=0.5.23", - "virtualenv>=20.26.6", + "virtualenv>=21", "backports.zstd>=1.0.0 ; python_version<'3.14'", ] dynamic = ["version"] diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hatch-hatch-v1.16.3/scripts/release_github.py new/hatch-hatch-v1.16.5/scripts/release_github.py --- old/hatch-hatch-v1.16.3/scripts/release_github.py 2026-01-21 02:32:44.000000000 +0100 +++ new/hatch-hatch-v1.16.5/scripts/release_github.py 2026-02-27 18:59:39.000000000 +0100 @@ -1,4 +1,6 @@ import argparse +import subprocess +import sys import webbrowser from urllib.parse import urlencode @@ -11,11 +13,23 @@ args = parser.parse_args() version, notes = get_latest_release(args.project) + tag = f"{args.project}-v{version}" + # Create and push tag first + try: + subprocess.run(["git", "tag", tag], check=True) # noqa: S607 + subprocess.run(["git", "push", "origin", tag], check=True) # noqa: S607 + print(f"Created and pushed tag: {tag}") + except subprocess.CalledProcessError as e: + print(f"Error creating tag: {e}") + sys.exit(1) + + # Open GitHub UI to create draft release params = urlencode({ "title": f"{args.project.capitalize()} v{version}", - "tag": f"{args.project}-v{version}", + "tag": tag, "body": notes, + "draft": "true", }) url = f"https://github.com/pypa/hatch/releases/new?{params}" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hatch-hatch-v1.16.3/src/hatch/cli/shell/__init__.py new/hatch-hatch-v1.16.5/src/hatch/cli/shell/__init__.py --- old/hatch-hatch-v1.16.3/src/hatch/cli/shell/__init__.py 2026-01-21 02:32:44.000000000 +0100 +++ new/hatch-hatch-v1.16.5/src/hatch/cli/shell/__init__.py 2026-02-27 18:59:39.000000000 +0100 @@ -1,9 +1,12 @@ from __future__ import annotations +import os from typing import TYPE_CHECKING import click +from hatch.config.constants import AppEnvVars + if TYPE_CHECKING: from hatch.cli.application import Application @@ -42,7 +45,7 @@ with app.project.ensure_cwd(): environment = app.project.get_environment(chosen_env) - app.project.prepare_environment(environment) + app.project.prepare_environment(environment, keep_env=bool(os.environ.get(AppEnvVars.KEEP_ENV))) first_run_indicator = app.cache_dir / "shell" / "first_run" if not first_run_indicator.is_file(): diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hatch-hatch-v1.16.3/src/hatch/env/plugin/interface.py new/hatch-hatch-v1.16.5/src/hatch/env/plugin/interface.py --- old/hatch-hatch-v1.16.3/src/hatch/env/plugin/interface.py 2026-01-21 02:32:44.000000000 +0100 +++ new/hatch-hatch-v1.16.5/src/hatch/env/plugin/interface.py 2026-02-27 18:59:39.000000000 +0100 @@ -1238,7 +1238,7 @@ path_spec = data["path"] normalized_path = os.path.normpath(os.path.join(root, path_spec)) absolute_path = os.path.abspath(normalized_path) - shared_prefix = os.path.commonprefix([root, absolute_path]) + shared_prefix = os.path.commonpath([root, absolute_path]) relative_path = os.path.relpath(absolute_path, shared_prefix) # Now we have the necessary information to perform an optimized glob search for members diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hatch-hatch-v1.16.3/src/hatch/env/virtual.py new/hatch-hatch-v1.16.5/src/hatch/env/virtual.py --- old/hatch-hatch-v1.16.3/src/hatch/env/virtual.py 2026-01-21 02:32:44.000000000 +0100 +++ new/hatch-hatch-v1.16.5/src/hatch/env/virtual.py 2026-02-27 18:59:39.000000000 +0100 @@ -22,7 +22,7 @@ from collections.abc import Callable, Iterable from packaging.specifiers import SpecifierSet - from virtualenv.discovery.py_info import PythonInfo + from python_discovery import PythonInfo from hatch.dep.core import Dependency from hatch.dep.sync import InstalledDistributions @@ -334,7 +334,7 @@ def _interpreter_is_compatible(self, interpreter: PythonInfo) -> bool: return ( - interpreter.executable + interpreter.executable is not None and self._is_stable_path(interpreter.executable) and (self.skip_install or self._python_constraint.contains(interpreter.version_str)) ) @@ -376,26 +376,12 @@ return None def _find_existing_interpreter(self, python_version: str = "") -> str | None: - from virtualenv.discovery import builtin as virtualenv_discovery + import python_discovery - propose_interpreters = virtualenv_discovery.propose_interpreters - - def _patched_propose_interpreters(*args, **kwargs): - for interpreter, impl_must_match in propose_interpreters(*args, **kwargs): - if not self._interpreter_is_compatible(interpreter): - continue - - yield interpreter, impl_must_match - - virtualenv_discovery.propose_interpreters = _patched_propose_interpreters - try: - python_info = virtualenv_discovery.get_interpreter( - python_version, (), env=self.get_interpreter_resolver_env() - ) - if python_info is not None: - return python_info.executable - finally: - virtualenv_discovery.propose_interpreters = propose_interpreters + python_info = python_discovery.get_interpreter( + python_version, (), env=self.get_interpreter_resolver_env(), predicate=self._interpreter_is_compatible + ) + return None if python_info is None else python_info.executable def _get_available_distribution(self, python_version: str = "") -> str | None: from hatch.python.resolve import get_compatible_distributions diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hatch-hatch-v1.16.3/tests/backend/builders/test_wheel.py new/hatch-hatch-v1.16.5/tests/backend/builders/test_wheel.py --- old/hatch-hatch-v1.16.3/tests/backend/builders/test_wheel.py 2026-01-21 02:32:44.000000000 +0100 +++ new/hatch-hatch-v1.16.5/tests/backend/builders/test_wheel.py 2026-02-27 18:59:39.000000000 +0100 @@ -786,7 +786,14 @@ zip_info = zip_archive.getinfo(f"{metadata_directory}/WHEEL") assert zip_info.date_time == (2020, 2, 2, 0, 0, 0) - def test_default_reproducible_timestamp(self, hatch, helpers, temp_dir, config_file): + @pytest.mark.parametrize( + ("epoch", "expected_date_time"), + [ + ("0", (1980, 1, 1, 0, 0, 0)), + ("1580601700", (2020, 2, 2, 0, 1, 40)), + ], + ) + def test_default_reproducible_timestamp(self, hatch, helpers, temp_dir, config_file, epoch, expected_date_time): config_file.model.template.plugins["default"]["src-layout"] = False config_file.save() @@ -812,7 +819,7 @@ build_path = project_path / "dist" build_path.mkdir() - with project_path.as_cwd(env_vars={"SOURCE_DATE_EPOCH": "1580601700"}): + with project_path.as_cwd(env_vars={"SOURCE_DATE_EPOCH": epoch}): artifacts = list(builder.build(directory=str(build_path))) assert len(artifacts) == 1 @@ -837,7 +844,7 @@ with zipfile.ZipFile(str(expected_artifact), "r") as zip_archive: zip_info = zip_archive.getinfo(f"{metadata_directory}/WHEEL") - assert zip_info.date_time == (2020, 2, 2, 0, 1, 40) + assert zip_info.date_time == expected_date_time def test_default_no_reproducible(self, hatch, helpers, temp_dir, config_file): config_file.model.template.plugins["default"]["src-layout"] = False diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hatch-hatch-v1.16.3/tests/backend/metadata/test_core.py new/hatch-hatch-v1.16.5/tests/backend/metadata/test_core.py --- old/hatch-hatch-v1.16.3/tests/backend/metadata/test_core.py 2026-01-21 02:32:44.000000000 +0100 +++ new/hatch-hatch-v1.16.5/tests/backend/metadata/test_core.py 2026-02-27 18:59:39.000000000 +0100 @@ -1163,7 +1163,7 @@ }, ) - assert metadata.core.dependencies == ["proj@ git+https://github.com/org/proj.git@v1"] + assert metadata.core.dependencies == ["proj @ git+https://github.com/org/proj.git@v1"] def test_context_formatting(self, isolation, uri_slash_prefix): metadata = ProjectMetadata( @@ -1176,7 +1176,7 @@ ) normalized_path = str(isolation).replace("\\", "/") - assert metadata.core.dependencies == [f"proj@ file:{uri_slash_prefix}{normalized_path}"] + assert metadata.core.dependencies == [f"proj @ file:{uri_slash_prefix}{normalized_path}"] def test_correct(self, isolation): metadata = ProjectMetadata( @@ -1343,7 +1343,7 @@ ) normalized_path = str(isolation).replace("\\", "/") - assert metadata.core.optional_dependencies == {"foo": [f"proj@ file:{uri_slash_prefix}{normalized_path}"]} + assert metadata.core.optional_dependencies == {"foo": [f"proj @ file:{uri_slash_prefix}{normalized_path}"]} def test_direct_reference_allowed(self, isolation): metadata = ProjectMetadata( @@ -1358,7 +1358,7 @@ }, ) - assert metadata.core.optional_dependencies == {"foo": ["proj@ git+https://github.com/org/proj.git@v1"]} + assert metadata.core.optional_dependencies == {"foo": ["proj @ git+https://github.com/org/proj.git@v1"]} def test_correct(self, isolation): metadata = ProjectMetadata( diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hatch-hatch-v1.16.3/tests/backend/metadata/test_spec.py new/hatch-hatch-v1.16.5/tests/backend/metadata/test_spec.py --- old/hatch-hatch-v1.16.3/tests/backend/metadata/test_spec.py 2026-01-21 02:32:44.000000000 +0100 +++ new/hatch-hatch-v1.16.5/tests/backend/metadata/test_spec.py 2026-02-27 18:59:39.000000000 +0100 @@ -216,7 +216,7 @@ Requires-Dist: bar==5; extra == 'feature2' Requires-Dist: foo==1; (python_version < '3') and extra == 'feature2' Provides-Extra: feature3 -Requires-Dist: baz@ file:///path/to/project ; extra == 'feature3' +Requires-Dist: baz @ file:///path/to/project ; extra == 'feature3' """ assert project_metadata_from_core_metadata(core_metadata) == { "name": "My.App", @@ -225,7 +225,7 @@ "optional-dependencies": { "feature1": ['bar==5; python_version < "3"', "foo==1"], "feature2": ["bar==5", 'foo==1; python_version < "3"'], - "feature3": ["baz@ file:///path/to/project"], + "feature3": ["baz @ file:///path/to/project"], }, } @@ -990,7 +990,7 @@ Requires-Dist: bar==5; extra == 'feature2' Requires-Dist: foo==1; (python_version < '3') and extra == 'feature2' Provides-Extra: feature3 - Requires-Dist: baz@ file:///path/to/project ; extra == 'feature3' + Requires-Dist: baz @ file:///path/to/project ; extra == 'feature3' Description-Content-Type: text/markdown test content @@ -1459,7 +1459,7 @@ Requires-Dist: bar==5; extra == 'feature2' Requires-Dist: foo==1; (python_version < '3') and extra == 'feature2' Provides-Extra: feature3 - Requires-Dist: baz@ file:///path/to/project ; extra == 'feature3' + Requires-Dist: baz @ file:///path/to/project ; extra == 'feature3' Description-Content-Type: text/markdown test content @@ -1898,7 +1898,7 @@ Requires-Dist: bar==5; extra == 'feature2' Requires-Dist: foo==1; (python_version < '3') and extra == 'feature2' Provides-Extra: feature3 - Requires-Dist: baz@ file:///path/to/project ; extra == 'feature3' + Requires-Dist: baz @ file:///path/to/project ; extra == 'feature3' Description-Content-Type: text/markdown test content @@ -2364,7 +2364,7 @@ Requires-Dist: bar==5; extra == 'feature2' Requires-Dist: foo==1; (python_version < '3') and extra == 'feature2' Provides-Extra: feature3 - Requires-Dist: baz@ file:///path/to/project ; extra == 'feature3' + Requires-Dist: baz @ file:///path/to/project ; extra == 'feature3' Description-Content-Type: text/markdown test content diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hatch-hatch-v1.16.3/tests/cli/dep/show/test_table.py new/hatch-hatch-v1.16.5/tests/cli/dep/show/test_table.py --- old/hatch-hatch-v1.16.3/tests/cli/dep/show/test_table.py 2026-01-21 02:32:44.000000000 +0100 +++ new/hatch-hatch-v1.16.5/tests/cli/dep/show/test_table.py 2026-02-27 18:59:39.000000000 +0100 @@ -69,7 +69,7 @@ assert result.exit_code == 0, result.output assert helpers.remove_trailing_spaces(result.output) == helpers.dedent( """ - Project + Project +-------------+ | Name | +=============+ @@ -103,7 +103,7 @@ assert result.exit_code == 0, result.output assert helpers.remove_trailing_spaces(result.output) == helpers.dedent( """ - Env: default + Env: default +-------------+ | Name | +=============+ @@ -140,13 +140,13 @@ assert result.exit_code == 0, result.output assert helpers.remove_trailing_spaces(result.output) == helpers.dedent( """ - Project + Project +-------------+ | Name | +=============+ | foo-bar-baz | +-------------+ - Env: default + Env: default +-------------+ | Name | +=============+ @@ -196,7 +196,7 @@ assert result.exit_code == 0, result.output assert helpers.remove_trailing_spaces(result.output) == helpers.dedent( """ - Project + Project +-----------------+----------+------------------------+------------+ | Name | Versions | Markers | Features | +=================+==========+========================+============+ @@ -204,7 +204,7 @@ | foo | | python_version < '3.8' | | | python-dateutil | | | | +-----------------+----------+------------------------+------------+ - Env: default + Env: default +---------+----------------------------------------+----------+------------------------+------------+ | Name | URL | Versions | Markers | Features | +=========+========================================+==========+========================+============+ @@ -252,7 +252,7 @@ assert helpers.remove_trailing_spaces(result.output) == helpers.dedent( """ Syncing environment plugin requirements - Project + Project +-------------+ | Name | +=============+ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hatch-hatch-v1.16.3/tests/cli/env/test_show.py new/hatch-hatch-v1.16.5/tests/cli/env/test_show.py --- old/hatch-hatch-v1.16.3/tests/cli/env/test_show.py 2026-01-21 02:32:44.000000000 +0100 +++ new/hatch-hatch-v1.16.5/tests/cli/env/test_show.py 2026-02-27 18:59:39.000000000 +0100 @@ -36,7 +36,7 @@ assert result.exit_code == 0, result.output assert helpers.remove_trailing_spaces(result.output) == helpers.dedent( """ - Standalone + Standalone +---------+---------+ | Name | Type | +=========+=========+ @@ -107,7 +107,7 @@ assert result.exit_code == 0, result.output assert helpers.remove_trailing_spaces(result.output) == helpers.dedent( """ - Standalone + Standalone +---------+---------+ | Name | Type | +=========+=========+ @@ -145,13 +145,13 @@ assert result.exit_code == 0, result.output assert helpers.remove_trailing_spaces(result.output) == helpers.dedent( """ - Standalone + Standalone +---------+---------+ | Name | Type | +=========+=========+ | default | virtual | +---------+---------+ - Matrices + Matrices +------+---------+----------------+ | Name | Type | Envs | +======+=========+================+ @@ -190,7 +190,7 @@ assert result.exit_code == 0, result.output assert helpers.remove_trailing_spaces(result.output) == helpers.dedent( """ - Matrices + Matrices +---------+---------+------------+ | Name | Type | Envs | +=========+=========+============+ @@ -231,13 +231,13 @@ assert result.exit_code == 0, result.output assert helpers.remove_trailing_spaces(result.output) == helpers.dedent( """ - Standalone + Standalone +------+---------+ | Name | Type | +======+=========+ | bar | virtual | +------+---------+ - Matrices + Matrices +---------+---------+----------------+ | Name | Type | Envs | +=========+=========+================+ @@ -280,7 +280,7 @@ assert result.exit_code == 0, result.output assert helpers.remove_trailing_spaces(result.output) == helpers.dedent( """ - Standalone + Standalone +------+---------+ | Name | Type | +======+=========+ @@ -377,7 +377,7 @@ assert result.exit_code == 0, result.output assert helpers.remove_trailing_spaces(result.output) == helpers.dedent( """ - Standalone + Standalone +------+---------+----------+-----------------------------+-----------------------+---------+----------------------------------------------------------------------------------------------------------+ | Name | Type | Features | Dependencies | Environment variables | Scripts | Description | +======+=========+==========+=============================+=======================+=========+==========================================================================================================+ @@ -387,7 +387,7 @@ | | | | | | | fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia | | | | | | | | deserunt mollit anim id est laborum. | +------+---------+----------+-----------------------------+-----------------------+---------+----------------------------------------------------------------------------------------------------------+ - Matrices + Matrices +---------+---------+------------+----------+-----------------------------+-----------------------+---------+------------------------------------------------------------------------------------------+ | Name | Type | Envs | Features | Dependencies | Environment variables | Scripts | Description | +=========+=========+============+==========+=============================+=======================+=========+==========================================================================================+ @@ -425,7 +425,7 @@ "default", { "matrix": [{"version": ["9000", "3.14"], "py": ["39", "310"]}], - "dependencies": ["foo @ {root:uri}/../foo"], + "dependencies": ["foo@ {root:uri}/../foo"], }, ) @@ -445,21 +445,21 @@ assert result.exit_code == 0, result.output assert helpers.remove_trailing_spaces(result.output) == helpers.dedent( """ - Standalone + Standalone +------+---------+--------------+-----------------------+ | Name | Type | Dependencies | Environment variables | +======+=========+==============+=======================+ | foo | virtual | pydantic | BAR=FOO_BAR | +------+---------+--------------+-----------------------+ - Matrices - +---------+---------+------------+------------------------+ - | Name | Type | Envs | Dependencies | - +=========+=========+============+========================+ - | default | virtual | py39-9000 | foo@ {root:uri}/../foo | - | | | py39-3.14 | | - | | | py310-9000 | | - | | | py310-3.14 | | - +---------+---------+------------+------------------------+ + Matrices + +---------+---------+------------+-------------------------+ + | Name | Type | Envs | Dependencies | + +=========+=========+============+=========================+ + | default | virtual | py39-9000 | foo @ {root:uri}/../foo | + | | | py39-3.14 | | + | | | py310-9000 | | + | | | py310-3.14 | | + +---------+---------+------------+-------------------------+ """ ) @@ -496,7 +496,7 @@ assert helpers.remove_trailing_spaces(result.output) == helpers.dedent( """ Syncing environment plugin requirements - Standalone + Standalone +---------+---------+ | Name | Type | +=========+=========+ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hatch-hatch-v1.16.3/tests/cli/python/test_show.py new/hatch-hatch-v1.16.5/tests/cli/python/test_show.py --- old/hatch-hatch-v1.16.3/tests/cli/python/test_show.py 2026-01-21 02:32:44.000000000 +0100 +++ new/hatch-hatch-v1.16.5/tests/cli/python/test_show.py 2026-02-27 18:59:39.000000000 +0100 @@ -16,7 +16,7 @@ table.add_row(*row) with console.capture() as capture: - console.print(table) + console.print(table, overflow="ignore", no_wrap=True, crop=False) return capture.get() diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hatch-hatch-v1.16.3/tests/conftest.py new/hatch-hatch-v1.16.5/tests/conftest.py --- old/hatch-hatch-v1.16.3/tests/conftest.py 2026-01-21 02:32:44.000000000 +0100 +++ new/hatch-hatch-v1.16.5/tests/conftest.py 2026-02-27 18:59:39.000000000 +0100 @@ -295,17 +295,33 @@ with FileLock(lock_file): if not any(devpi_started_sessions.iterdir()): with EnvVars(env_vars): - subprocess.check_call(["docker", "compose", "-f", compose_file, "up", "--build", "-d"]) + result = subprocess.run( + ["docker", "compose", "-f", compose_file, "up", "--build", "-d", "--wait"], + check=False, + capture_output=True, + ) + if result.returncode != 0: + # Debugging info for if devpi fails to start + logs = subprocess.run(["docker", "logs", "hatch-devpi"], check=False, capture_output=True) + pytest.fail( + f"Failed to start devpi container, see logs:\n{logs.stdout.decode()}\n{logs.stderr.decode()}" + ) - for _ in range(60): + for _ in range(120): output = subprocess.check_output(["docker", "logs", "hatch-devpi"]).decode("utf-8") if f"Serving index {dp.user}/{dp.index_name}" in output: - time.sleep(5) + time.sleep(15) break time.sleep(1) else: # no cov - pass + # Add logging here too for timeout case + import warnings + + logs = subprocess.run(["docker", "logs", "hatch-devpi"], check=False, capture_output=True) + warnings.warn( + f"devpi container logs (timeout):\n{logs.stdout.decode()}\n{logs.stderr.decode()}", stacklevel=1 + ) (devpi_started_sessions / worker_id).touch() diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hatch-hatch-v1.16.3/tests/env/plugin/test_interface.py new/hatch-hatch-v1.16.5/tests/env/plugin/test_interface.py --- old/hatch-hatch-v1.16.3/tests/env/plugin/test_interface.py 2026-01-21 02:32:44.000000000 +0100 +++ new/hatch-hatch-v1.16.5/tests/env/plugin/test_interface.py 2026-02-27 18:59:39.000000000 +0100 @@ -1194,7 +1194,7 @@ ) normalized_path = str(isolation).replace("\\", "/") - assert environment.dependencies == ["dep2", f"proj@ file:{uri_slash_prefix}{normalized_path}", "dep1"] + assert environment.dependencies == ["dep2", f"proj @ file:{uri_slash_prefix}{normalized_path}", "dep1"] def test_project_dependencies_context_formatting( self, temp_dir, isolated_data_dir, platform, temp_application, uri_slash_prefix @@ -1244,7 +1244,7 @@ ) normalized_parent_path = str(temp_dir.parent).replace("\\", "/") - expected_dep = f"sibling-project@ file:{uri_slash_prefix}{normalized_parent_path}/sibling-project" + expected_dep = f"sibling-project @ file:{uri_slash_prefix}{normalized_parent_path}/sibling-project" # Verify the dependency was formatted correctly assert expected_dep in environment.dependencies @@ -3221,6 +3221,59 @@ assert members[1].project.location == member2_path assert members[2].project.location == member3_path + def test_member_outside_root_with_shared_prefix(self, temp_dir, isolated_data_dir, platform, global_application): + """Verify correct workspace member discovery with shared path prefix. + + os.path.commonprefix works character-by-character, so for paths that + share a partial directory name (e.g. 'local_app' and 'lib_member' both + start with 'l'), it would return an invalid path like '.../l' instead + of the true common ancestor directory. os.path.commonpath correctly + returns the nearest common directory, which is what we need as the + base for the member glob search. + + Example of the mismatch: + os.path.commonprefix(['/usr/lib', '/usr/local/lib']) == '/usr/l' + os.path.commonpath(['/usr/lib', '/usr/local/lib']) == '/usr' + """ + project_root = temp_dir / "local_app" + project_root.mkdir() + + member_path = temp_dir / "lib_member" + member_path.mkdir() + (member_path / "pyproject.toml").write_text( + """\ +[build-system] +requires = ["hatchling"] +build-backend = "hatchling.build" + +[project] +name = "lib-member" +version = "0.1.0" +""" + ) + + config = { + "project": {"name": "my_app", "version": "0.0.1"}, + "tool": {"hatch": {"envs": {"default": {"workspace": {"members": [{"path": "../lib_member"}]}}}}}, + } + project = Project(project_root, config=config) + environment = MockEnvironment( + project_root, + project.metadata, + "default", + project.config.envs["default"], + {}, + isolated_data_dir, + isolated_data_dir, + platform, + 0, + global_application, + ) + + members = environment.workspace.members + assert len(members) == 1 + assert members[0].project.location == member_path + class TestWorkspaceDependencies: def test_basic(self, temp_dir, isolated_data_dir, platform, global_application): diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hatch-hatch-v1.16.3/tests/helpers/templates/licenses/__init__.py new/hatch-hatch-v1.16.5/tests/helpers/templates/licenses/__init__.py --- old/hatch-hatch-v1.16.3/tests/helpers/templates/licenses/__init__.py 2026-01-21 02:32:44.000000000 +0100 +++ new/hatch-hatch-v1.16.5/tests/helpers/templates/licenses/__init__.py 2026-02-27 18:59:39.000000000 +0100 @@ -194,9 +194,18 @@ Copyright (c) <year> <copyright holders> -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and +associated documentation files (the "Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the +following conditions: -The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. +The above copyright notice and this permission notice shall be included in all copies or substantial +portions of the Software. -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT +LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO +EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +USE OR OTHER DEALINGS IN THE SOFTWARE. """ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hatch-hatch-v1.16.3/tests/index/server/devpi/entrypoint.sh new/hatch-hatch-v1.16.5/tests/index/server/devpi/entrypoint.sh --- old/hatch-hatch-v1.16.3/tests/index/server/devpi/entrypoint.sh 2026-01-21 02:32:44.000000000 +0100 +++ new/hatch-hatch-v1.16.5/tests/index/server/devpi/entrypoint.sh 2026-02-27 18:59:39.000000000 +0100 @@ -10,7 +10,17 @@ devpi-server --host 0.0.0.0 --port 3141 & echo "==:> Waiting on server" -sleep 5 +for i in $(seq 1 30); do + if devpi use http://localhost:3141 2>/dev/null; then + break + fi + if [ "$i" -eq 30 ]; then + echo "Timed out waiting for devpi-server" + exit 1 + fi + sleep 1 +done + echo "==:> Setting up index" devpi use http://localhost:3141 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hatch-hatch-v1.16.3/tests/index/server/docker-compose.yaml new/hatch-hatch-v1.16.5/tests/index/server/docker-compose.yaml --- old/hatch-hatch-v1.16.3/tests/index/server/docker-compose.yaml 2026-01-21 02:32:44.000000000 +0100 +++ new/hatch-hatch-v1.16.5/tests/index/server/docker-compose.yaml 2026-02-27 18:59:39.000000000 +0100 @@ -9,6 +9,12 @@ - DEVPI_INDEX_NAME - DEVPI_USERNAME - DEVPI_PASSWORD + healthcheck: + test: [ "CMD", "python", "-c", "import urllib.request; urllib.request.urlopen('http://localhost:3141')" ] + interval: 2s + timeout: 5s + retries: 30 + start_period: 10s nginx: container_name: hatch-nginx @@ -19,4 +25,5 @@ volumes: - ./nginx:/etc/nginx depends_on: - - devpi + devpi: + condition: service_healthy \ No newline at end of file
