vcs-versioning 2.3.0__tar.gz → 2.3.2__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (102) hide show
  1. {vcs_versioning-2.3.0 → vcs_versioning-2.3.2}/CHANGELOG.md +19 -0
  2. {vcs_versioning-2.3.0 → vcs_versioning-2.3.2}/MANIFEST.in +0 -1
  3. {vcs_versioning-2.3.0/src/vcs_versioning.egg-info → vcs_versioning-2.3.2}/PKG-INFO +1 -1
  4. {vcs_versioning-2.3.0 → vcs_versioning-2.3.2}/pyproject.toml +1 -0
  5. {vcs_versioning-2.3.0 → vcs_versioning-2.3.2}/src/vcs_versioning/_fallback_workdir.py +39 -1
  6. {vcs_versioning-2.3.0 → vcs_versioning-2.3.2}/src/vcs_versioning/_file_finders/_git.py +4 -0
  7. {vcs_versioning-2.3.0 → vcs_versioning-2.3.2}/src/vcs_versioning/_worktree_discovery.py +8 -4
  8. {vcs_versioning-2.3.0 → vcs_versioning-2.3.2/src/vcs_versioning.egg-info}/PKG-INFO +1 -1
  9. {vcs_versioning-2.3.0 → vcs_versioning-2.3.2}/src/vcs_versioning.egg-info/SOURCES.txt +0 -1
  10. {vcs_versioning-2.3.0 → vcs_versioning-2.3.2}/src/vcs_versioning.egg-info/entry_points.txt +1 -0
  11. {vcs_versioning-2.3.0 → vcs_versioning-2.3.2}/testing_vcs/test_git.py +20 -0
  12. {vcs_versioning-2.3.0 → vcs_versioning-2.3.2}/testing_vcs/test_workdir_discovery.py +168 -0
  13. vcs_versioning-2.3.0/uv.lock +0 -330
  14. {vcs_versioning-2.3.0 → vcs_versioning-2.3.2}/LICENSE.txt +0 -0
  15. {vcs_versioning-2.3.0 → vcs_versioning-2.3.2}/README.md +0 -0
  16. {vcs_versioning-2.3.0 → vcs_versioning-2.3.2}/setup.cfg +0 -0
  17. {vcs_versioning-2.3.0 → vcs_versioning-2.3.2}/setup.py +0 -0
  18. {vcs_versioning-2.3.0 → vcs_versioning-2.3.2}/src/vcs_versioning/__init__.py +0 -0
  19. {vcs_versioning-2.3.0 → vcs_versioning-2.3.2}/src/vcs_versioning/__main__.py +0 -0
  20. {vcs_versioning-2.3.0 → vcs_versioning-2.3.2}/src/vcs_versioning/_backends/__init__.py +0 -0
  21. {vcs_versioning-2.3.0 → vcs_versioning-2.3.2}/src/vcs_versioning/_backends/_discover_vcs.py +0 -0
  22. {vcs_versioning-2.3.0 → vcs_versioning-2.3.2}/src/vcs_versioning/_backends/_git.py +0 -0
  23. {vcs_versioning-2.3.0 → vcs_versioning-2.3.2}/src/vcs_versioning/_backends/_hg.py +0 -0
  24. {vcs_versioning-2.3.0 → vcs_versioning-2.3.2}/src/vcs_versioning/_backends/_hg_git.py +0 -0
  25. {vcs_versioning-2.3.0 → vcs_versioning-2.3.2}/src/vcs_versioning/_backends/_jj.py +0 -0
  26. {vcs_versioning-2.3.0 → vcs_versioning-2.3.2}/src/vcs_versioning/_backends/_scm_workdir.py +0 -0
  27. {vcs_versioning-2.3.0 → vcs_versioning-2.3.2}/src/vcs_versioning/_cli/__init__.py +0 -0
  28. {vcs_versioning-2.3.0 → vcs_versioning-2.3.2}/src/vcs_versioning/_cli/_args.py +0 -0
  29. {vcs_versioning-2.3.0 → vcs_versioning-2.3.2}/src/vcs_versioning/_cli/git_archival_full.txt +0 -0
  30. {vcs_versioning-2.3.0 → vcs_versioning-2.3.2}/src/vcs_versioning/_cli/git_archival_stable.txt +0 -0
  31. {vcs_versioning-2.3.0 → vcs_versioning-2.3.2}/src/vcs_versioning/_compat.py +0 -0
  32. {vcs_versioning-2.3.0 → vcs_versioning-2.3.2}/src/vcs_versioning/_config.py +0 -0
  33. {vcs_versioning-2.3.0 → vcs_versioning-2.3.2}/src/vcs_versioning/_discover.py +0 -0
  34. {vcs_versioning-2.3.0 → vcs_versioning-2.3.2}/src/vcs_versioning/_dump_version.py +0 -0
  35. {vcs_versioning-2.3.0 → vcs_versioning-2.3.2}/src/vcs_versioning/_dynamic_metadata.py +0 -0
  36. {vcs_versioning-2.3.0 → vcs_versioning-2.3.2}/src/vcs_versioning/_entrypoints.py +0 -0
  37. {vcs_versioning-2.3.0 → vcs_versioning-2.3.2}/src/vcs_versioning/_environment.py +0 -0
  38. {vcs_versioning-2.3.0 → vcs_versioning-2.3.2}/src/vcs_versioning/_exceptions.py +0 -0
  39. {vcs_versioning-2.3.0 → vcs_versioning-2.3.2}/src/vcs_versioning/_fallbacks.py +0 -0
  40. {vcs_versioning-2.3.0 → vcs_versioning-2.3.2}/src/vcs_versioning/_file_finders/__init__.py +0 -0
  41. {vcs_versioning-2.3.0 → vcs_versioning-2.3.2}/src/vcs_versioning/_file_finders/_hg.py +0 -0
  42. {vcs_versioning-2.3.0 → vcs_versioning-2.3.2}/src/vcs_versioning/_file_finders/_jj.py +0 -0
  43. {vcs_versioning-2.3.0 → vcs_versioning-2.3.2}/src/vcs_versioning/_get_version_impl.py +0 -0
  44. {vcs_versioning-2.3.0 → vcs_versioning-2.3.2}/src/vcs_versioning/_integration.py +0 -0
  45. {vcs_versioning-2.3.0 → vcs_versioning-2.3.2}/src/vcs_versioning/_integrator_helpers.py +0 -0
  46. {vcs_versioning-2.3.0 → vcs_versioning-2.3.2}/src/vcs_versioning/_legacy_parse.py +0 -0
  47. {vcs_versioning-2.3.0 → vcs_versioning-2.3.2}/src/vcs_versioning/_log.py +0 -0
  48. {vcs_versioning-2.3.0 → vcs_versioning-2.3.2}/src/vcs_versioning/_modify_version.py +0 -0
  49. {vcs_versioning-2.3.0 → vcs_versioning-2.3.2}/src/vcs_versioning/_node_utils.py +0 -0
  50. {vcs_versioning-2.3.0 → vcs_versioning-2.3.2}/src/vcs_versioning/_overrides.py +0 -0
  51. {vcs_versioning-2.3.0 → vcs_versioning-2.3.2}/src/vcs_versioning/_paths.py +0 -0
  52. {vcs_versioning-2.3.0 → vcs_versioning-2.3.2}/src/vcs_versioning/_project_overrides.py +0 -0
  53. {vcs_versioning-2.3.0 → vcs_versioning-2.3.2}/src/vcs_versioning/_protocols.py +0 -0
  54. {vcs_versioning-2.3.0 → vcs_versioning-2.3.2}/src/vcs_versioning/_pyproject_reading.py +0 -0
  55. {vcs_versioning-2.3.0 → vcs_versioning-2.3.2}/src/vcs_versioning/_requirement_cls.py +0 -0
  56. {vcs_versioning-2.3.0 → vcs_versioning-2.3.2}/src/vcs_versioning/_run_cmd.py +0 -0
  57. {vcs_versioning-2.3.0 → vcs_versioning-2.3.2}/src/vcs_versioning/_scm_metadata.py +0 -0
  58. {vcs_versioning-2.3.0 → vcs_versioning-2.3.2}/src/vcs_versioning/_scm_version.py +0 -0
  59. {vcs_versioning-2.3.0 → vcs_versioning-2.3.2}/src/vcs_versioning/_test_utils.py +0 -0
  60. {vcs_versioning-2.3.0 → vcs_versioning-2.3.2}/src/vcs_versioning/_toml.py +0 -0
  61. {vcs_versioning-2.3.0 → vcs_versioning-2.3.2}/src/vcs_versioning/_types.py +0 -0
  62. {vcs_versioning-2.3.0 → vcs_versioning-2.3.2}/src/vcs_versioning/_version_cls.py +0 -0
  63. {vcs_versioning-2.3.0 → vcs_versioning-2.3.2}/src/vcs_versioning/_version_fields.py +0 -0
  64. {vcs_versioning-2.3.0 → vcs_versioning-2.3.2}/src/vcs_versioning/_version_inference.py +0 -0
  65. {vcs_versioning-2.3.0 → vcs_versioning-2.3.2}/src/vcs_versioning/_version_schemes/__init__.py +0 -0
  66. {vcs_versioning-2.3.0 → vcs_versioning-2.3.2}/src/vcs_versioning/_version_schemes/_common.py +0 -0
  67. {vcs_versioning-2.3.0 → vcs_versioning-2.3.2}/src/vcs_versioning/_version_schemes/_standard.py +0 -0
  68. {vcs_versioning-2.3.0 → vcs_versioning-2.3.2}/src/vcs_versioning/_version_schemes/_towncrier.py +0 -0
  69. {vcs_versioning-2.3.0 → vcs_versioning-2.3.2}/src/vcs_versioning/overrides.py +0 -0
  70. {vcs_versioning-2.3.0 → vcs_versioning-2.3.2}/src/vcs_versioning/py.typed +0 -0
  71. {vcs_versioning-2.3.0 → vcs_versioning-2.3.2}/src/vcs_versioning/test_api.py +0 -0
  72. {vcs_versioning-2.3.0 → vcs_versioning-2.3.2}/src/vcs_versioning.egg-info/dependency_links.txt +0 -0
  73. {vcs_versioning-2.3.0 → vcs_versioning-2.3.2}/src/vcs_versioning.egg-info/requires.txt +0 -0
  74. {vcs_versioning-2.3.0 → vcs_versioning-2.3.2}/src/vcs_versioning.egg-info/top_level.txt +0 -0
  75. {vcs_versioning-2.3.0 → vcs_versioning-2.3.2}/testing_vcs/__init__.py +0 -0
  76. {vcs_versioning-2.3.0 → vcs_versioning-2.3.2}/testing_vcs/conftest.py +0 -0
  77. {vcs_versioning-2.3.0 → vcs_versioning-2.3.2}/testing_vcs/test_better_root_errors.py +0 -0
  78. {vcs_versioning-2.3.0 → vcs_versioning-2.3.2}/testing_vcs/test_chain_api.py +0 -0
  79. {vcs_versioning-2.3.0 → vcs_versioning-2.3.2}/testing_vcs/test_compat.py +0 -0
  80. {vcs_versioning-2.3.0 → vcs_versioning-2.3.2}/testing_vcs/test_config.py +0 -0
  81. {vcs_versioning-2.3.0 → vcs_versioning-2.3.2}/testing_vcs/test_dynamic_metadata.py +0 -0
  82. {vcs_versioning-2.3.0 → vcs_versioning-2.3.2}/testing_vcs/test_expect_parse.py +0 -0
  83. {vcs_versioning-2.3.0 → vcs_versioning-2.3.2}/testing_vcs/test_file_finders.py +0 -0
  84. {vcs_versioning-2.3.0 → vcs_versioning-2.3.2}/testing_vcs/test_hg_git.py +0 -0
  85. {vcs_versioning-2.3.0 → vcs_versioning-2.3.2}/testing_vcs/test_hg_tag_strict.py +0 -0
  86. {vcs_versioning-2.3.0 → vcs_versioning-2.3.2}/testing_vcs/test_integrator_helpers.py +0 -0
  87. {vcs_versioning-2.3.0 → vcs_versioning-2.3.2}/testing_vcs/test_internal_log_level.py +0 -0
  88. {vcs_versioning-2.3.0 → vcs_versioning-2.3.2}/testing_vcs/test_jj.py +0 -0
  89. {vcs_versioning-2.3.0 → vcs_versioning-2.3.2}/testing_vcs/test_legacy_parse.py +0 -0
  90. {vcs_versioning-2.3.0 → vcs_versioning-2.3.2}/testing_vcs/test_mercurial.py +0 -0
  91. {vcs_versioning-2.3.0 → vcs_versioning-2.3.2}/testing_vcs/test_overrides_api.py +0 -0
  92. {vcs_versioning-2.3.0 → vcs_versioning-2.3.2}/testing_vcs/test_overrides_env_reader.py +0 -0
  93. {vcs_versioning-2.3.0 → vcs_versioning-2.3.2}/testing_vcs/test_project_overrides.py +0 -0
  94. {vcs_versioning-2.3.0 → vcs_versioning-2.3.2}/testing_vcs/test_project_path.py +0 -0
  95. {vcs_versioning-2.3.0 → vcs_versioning-2.3.2}/testing_vcs/test_regressions.py +0 -0
  96. {vcs_versioning-2.3.0 → vcs_versioning-2.3.2}/testing_vcs/test_scm_metadata.py +0 -0
  97. {vcs_versioning-2.3.0 → vcs_versioning-2.3.2}/testing_vcs/test_tag_config.py +0 -0
  98. {vcs_versioning-2.3.0 → vcs_versioning-2.3.2}/testing_vcs/test_tag_strict_diagnostics.py +0 -0
  99. {vcs_versioning-2.3.0 → vcs_versioning-2.3.2}/testing_vcs/test_version.py +0 -0
  100. {vcs_versioning-2.3.0 → vcs_versioning-2.3.2}/testing_vcs/test_version_scheme_towncrier.py +0 -0
  101. {vcs_versioning-2.3.0 → vcs_versioning-2.3.2}/testing_vcs/test_version_schemes.py +0 -0
  102. {vcs_versioning-2.3.0 → vcs_versioning-2.3.2}/testing_vcs/test_workdir_api.py +0 -0
@@ -2,6 +2,25 @@
2
2
 
3
3
  <!-- towncrier release notes start -->
4
4
 
5
+ ## 2.3.2 (2026-09-01)
6
+
7
+ ### Fixed
8
+
9
+ - Register the `pkginfo` workdir discovery factory in vcs-versioning itself. `PKG-INFO` is standard sdist metadata, not a setuptools artifact, but its factory was only registered by setuptools-scm -- so a standalone vcs-versioning install could not infer a version from an sdist. This broke sdist builds for non-setuptools backends, e.g. meson-python calling `python -m vcs_versioning` from `project()`.
10
+
11
+ Fallback workdir candidates are now ordered by how much metadata they carry (egg-info, then archival, then `PKG-INFO`) instead of by entry point iteration order, so a setuptools built sdist keeps using its `scm_version.json` now that the two factories ship from different distributions. ([#1507](https://github.com/pypa/setuptools-scm/issues/1507))
12
+
13
+
14
+ ### Miscellaneous
15
+
16
+ - Stop shipping a per-package `uv.lock` in the sdist. It could not be generated correctly whenever `setuptools-scm` required an unreleased `vcs-versioning`, which broke the release proposal workflow. ([#1509](https://github.com/pypa/setuptools-scm/issues/1509))
17
+
18
+ ## 2.3.1 (2026-08-19)
19
+
20
+ ### Fixed
21
+
22
+ - Fix a `FileNotFoundError` crash in the git file finder when a submodule is tracked in the index but its working tree directory does not exist - such gitlinks are now skipped like not checked out submodules. ([#1500](https://github.com/pypa/setuptools-scm/issues/1500))
23
+
5
24
  ## 2.3.0 (2026-08-13)
6
25
 
7
26
  ### Added
@@ -9,6 +9,5 @@ include *.toml
9
9
  include LICENSE.txt
10
10
  include README.md
11
11
  include CHANGELOG.md
12
- include uv.lock
13
12
 
14
13
  prune .cursor
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: vcs-versioning
3
- Version: 2.3.0
3
+ Version: 2.3.2
4
4
  Summary: the blessed package to manage your versions by vcs metadata
5
5
  Author-email: Ronny Pfannschmidt <opensource@ronnypfannschmidt.de>
6
6
  License: MIT
@@ -61,6 +61,7 @@ Source = "https://github.com/pypa/setuptools-scm"
61
61
  [project.entry-points."vcs_versioning.discover_workdir"]
62
62
  hg-git = "vcs_versioning._backends._discover_vcs:discover"
63
63
  archival = "vcs_versioning._fallback_workdir:discover_archival"
64
+ pkginfo = "vcs_versioning._fallback_workdir:discover_pkginfo"
64
65
 
65
66
  [project.entry-points."setuptools_scm.files_command"]
66
67
  ".jj" = "vcs_versioning._file_finders._jj:jj_find_files"
@@ -13,7 +13,7 @@ from dataclasses import dataclass
13
13
  from dataclasses import field as dc_field
14
14
  from datetime import date
15
15
  from pathlib import Path
16
- from typing import TYPE_CHECKING
16
+ from typing import TYPE_CHECKING, ClassVar
17
17
 
18
18
  from ._integration import data_from_mime
19
19
  from ._scm_metadata import read_scm_file_list, read_scm_version_data
@@ -29,6 +29,22 @@ log = logging.getLogger(__name__)
29
29
  class FallbackWorkdir:
30
30
  """Base for work directories without a live VCS checkout."""
31
31
 
32
+ discovery_priority: ClassVar[int] = 100
33
+ """How much metadata this workdir carries; lower wins.
34
+
35
+ Discovery stashes every fallback workdir that matches, then takes the
36
+ first one that can produce a version. A sdist can match several at
37
+ once -- a setuptools built one carries both ``PKG-INFO`` and
38
+ ``*.egg-info/scm_version.json`` -- and their factories may ship from
39
+ different distributions, so entry point iteration order must not
40
+ decide the winner (:issue:`1507`). Rank by how much the workdir
41
+ knows instead: tag plus distance plus node plus file list beats a
42
+ flat preformatted version.
43
+
44
+ Third-party workdirs inherit the default and rank after all built-ins
45
+ unless they set their own.
46
+ """
47
+
32
48
  path: Path
33
49
 
34
50
  _config: Configuration | None = dc_field(default=None, repr=False, compare=False)
@@ -60,6 +76,10 @@ class FallbackWorkdir:
60
76
  class MetadataWorkdir(FallbackWorkdir):
61
77
  """Reads ``scm_version.json`` / ``scm_file_list.json`` written by a build backend."""
62
78
 
79
+ discovery_priority: ClassVar[int] = (
80
+ 10 # tag, distance, node and a tracked file list
81
+ )
82
+
63
83
  metadata_dir: Path | None = dc_field(default=None)
64
84
 
65
85
  def __post_init__(self) -> None:
@@ -113,6 +133,8 @@ class MetadataWorkdir(FallbackWorkdir):
113
133
  class ArchivedWorkdir(FallbackWorkdir):
114
134
  """Reads ``.git_archival.txt`` or ``.hg_archival.txt``."""
115
135
 
136
+ discovery_priority: ClassVar[int] = 20 # describe output, no file list
137
+
116
138
  archival_path: Path | None = dc_field(default=None)
117
139
 
118
140
  def __post_init__(self) -> None:
@@ -146,6 +168,8 @@ class ArchivedWorkdir(FallbackWorkdir):
146
168
  class PkgInfoWorkdir(FallbackWorkdir):
147
169
  """Reads ``PKG-INFO`` for version; file list from ``scm_file_list.json`` if present."""
148
170
 
171
+ discovery_priority: ClassVar[int] = 30 # a flat preformatted version only
172
+
149
173
  def get_scm_version(self) -> ScmVersion | None:
150
174
  pkginfo = self.path / "PKG-INFO"
151
175
  if not pkginfo.is_file():
@@ -165,6 +189,8 @@ class PkgInfoWorkdir(FallbackWorkdir):
165
189
  class StaticWorkdir(FallbackWorkdir):
166
190
  """Uses ``config.fallback_version`` / ``parentdir_prefix_version``; no file list."""
167
191
 
192
+ discovery_priority: ClassVar[int] = 90 # configured constants, no SCM data at all
193
+
168
194
  def get_scm_version(self) -> ScmVersion | None:
169
195
  config = self.config
170
196
  if config.parentdir_prefix_version is not None:
@@ -197,6 +223,18 @@ def discover_archival(path: Path, *, config: Configuration) -> FallbackWorkdir |
197
223
  return None
198
224
 
199
225
 
226
+ def discover_pkginfo(path: Path, *, config: Configuration) -> FallbackWorkdir | None:
227
+ """Probe *path* for ``PKG-INFO``.
228
+
229
+ ``PKG-INFO`` is the standard sdist metadata file written by every
230
+ build backend, so this factory lives in the core package rather than
231
+ in the setuptools integration (:issue:`1507`).
232
+ """
233
+ if (path / "PKG-INFO").is_file():
234
+ return PkgInfoWorkdir(path=path)
235
+ return None
236
+
237
+
200
238
  # ------------------------------------------------------------------
201
239
  # Archival parsers (thin wrappers around existing logic)
202
240
  # ------------------------------------------------------------------
@@ -84,6 +84,10 @@ def _ls_files_entries(
84
84
  ``None`` signals that git refused to list files (no repository yet,
85
85
  or a submodule that is not checked out).
86
86
  """
87
+ if not repo.is_dir():
88
+ # a submodule tracked in the index whose working tree is absent -
89
+ # running git in it would fail before git could report anything
90
+ return None
87
91
  res = run_git(
88
92
  ["ls-files", "-z", "-s", "--", ".", ":(exclude,attr:export-ignore)"],
89
93
  repo,
@@ -70,10 +70,11 @@ def discover_workdir(config: Configuration) -> AnyWorkdir | None:
70
70
  - ScmWorkdir result: verify project_path, return immediately.
71
71
  - FallbackWorkdir result: stash as candidate, keep probing for SCM.
72
72
  2. Fallback phase: probe ``project_dir`` (if different from scm root).
73
- 3. Try each stashed FallbackWorkdir in discovery order; return the first
74
- whose ``get_scm_version()`` is not None. This prevents an
75
- unprocessed ``.git_archival.txt`` from shadowing a valid ``PKG-INFO``
76
- (see :issue:`1431`).
73
+ 3. Sort the stashed FallbackWorkdirs by ``discovery_priority`` and
74
+ return the first whose ``get_scm_version()`` is not None. Trying
75
+ every candidate prevents an unprocessed ``.git_archival.txt`` from
76
+ shadowing a valid ``PKG-INFO`` (see :issue:`1431`); sorting keeps
77
+ the winner independent of entry point order (see :issue:`1507`).
77
78
  4. Try StaticWorkdir from config.fallback_version / parentdir_prefix_version.
78
79
  5. Return None.
79
80
  """
@@ -152,6 +153,9 @@ def discover_workdir(config: Configuration) -> AnyWorkdir | None:
152
153
  # Earlier discovery code stashed all matching fallback workdirs; an
153
154
  # unprocessed .git_archival.txt (raw $Format placeholders) would
154
155
  # shadow a valid PKG-INFO if we only kept the first candidate.
156
+ # Richest metadata first, so the winner does not depend on entry point
157
+ # iteration order (#1507); stable, so probe order still breaks ties.
158
+ fallback_candidates.sort(key=lambda w: w.discovery_priority)
155
159
  for candidate in fallback_candidates:
156
160
  if candidate.get_scm_version() is not None:
157
161
  log.info("using fallback workdir %s", type(candidate).__name__)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: vcs-versioning
3
- Version: 2.3.0
3
+ Version: 2.3.2
4
4
  Summary: the blessed package to manage your versions by vcs metadata
5
5
  Author-email: Ronny Pfannschmidt <opensource@ronnypfannschmidt.de>
6
6
  License: MIT
@@ -4,7 +4,6 @@ MANIFEST.in
4
4
  README.md
5
5
  pyproject.toml
6
6
  setup.py
7
- uv.lock
8
7
  src/vcs_versioning/__init__.py
9
8
  src/vcs_versioning/__main__.py
10
9
  src/vcs_versioning/_compat.py
@@ -36,3 +36,4 @@ towncrier-fragments = vcs_versioning._version_schemes._towncrier:version_from_fr
36
36
  [vcs_versioning.discover_workdir]
37
37
  archival = vcs_versioning._fallback_workdir:discover_archival
38
38
  hg-git = vcs_versioning._backends._discover_vcs:discover
39
+ pkginfo = vcs_versioning._fallback_workdir:discover_pkginfo
@@ -508,6 +508,26 @@ def test_git_uninitialized_submodule_skipped(
508
508
  assert not [name for name in found if "mysub" in name]
509
509
 
510
510
 
511
+ @pytest.mark.issue("https://github.com/pypa/setuptools-scm/issues/1500")
512
+ def test_git_submodule_without_working_tree_skipped(
513
+ wd: WorkDir, monkeypatch: pytest.MonkeyPatch
514
+ ) -> None:
515
+ """A gitlink whose directory does not exist at all is skipped, not fatal."""
516
+ wd.write("parent_file.txt", "parent content")
517
+ wd("git add parent_file.txt")
518
+ wd(
519
+ "git update-index --add --cacheinfo"
520
+ " 160000,77ef5b8fe4bab2b73f7b234267f0dfb75e96eeee,missing_submodule"
521
+ )
522
+ wd.commit()
523
+
524
+ monkeypatch.chdir(wd.cwd)
525
+ found = set(vcs_versioning._file_finders.find_files("."))
526
+
527
+ assert opj(".", "parent_file.txt") in found
528
+ assert not [name for name in found if "missing_submodule" in name]
529
+
530
+
511
531
  @pytest.mark.issue("https://github.com/pypa/setuptools-scm/issues/728")
512
532
  def test_git_branch_names_correct(wd: WorkDir) -> None:
513
533
  wd.commit_testfile()
@@ -3,14 +3,18 @@
3
3
  from __future__ import annotations
4
4
 
5
5
  import subprocess
6
+ from importlib.metadata import EntryPoint
6
7
  from pathlib import Path
8
+ from typing import Any
7
9
 
8
10
  import pytest
9
11
  from vcs_versioning._backends._scm_workdir import ScmWorkdir
10
12
  from vcs_versioning._config import Configuration
11
13
  from vcs_versioning._fallback_workdir import (
12
14
  ArchivedWorkdir,
15
+ FallbackWorkdir,
13
16
  MetadataWorkdir,
17
+ PkgInfoWorkdir,
14
18
  StaticWorkdir,
15
19
  )
16
20
  from vcs_versioning._scm_metadata import (
@@ -18,6 +22,7 @@ from vcs_versioning._scm_metadata import (
18
22
  write_scm_file_list,
19
23
  write_scm_version_data,
20
24
  )
25
+ from vcs_versioning._scm_version import ScmVersion, meta
21
26
  from vcs_versioning._worktree_discovery import discover_workdir
22
27
 
23
28
 
@@ -149,6 +154,16 @@ class TestDiscoverWorkdirFallback:
149
154
  assert result is not None
150
155
  assert isinstance(result, ArchivedWorkdir)
151
156
 
157
+ def test_discovers_pkginfo(self, tmp_path: Path) -> None:
158
+ (tmp_path / "PKG-INFO").write_text(
159
+ "Metadata-Version: 2.1\nName: pkg\nVersion: 3.0.0\n",
160
+ encoding="utf-8",
161
+ )
162
+ config = Configuration(relative_to=str(tmp_path / "pyproject.toml"))
163
+ result = discover_workdir(config)
164
+ assert result is not None
165
+ assert isinstance(result, PkgInfoWorkdir)
166
+
152
167
  def test_scm_preferred_over_fallback(self, tmp_path: Path) -> None:
153
168
  """SCM markers should be preferred over fallback markers."""
154
169
  _git_init(tmp_path)
@@ -233,6 +248,21 @@ class TestFallbackWorkdirDiscoveryFactories:
233
248
  config = Configuration()
234
249
  assert discover_archival(tmp_path, config=config) is None
235
250
 
251
+ def test_discover_pkginfo(self, tmp_path: Path) -> None:
252
+ from vcs_versioning._fallback_workdir import discover_pkginfo
253
+
254
+ (tmp_path / "PKG-INFO").write_text("Version: 1.0\n", encoding="utf-8")
255
+ config = Configuration()
256
+ result = discover_pkginfo(tmp_path, config=config)
257
+ assert result is not None
258
+ assert isinstance(result, PkgInfoWorkdir)
259
+
260
+ def test_discover_pkginfo_none(self, tmp_path: Path) -> None:
261
+ from vcs_versioning._fallback_workdir import discover_pkginfo
262
+
263
+ config = Configuration()
264
+ assert discover_pkginfo(tmp_path, config=config) is None
265
+
236
266
 
237
267
  class TestMetadataWorkdir:
238
268
  def test_reads_version_from_json(self, tmp_path: Path) -> None:
@@ -284,3 +314,141 @@ class TestMetadataWorkdir:
284
314
  wd = MetadataWorkdir(path=tmp_path, metadata_dir=tmp_path, _config=config)
285
315
  assert wd.get_scm_version() is None
286
316
  assert wd.list_tracked_files() == []
317
+
318
+
319
+ class TestFallbackPriority:
320
+ @pytest.mark.issue(1431)
321
+ def test_unprocessed_archival_falls_through_to_pkginfo(
322
+ self, tmp_path: Path
323
+ ) -> None:
324
+ """Unprocessed .git_archival.txt must not shadow a valid PKG-INFO.
325
+
326
+ PyPI sdists contain both files: a .git_archival.txt with raw
327
+ ``$Format:...`` placeholders (never substituted because the sdist
328
+ was built by setuptools, not ``git archive``) and a PKG-INFO with
329
+ the correct version. Before the fix, the archival fallback was
330
+ stashed as the sole candidate and its ``get_scm_version()`` returned
331
+ None, causing a LookupError.
332
+ """
333
+ (tmp_path / ".git_archival.txt").write_text(
334
+ "node: $Format:%H$\n"
335
+ "node-date: $Format:%cI$\n"
336
+ "describe-name: $Format:%(describe:tags=true)$\n"
337
+ "ref-names: $Format:%D$\n",
338
+ encoding="utf-8",
339
+ )
340
+ (tmp_path / "PKG-INFO").write_text(
341
+ "Metadata-Version: 2.1\nName: my-pkg\nVersion: 1.2.3\n",
342
+ encoding="utf-8",
343
+ )
344
+ config = Configuration(relative_to=str(tmp_path / "pyproject.toml"))
345
+ result = discover_workdir(config)
346
+ assert result is not None
347
+ assert isinstance(result, PkgInfoWorkdir)
348
+ version = result.get_scm_version()
349
+ assert version is not None
350
+ assert str(version.tag) == "1.2.3"
351
+
352
+
353
+ class TestPkgInfoRegisteredByCore:
354
+ """PKG-INFO fallback must work without setuptools-scm installed (#1507)."""
355
+
356
+ @pytest.mark.issue(1507)
357
+ def test_pkginfo_factory_registered_by_vcs_versioning(self) -> None:
358
+ """Assert on the distribution metadata, not the merged EP view.
359
+
360
+ In the monorepo venv setuptools-scm is installed too, so a plain
361
+ ``entry_points(group=...)`` lookup cannot tell which package
362
+ registered the factory -- which is exactly how #1507 escaped the
363
+ test suite.
364
+ """
365
+ from importlib.metadata import distribution
366
+
367
+ names = {
368
+ ep.name
369
+ for ep in distribution("vcs-versioning").entry_points
370
+ if ep.group == "vcs_versioning.discover_workdir"
371
+ }
372
+ assert "pkginfo" in names
373
+
374
+ @pytest.mark.issue(1507)
375
+ def test_discovery_without_setuptools_scm(
376
+ self, tmp_path: Path, monkeypatch: pytest.MonkeyPatch
377
+ ) -> None:
378
+ """Discovery finds PKG-INFO using only vcs-versioning's own factories."""
379
+ from vcs_versioning import _compat, _worktree_discovery
380
+
381
+ real = _compat.entry_points
382
+
383
+ def core_only(*args: Any, **kwargs: Any) -> list[EntryPoint]:
384
+ return [
385
+ ep
386
+ for ep in real(*args, **kwargs)
387
+ if ep.value.startswith("vcs_versioning")
388
+ ]
389
+
390
+ monkeypatch.setattr(_worktree_discovery, "entry_points", core_only)
391
+
392
+ (tmp_path / "PKG-INFO").write_text(
393
+ "Metadata-Version: 2.1\nName: pkg\nVersion: 3.0.0\n",
394
+ encoding="utf-8",
395
+ )
396
+ config = Configuration(relative_to=str(tmp_path / "pyproject.toml"))
397
+ result = discover_workdir(config)
398
+ assert isinstance(result, PkgInfoWorkdir)
399
+
400
+
401
+ class TestFallbackCandidatePriority:
402
+ @pytest.mark.issue(1507)
403
+ def test_egg_info_metadata_wins_over_pkginfo(self, tmp_path: Path) -> None:
404
+ """Richer metadata must win regardless of entry point order.
405
+
406
+ A setuptools-scm built sdist carries both a root PKG-INFO and
407
+ ``*.egg-info/scm_version.json``. The two factories ship from
408
+ different distributions, so entry point iteration order cannot
409
+ decide this -- MetadataWorkdir knows distance, node and the
410
+ tracked file list, PkgInfoWorkdir only a flat version.
411
+ """
412
+ (tmp_path / "PKG-INFO").write_text(
413
+ "Metadata-Version: 2.1\nName: pkg\nVersion: 1.0.0\n",
414
+ encoding="utf-8",
415
+ )
416
+ egg_info = tmp_path / "pkg.egg-info"
417
+ egg_info.mkdir()
418
+ write_scm_version_data(
419
+ egg_info,
420
+ ScmVersionData(
421
+ tag="1.0.0",
422
+ distance=3,
423
+ node="gdeadbee",
424
+ dirty=False,
425
+ branch="main",
426
+ node_date=None,
427
+ ),
428
+ )
429
+ write_scm_file_list(egg_info, ["pkg/__init__.py"])
430
+
431
+ config = Configuration(relative_to=str(tmp_path / "pyproject.toml"))
432
+ result = discover_workdir(config)
433
+ assert isinstance(result, MetadataWorkdir)
434
+ version = result.get_scm_version()
435
+ assert version is not None
436
+ assert version.distance == 3
437
+ assert result.list_tracked_files() == ["pkg/__init__.py"]
438
+
439
+ @pytest.mark.issue(1507)
440
+ def test_third_party_workdir_ranks_by_declared_priority(
441
+ self, tmp_path: Path
442
+ ) -> None:
443
+ """discovery_priority is the knob, not entry point order."""
444
+
445
+ class PoorWorkdir(FallbackWorkdir):
446
+ def get_scm_version(self) -> ScmVersion | None:
447
+ return meta("9.9.9", preformatted=True, config=self.config)
448
+
449
+ class RichWorkdir(PoorWorkdir):
450
+ discovery_priority = 5
451
+
452
+ assert PoorWorkdir.discovery_priority == FallbackWorkdir.discovery_priority
453
+ assert PoorWorkdir.discovery_priority > PkgInfoWorkdir.discovery_priority
454
+ assert RichWorkdir.discovery_priority < MetadataWorkdir.discovery_priority
@@ -1,330 +0,0 @@
1
- version = 1
2
- revision = 3
3
- requires-python = ">=3.8"
4
- resolution-markers = [
5
- "python_full_version >= '3.10'",
6
- "python_full_version == '3.9.*'",
7
- "python_full_version < '3.9'",
8
- ]
9
-
10
- [[package]]
11
- name = "colorama"
12
- version = "0.4.6"
13
- source = { registry = "https://pypi.org/simple" }
14
- sdist = { url = "https://files.pythonhosted.org/packages/d8/53/6f443c9a4a8358a93a6792e2acffb9d9d5cb0a5cfd8802644b7b1c9a02e4/colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44", size = 27697, upload-time = "2022-10-25T02:36:22.414Z" }
15
- wheels = [
16
- { url = "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6", size = 25335, upload-time = "2022-10-25T02:36:20.889Z" },
17
- ]
18
-
19
- [[package]]
20
- name = "exceptiongroup"
21
- version = "1.3.1"
22
- source = { registry = "https://pypi.org/simple" }
23
- dependencies = [
24
- { name = "typing-extensions", version = "4.13.2", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.9' or python_full_version >= '3.11'" },
25
- { name = "typing-extensions", version = "4.15.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.9' and python_full_version < '3.11'" },
26
- ]
27
- 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" }
28
- wheels = [
29
- { url = "https://files.pythonhosted.org/packages/8a/0e/97c33bf5009bdbac74fd2beace167cab3f978feb69cc36f1ef79360d6c4e/exceptiongroup-1.3.1-py3-none-any.whl", hash = "sha256:a7a39a3bd276781e98394987d3a5701d0c4edffb633bb7a5144577f82c773598", size = 16740, upload-time = "2025-11-21T23:01:53.443Z" },
30
- ]
31
-
32
- [[package]]
33
- name = "execnet"
34
- version = "2.1.2"
35
- source = { registry = "https://pypi.org/simple" }
36
- sdist = { url = "https://files.pythonhosted.org/packages/bf/89/780e11f9588d9e7128a3f87788354c7946a9cbb1401ad38a48c4db9a4f07/execnet-2.1.2.tar.gz", hash = "sha256:63d83bfdd9a23e35b9c6a3261412324f964c2ec8dcd8d3c6916ee9373e0befcd", size = 166622, upload-time = "2025-11-12T09:56:37.75Z" }
37
- wheels = [
38
- { url = "https://files.pythonhosted.org/packages/ab/84/02fc1827e8cdded4aa65baef11296a9bbe595c474f0d6d758af082d849fd/execnet-2.1.2-py3-none-any.whl", hash = "sha256:67fba928dd5a544b783f6056f449e5e3931a5c378b128bc18501f7ea79e296ec", size = 40708, upload-time = "2025-11-12T09:56:36.333Z" },
39
- ]
40
-
41
- [[package]]
42
- name = "iniconfig"
43
- version = "2.1.0"
44
- source = { registry = "https://pypi.org/simple" }
45
- resolution-markers = [
46
- "python_full_version == '3.9.*'",
47
- "python_full_version < '3.9'",
48
- ]
49
- sdist = { url = "https://files.pythonhosted.org/packages/f2/97/ebf4da567aa6827c909642694d71c9fcf53e5b504f2d96afea02718862f3/iniconfig-2.1.0.tar.gz", hash = "sha256:3abbd2e30b36733fee78f9c7f7308f2d0050e88f0087fd25c2645f63c773e1c7", size = 4793, upload-time = "2025-03-19T20:09:59.721Z" }
50
- wheels = [
51
- { url = "https://files.pythonhosted.org/packages/2c/e1/e6716421ea10d38022b952c159d5161ca1193197fb744506875fbb87ea7b/iniconfig-2.1.0-py3-none-any.whl", hash = "sha256:9deba5723312380e77435581c6bf4935c94cbfab9b1ed33ef8d238ea168eb760", size = 6050, upload-time = "2025-03-19T20:10:01.071Z" },
52
- ]
53
-
54
- [[package]]
55
- name = "iniconfig"
56
- version = "2.3.0"
57
- source = { registry = "https://pypi.org/simple" }
58
- resolution-markers = [
59
- "python_full_version >= '3.10'",
60
- ]
61
- sdist = { url = "https://files.pythonhosted.org/packages/72/34/14ca021ce8e5dfedc35312d08ba8bf51fdd999c576889fc2c24cb97f4f10/iniconfig-2.3.0.tar.gz", hash = "sha256:c76315c77db068650d49c5b56314774a7804df16fee4402c1f19d6d15d8c4730", size = 20503, upload-time = "2025-10-18T21:55:43.219Z" }
62
- wheels = [
63
- { url = "https://files.pythonhosted.org/packages/cb/b1/3846dd7f199d53cb17f49cba7e651e9ce294d8497c8c150530ed11865bb8/iniconfig-2.3.0-py3-none-any.whl", hash = "sha256:f631c04d2c48c52b84d0d0549c99ff3859c98df65b3101406327ecc7d53fbf12", size = 7484, upload-time = "2025-10-18T21:55:41.639Z" },
64
- ]
65
-
66
- [[package]]
67
- name = "packaging"
68
- version = "26.2"
69
- source = { registry = "https://pypi.org/simple" }
70
- sdist = { url = "https://files.pythonhosted.org/packages/d7/f1/e7a6dd94a8d4a5626c03e4e99c87f241ba9e350cd9e6d75123f992427270/packaging-26.2.tar.gz", hash = "sha256:ff452ff5a3e828ce110190feff1178bb1f2ea2281fa2075aadb987c2fb221661", size = 228134, upload-time = "2026-04-24T20:15:23.917Z" }
71
- wheels = [
72
- { url = "https://files.pythonhosted.org/packages/df/b2/87e62e8c3e2f4b32e5fe99e0b86d576da1312593b39f47d8ceef365e95ed/packaging-26.2-py3-none-any.whl", hash = "sha256:5fc45236b9446107ff2415ce77c807cee2862cb6fac22b8a73826d0693b0980e", size = 100195, upload-time = "2026-04-24T20:15:22.081Z" },
73
- ]
74
-
75
- [[package]]
76
- name = "pluggy"
77
- version = "1.5.0"
78
- source = { registry = "https://pypi.org/simple" }
79
- resolution-markers = [
80
- "python_full_version < '3.9'",
81
- ]
82
- sdist = { url = "https://files.pythonhosted.org/packages/96/2d/02d4312c973c6050a18b314a5ad0b3210edb65a906f868e31c111dede4a6/pluggy-1.5.0.tar.gz", hash = "sha256:2cffa88e94fdc978c4c574f15f9e59b7f4201d439195c3715ca9e2486f1d0cf1", size = 67955, upload-time = "2024-04-20T21:34:42.531Z" }
83
- wheels = [
84
- { url = "https://files.pythonhosted.org/packages/88/5f/e351af9a41f866ac3f1fac4ca0613908d9a41741cfcf2228f4ad853b697d/pluggy-1.5.0-py3-none-any.whl", hash = "sha256:44e1ad92c8ca002de6377e165f3e0f1be63266ab4d554740532335b9d75ea669", size = 20556, upload-time = "2024-04-20T21:34:40.434Z" },
85
- ]
86
-
87
- [[package]]
88
- name = "pluggy"
89
- version = "1.6.0"
90
- source = { registry = "https://pypi.org/simple" }
91
- resolution-markers = [
92
- "python_full_version >= '3.10'",
93
- "python_full_version == '3.9.*'",
94
- ]
95
- sdist = { url = "https://files.pythonhosted.org/packages/f9/e2/3e91f31a7d2b083fe6ef3fa267035b518369d9511ffab804f839851d2779/pluggy-1.6.0.tar.gz", hash = "sha256:7dcc130b76258d33b90f61b658791dede3486c3e6bfb003ee5c9bfb396dd22f3", size = 69412, upload-time = "2025-05-15T12:30:07.975Z" }
96
- wheels = [
97
- { url = "https://files.pythonhosted.org/packages/54/20/4d324d65cc6d9205fabedc306948156824eb9f0ee1633355a8f7ec5c66bf/pluggy-1.6.0-py3-none-any.whl", hash = "sha256:e920276dd6813095e9377c0bc5566d94c932c33b27a3e3945d8389c374dd4746", size = 20538, upload-time = "2025-05-15T12:30:06.134Z" },
98
- ]
99
-
100
- [[package]]
101
- name = "pygments"
102
- version = "2.20.0"
103
- source = { registry = "https://pypi.org/simple" }
104
- sdist = { url = "https://files.pythonhosted.org/packages/c3/b2/bc9c9196916376152d655522fdcebac55e66de6603a76a02bca1b6414f6c/pygments-2.20.0.tar.gz", hash = "sha256:6757cd03768053ff99f3039c1a36d6c0aa0b263438fcab17520b30a303a82b5f", size = 4955991, upload-time = "2026-03-29T13:29:33.898Z" }
105
- wheels = [
106
- { url = "https://files.pythonhosted.org/packages/f4/7e/a72dd26f3b0f4f2bf1dd8923c85f7ceb43172af56d63c7383eb62b332364/pygments-2.20.0-py3-none-any.whl", hash = "sha256:81a9e26dd42fd28a23a2d169d86d7ac03b46e2f8b59ed4698fb4785f946d0176", size = 1231151, upload-time = "2026-03-29T13:29:30.038Z" },
107
- ]
108
-
109
- [[package]]
110
- name = "pytest"
111
- version = "8.3.5"
112
- source = { registry = "https://pypi.org/simple" }
113
- resolution-markers = [
114
- "python_full_version < '3.9'",
115
- ]
116
- dependencies = [
117
- { name = "colorama", marker = "sys_platform == 'win32'" },
118
- { name = "exceptiongroup" },
119
- { name = "iniconfig", version = "2.1.0", source = { registry = "https://pypi.org/simple" } },
120
- { name = "packaging" },
121
- { name = "pluggy", version = "1.5.0", source = { registry = "https://pypi.org/simple" } },
122
- { name = "tomli" },
123
- ]
124
- sdist = { url = "https://files.pythonhosted.org/packages/ae/3c/c9d525a414d506893f0cd8a8d0de7706446213181570cdbd766691164e40/pytest-8.3.5.tar.gz", hash = "sha256:f4efe70cc14e511565ac476b57c279e12a855b11f48f212af1080ef2263d3845", size = 1450891, upload-time = "2025-03-02T12:54:54.503Z" }
125
- wheels = [
126
- { url = "https://files.pythonhosted.org/packages/30/3d/64ad57c803f1fa1e963a7946b6e0fea4a70df53c1a7fed304586539c2bac/pytest-8.3.5-py3-none-any.whl", hash = "sha256:c69214aa47deac29fad6c2a4f590b9c4a9fdb16a403176fe154b79c0b4d4d820", size = 343634, upload-time = "2025-03-02T12:54:52.069Z" },
127
- ]
128
-
129
- [[package]]
130
- name = "pytest"
131
- version = "8.4.2"
132
- source = { registry = "https://pypi.org/simple" }
133
- resolution-markers = [
134
- "python_full_version == '3.9.*'",
135
- ]
136
- dependencies = [
137
- { name = "colorama", marker = "sys_platform == 'win32'" },
138
- { name = "exceptiongroup" },
139
- { name = "iniconfig", version = "2.1.0", source = { registry = "https://pypi.org/simple" } },
140
- { name = "packaging" },
141
- { name = "pluggy", version = "1.6.0", source = { registry = "https://pypi.org/simple" } },
142
- { name = "pygments" },
143
- { name = "tomli" },
144
- ]
145
- sdist = { url = "https://files.pythonhosted.org/packages/a3/5c/00a0e072241553e1a7496d638deababa67c5058571567b92a7eaa258397c/pytest-8.4.2.tar.gz", hash = "sha256:86c0d0b93306b961d58d62a4db4879f27fe25513d4b969df351abdddb3c30e01", size = 1519618, upload-time = "2025-09-04T14:34:22.711Z" }
146
- wheels = [
147
- { url = "https://files.pythonhosted.org/packages/a8/a4/20da314d277121d6534b3a980b29035dcd51e6744bd79075a6ce8fa4eb8d/pytest-8.4.2-py3-none-any.whl", hash = "sha256:872f880de3fc3a5bdc88a11b39c9710c3497a547cfa9320bc3c5e62fbf272e79", size = 365750, upload-time = "2025-09-04T14:34:20.226Z" },
148
- ]
149
-
150
- [[package]]
151
- name = "pytest"
152
- version = "9.1.1"
153
- source = { registry = "https://pypi.org/simple" }
154
- resolution-markers = [
155
- "python_full_version >= '3.10'",
156
- ]
157
- dependencies = [
158
- { name = "colorama", marker = "sys_platform == 'win32'" },
159
- { name = "exceptiongroup", marker = "python_full_version < '3.11'" },
160
- { name = "iniconfig", version = "2.3.0", source = { registry = "https://pypi.org/simple" } },
161
- { name = "packaging" },
162
- { name = "pluggy", version = "1.6.0", source = { registry = "https://pypi.org/simple" } },
163
- { name = "pygments" },
164
- { name = "tomli", marker = "python_full_version < '3.11'" },
165
- ]
166
- sdist = { url = "https://files.pythonhosted.org/packages/e4/47/b9efed96c114afcfa3c9d3fe98a76a1d14c74a9e266d397cf6eb64be5e01/pytest-9.1.1.tar.gz", hash = "sha256:1088fbde8f2b49d95a549a195707afa7a76a3ce9bcadc26b6d71f0ffda5fe313", size = 1636369, upload-time = "2026-06-19T10:58:32.857Z" }
167
- wheels = [
168
- { url = "https://files.pythonhosted.org/packages/24/25/1de2678b631f5a49215c6c96fff41ba892b0a34df68d6d80292b1b48aa7f/pytest-9.1.1-py3-none-any.whl", hash = "sha256:37a86b45efb9a47a61a36449063e8e18d0cab3161329fc099eb21783169c4f0c", size = 386536, upload-time = "2026-06-19T10:58:31.347Z" },
169
- ]
170
-
171
- [[package]]
172
- name = "pytest-timeout"
173
- version = "2.4.0"
174
- source = { registry = "https://pypi.org/simple" }
175
- dependencies = [
176
- { name = "pytest", version = "8.3.5", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.9'" },
177
- { name = "pytest", version = "8.4.2", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version == '3.9.*'" },
178
- { name = "pytest", version = "9.1.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.10'" },
179
- ]
180
- sdist = { url = "https://files.pythonhosted.org/packages/ac/82/4c9ecabab13363e72d880f2fb504c5f750433b2b6f16e99f4ec21ada284c/pytest_timeout-2.4.0.tar.gz", hash = "sha256:7e68e90b01f9eff71332b25001f85c75495fc4e3a836701876183c4bcfd0540a", size = 17973, upload-time = "2025-05-05T19:44:34.99Z" }
181
- wheels = [
182
- { url = "https://files.pythonhosted.org/packages/fa/b6/3127540ecdf1464a00e5a01ee60a1b09175f6913f0644ac748494d9c4b21/pytest_timeout-2.4.0-py3-none-any.whl", hash = "sha256:c42667e5cdadb151aeb5b26d114aff6bdf5a907f176a007a30b940d3d865b5c2", size = 14382, upload-time = "2025-05-05T19:44:33.502Z" },
183
- ]
184
-
185
- [[package]]
186
- name = "pytest-xdist"
187
- version = "3.6.1"
188
- source = { registry = "https://pypi.org/simple" }
189
- resolution-markers = [
190
- "python_full_version < '3.9'",
191
- ]
192
- dependencies = [
193
- { name = "execnet" },
194
- { name = "pytest", version = "8.3.5", source = { registry = "https://pypi.org/simple" } },
195
- ]
196
- sdist = { url = "https://files.pythonhosted.org/packages/41/c4/3c310a19bc1f1e9ef50075582652673ef2bfc8cd62afef9585683821902f/pytest_xdist-3.6.1.tar.gz", hash = "sha256:ead156a4db231eec769737f57668ef58a2084a34b2e55c4a8fa20d861107300d", size = 84060, upload-time = "2024-04-28T19:29:54.414Z" }
197
- wheels = [
198
- { url = "https://files.pythonhosted.org/packages/6d/82/1d96bf03ee4c0fdc3c0cbe61470070e659ca78dc0086fb88b66c185e2449/pytest_xdist-3.6.1-py3-none-any.whl", hash = "sha256:9ed4adfb68a016610848639bb7e02c9352d5d9f03d04809919e2dafc3be4cca7", size = 46108, upload-time = "2024-04-28T19:29:52.813Z" },
199
- ]
200
-
201
- [[package]]
202
- name = "pytest-xdist"
203
- version = "3.8.0"
204
- source = { registry = "https://pypi.org/simple" }
205
- resolution-markers = [
206
- "python_full_version >= '3.10'",
207
- "python_full_version == '3.9.*'",
208
- ]
209
- dependencies = [
210
- { name = "execnet" },
211
- { name = "pytest", version = "8.4.2", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.10'" },
212
- { name = "pytest", version = "9.1.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.10'" },
213
- ]
214
- sdist = { url = "https://files.pythonhosted.org/packages/78/b4/439b179d1ff526791eb921115fca8e44e596a13efeda518b9d845a619450/pytest_xdist-3.8.0.tar.gz", hash = "sha256:7e578125ec9bc6050861aa93f2d59f1d8d085595d6551c2c90b6f4fad8d3a9f1", size = 88069, upload-time = "2025-07-01T13:30:59.346Z" }
215
- wheels = [
216
- { url = "https://files.pythonhosted.org/packages/ca/31/d4e37e9e550c2b92a9cbc2e4d0b7420a27224968580b5a447f420847c975/pytest_xdist-3.8.0-py3-none-any.whl", hash = "sha256:202ca578cfeb7370784a8c33d6d05bc6e13b4f25b5053c30a152269fd10f0b88", size = 46396, upload-time = "2025-07-01T13:30:56.632Z" },
217
- ]
218
-
219
- [[package]]
220
- name = "tomli"
221
- version = "2.4.1"
222
- source = { registry = "https://pypi.org/simple" }
223
- sdist = { url = "https://files.pythonhosted.org/packages/22/de/48c59722572767841493b26183a0d1cc411d54fd759c5607c4590b6563a6/tomli-2.4.1.tar.gz", hash = "sha256:7c7e1a961a0b2f2472c1ac5b69affa0ae1132c39adcb67aba98568702b9cc23f", size = 17543, upload-time = "2026-03-25T20:22:03.828Z" }
224
- wheels = [
225
- { url = "https://files.pythonhosted.org/packages/f4/11/db3d5885d8528263d8adc260bb2d28ebf1270b96e98f0e0268d32b8d9900/tomli-2.4.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:f8f0fc26ec2cc2b965b7a3b87cd19c5c6b8c5e5f436b984e85f486d652285c30", size = 154704, upload-time = "2026-03-25T20:21:10.473Z" },
226
- { url = "https://files.pythonhosted.org/packages/6d/f7/675db52c7e46064a9aa928885a9b20f4124ecb9bc2e1ce74c9106648d202/tomli-2.4.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:4ab97e64ccda8756376892c53a72bd1f964e519c77236368527f758fbc36a53a", size = 149454, upload-time = "2026-03-25T20:21:12.036Z" },
227
- { url = "https://files.pythonhosted.org/packages/61/71/81c50943cf953efa35bce7646caab3cf457a7d8c030b27cfb40d7235f9ee/tomli-2.4.1-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:96481a5786729fd470164b47cdb3e0e58062a496f455ee41b4403be77cb5a076", size = 237561, upload-time = "2026-03-25T20:21:13.098Z" },
228
- { url = "https://files.pythonhosted.org/packages/48/c1/f41d9cb618acccca7df82aaf682f9b49013c9397212cb9f53219e3abac37/tomli-2.4.1-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:5a881ab208c0baf688221f8cecc5401bd291d67e38a1ac884d6736cbcd8247e9", size = 243824, upload-time = "2026-03-25T20:21:14.569Z" },
229
- { url = "https://files.pythonhosted.org/packages/22/e4/5a816ecdd1f8ca51fb756ef684b90f2780afc52fc67f987e3c61d800a46d/tomli-2.4.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:47149d5bd38761ac8be13a84864bf0b7b70bc051806bc3669ab1cbc56216b23c", size = 242227, upload-time = "2026-03-25T20:21:15.712Z" },
230
- { url = "https://files.pythonhosted.org/packages/6b/49/2b2a0ef529aa6eec245d25f0c703e020a73955ad7edf73e7f54ddc608aa5/tomli-2.4.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:ec9bfaf3ad2df51ace80688143a6a4ebc09a248f6ff781a9945e51937008fcbc", size = 247859, upload-time = "2026-03-25T20:21:17.001Z" },
231
- { url = "https://files.pythonhosted.org/packages/83/bd/6c1a630eaca337e1e78c5903104f831bda934c426f9231429396ce3c3467/tomli-2.4.1-cp311-cp311-win32.whl", hash = "sha256:ff2983983d34813c1aeb0fa89091e76c3a22889ee83ab27c5eeb45100560c049", size = 97204, upload-time = "2026-03-25T20:21:18.079Z" },
232
- { url = "https://files.pythonhosted.org/packages/42/59/71461df1a885647e10b6bb7802d0b8e66480c61f3f43079e0dcd315b3954/tomli-2.4.1-cp311-cp311-win_amd64.whl", hash = "sha256:5ee18d9ebdb417e384b58fe414e8d6af9f4e7a0ae761519fb50f721de398dd4e", size = 108084, upload-time = "2026-03-25T20:21:18.978Z" },
233
- { url = "https://files.pythonhosted.org/packages/b8/83/dceca96142499c069475b790e7913b1044c1a4337e700751f48ed723f883/tomli-2.4.1-cp311-cp311-win_arm64.whl", hash = "sha256:c2541745709bad0264b7d4705ad453b76ccd191e64aa6f0fc66b69a293a45ece", size = 95285, upload-time = "2026-03-25T20:21:20.309Z" },
234
- { url = "https://files.pythonhosted.org/packages/c1/ba/42f134a3fe2b370f555f44b1d72feebb94debcab01676bf918d0cb70e9aa/tomli-2.4.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:c742f741d58a28940ce01d58f0ab2ea3ced8b12402f162f4d534dfe18ba1cd6a", size = 155924, upload-time = "2026-03-25T20:21:21.626Z" },
235
- { url = "https://files.pythonhosted.org/packages/dc/c7/62d7a17c26487ade21c5422b646110f2162f1fcc95980ef7f63e73c68f14/tomli-2.4.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:7f86fd587c4ed9dd76f318225e7d9b29cfc5a9d43de44e5754db8d1128487085", size = 150018, upload-time = "2026-03-25T20:21:23.002Z" },
236
- { url = "https://files.pythonhosted.org/packages/5c/05/79d13d7c15f13bdef410bdd49a6485b1c37d28968314eabee452c22a7fda/tomli-2.4.1-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ff18e6a727ee0ab0388507b89d1bc6a22b138d1e2fa56d1ad494586d61d2eae9", size = 244948, upload-time = "2026-03-25T20:21:24.04Z" },
237
- { url = "https://files.pythonhosted.org/packages/10/90/d62ce007a1c80d0b2c93e02cab211224756240884751b94ca72df8a875ca/tomli-2.4.1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:136443dbd7e1dee43c68ac2694fde36b2849865fa258d39bf822c10e8068eac5", size = 253341, upload-time = "2026-03-25T20:21:25.177Z" },
238
- { url = "https://files.pythonhosted.org/packages/1a/7e/caf6496d60152ad4ed09282c1885cca4eea150bfd007da84aea07bcc0a3e/tomli-2.4.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:5e262d41726bc187e69af7825504c933b6794dc3fbd5945e41a79bb14c31f585", size = 248159, upload-time = "2026-03-25T20:21:26.364Z" },
239
- { url = "https://files.pythonhosted.org/packages/99/e7/c6f69c3120de34bbd882c6fba7975f3d7a746e9218e56ab46a1bc4b42552/tomli-2.4.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:5cb41aa38891e073ee49d55fbc7839cfdb2bc0e600add13874d048c94aadddd1", size = 253290, upload-time = "2026-03-25T20:21:27.46Z" },
240
- { url = "https://files.pythonhosted.org/packages/d6/2f/4a3c322f22c5c66c4b836ec58211641a4067364f5dcdd7b974b4c5da300c/tomli-2.4.1-cp312-cp312-win32.whl", hash = "sha256:da25dc3563bff5965356133435b757a795a17b17d01dbc0f42fb32447ddfd917", size = 98141, upload-time = "2026-03-25T20:21:28.492Z" },
241
- { url = "https://files.pythonhosted.org/packages/24/22/4daacd05391b92c55759d55eaee21e1dfaea86ce5c571f10083360adf534/tomli-2.4.1-cp312-cp312-win_amd64.whl", hash = "sha256:52c8ef851d9a240f11a88c003eacb03c31fc1c9c4ec64a99a0f922b93874fda9", size = 108847, upload-time = "2026-03-25T20:21:29.386Z" },
242
- { url = "https://files.pythonhosted.org/packages/68/fd/70e768887666ddd9e9f5d85129e84910f2db2796f9096aa02b721a53098d/tomli-2.4.1-cp312-cp312-win_arm64.whl", hash = "sha256:f758f1b9299d059cc3f6546ae2af89670cb1c4d48ea29c3cacc4fe7de3058257", size = 95088, upload-time = "2026-03-25T20:21:30.677Z" },
243
- { url = "https://files.pythonhosted.org/packages/07/06/b823a7e818c756d9a7123ba2cda7d07bc2dd32835648d1a7b7b7a05d848d/tomli-2.4.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:36d2bd2ad5fb9eaddba5226aa02c8ec3fa4f192631e347b3ed28186d43be6b54", size = 155866, upload-time = "2026-03-25T20:21:31.65Z" },
244
- { url = "https://files.pythonhosted.org/packages/14/6f/12645cf7f08e1a20c7eb8c297c6f11d31c1b50f316a7e7e1e1de6e2e7b7e/tomli-2.4.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:eb0dc4e38e6a1fd579e5d50369aa2e10acfc9cace504579b2faabb478e76941a", size = 149887, upload-time = "2026-03-25T20:21:33.028Z" },
245
- { url = "https://files.pythonhosted.org/packages/5c/e0/90637574e5e7212c09099c67ad349b04ec4d6020324539297b634a0192b0/tomli-2.4.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c7f2c7f2b9ca6bdeef8f0fa897f8e05085923eb091721675170254cbc5b02897", size = 243704, upload-time = "2026-03-25T20:21:34.51Z" },
246
- { url = "https://files.pythonhosted.org/packages/10/8f/d3ddb16c5a4befdf31a23307f72828686ab2096f068eaf56631e136c1fdd/tomli-2.4.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f3c6818a1a86dd6dca7ddcaaf76947d5ba31aecc28cb1b67009a5877c9a64f3f", size = 251628, upload-time = "2026-03-25T20:21:36.012Z" },
247
- { url = "https://files.pythonhosted.org/packages/e3/f1/dbeeb9116715abee2485bf0a12d07a8f31af94d71608c171c45f64c0469d/tomli-2.4.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:d312ef37c91508b0ab2cee7da26ec0b3ed2f03ce12bd87a588d771ae15dcf82d", size = 247180, upload-time = "2026-03-25T20:21:37.136Z" },
248
- { url = "https://files.pythonhosted.org/packages/d3/74/16336ffd19ed4da28a70959f92f506233bd7cfc2332b20bdb01591e8b1d1/tomli-2.4.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:51529d40e3ca50046d7606fa99ce3956a617f9b36380da3b7f0dd3dd28e68cb5", size = 251674, upload-time = "2026-03-25T20:21:38.298Z" },
249
- { url = "https://files.pythonhosted.org/packages/16/f9/229fa3434c590ddf6c0aa9af64d3af4b752540686cace29e6281e3458469/tomli-2.4.1-cp313-cp313-win32.whl", hash = "sha256:2190f2e9dd7508d2a90ded5ed369255980a1bcdd58e52f7fe24b8162bf9fedbd", size = 97976, upload-time = "2026-03-25T20:21:39.316Z" },
250
- { url = "https://files.pythonhosted.org/packages/6a/1e/71dfd96bcc1c775420cb8befe7a9d35f2e5b1309798f009dca17b7708c1e/tomli-2.4.1-cp313-cp313-win_amd64.whl", hash = "sha256:8d65a2fbf9d2f8352685bc1364177ee3923d6baf5e7f43ea4959d7d8bc326a36", size = 108755, upload-time = "2026-03-25T20:21:40.248Z" },
251
- { url = "https://files.pythonhosted.org/packages/83/7a/d34f422a021d62420b78f5c538e5b102f62bea616d1d75a13f0a88acb04a/tomli-2.4.1-cp313-cp313-win_arm64.whl", hash = "sha256:4b605484e43cdc43f0954ddae319fb75f04cc10dd80d830540060ee7cd0243cd", size = 95265, upload-time = "2026-03-25T20:21:41.219Z" },
252
- { url = "https://files.pythonhosted.org/packages/3c/fb/9a5c8d27dbab540869f7c1f8eb0abb3244189ce780ba9cd73f3770662072/tomli-2.4.1-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:fd0409a3653af6c147209d267a0e4243f0ae46b011aa978b1080359fddc9b6cf", size = 155726, upload-time = "2026-03-25T20:21:42.23Z" },
253
- { url = "https://files.pythonhosted.org/packages/62/05/d2f816630cc771ad836af54f5001f47a6f611d2d39535364f148b6a92d6b/tomli-2.4.1-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:a120733b01c45e9a0c34aeef92bf0cf1d56cfe81ed9d47d562f9ed591a9828ac", size = 149859, upload-time = "2026-03-25T20:21:43.386Z" },
254
- { url = "https://files.pythonhosted.org/packages/ce/48/66341bdb858ad9bd0ceab5a86f90eddab127cf8b046418009f2125630ecb/tomli-2.4.1-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:559db847dc486944896521f68d8190be1c9e719fced785720d2216fe7022b662", size = 244713, upload-time = "2026-03-25T20:21:44.474Z" },
255
- { url = "https://files.pythonhosted.org/packages/df/6d/c5fad00d82b3c7a3ab6189bd4b10e60466f22cfe8a08a9394185c8a8111c/tomli-2.4.1-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:01f520d4f53ef97964a240a035ec2a869fe1a37dde002b57ebc4417a27ccd853", size = 252084, upload-time = "2026-03-25T20:21:45.62Z" },
256
- { url = "https://files.pythonhosted.org/packages/00/71/3a69e86f3eafe8c7a59d008d245888051005bd657760e96d5fbfb0b740c2/tomli-2.4.1-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:7f94b27a62cfad8496c8d2513e1a222dd446f095fca8987fceef261225538a15", size = 247973, upload-time = "2026-03-25T20:21:46.937Z" },
257
- { url = "https://files.pythonhosted.org/packages/67/50/361e986652847fec4bd5e4a0208752fbe64689c603c7ae5ea7cb16b1c0ca/tomli-2.4.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:ede3e6487c5ef5d28634ba3f31f989030ad6af71edfb0055cbbd14189ff240ba", size = 256223, upload-time = "2026-03-25T20:21:48.467Z" },
258
- { url = "https://files.pythonhosted.org/packages/8c/9a/b4173689a9203472e5467217e0154b00e260621caa227b6fa01feab16998/tomli-2.4.1-cp314-cp314-win32.whl", hash = "sha256:3d48a93ee1c9b79c04bb38772ee1b64dcf18ff43085896ea460ca8dec96f35f6", size = 98973, upload-time = "2026-03-25T20:21:49.526Z" },
259
- { url = "https://files.pythonhosted.org/packages/14/58/640ac93bf230cd27d002462c9af0d837779f8773bc03dee06b5835208214/tomli-2.4.1-cp314-cp314-win_amd64.whl", hash = "sha256:88dceee75c2c63af144e456745e10101eb67361050196b0b6af5d717254dddf7", size = 109082, upload-time = "2026-03-25T20:21:50.506Z" },
260
- { url = "https://files.pythonhosted.org/packages/d5/2f/702d5e05b227401c1068f0d386d79a589bb12bf64c3d2c72ce0631e3bc49/tomli-2.4.1-cp314-cp314-win_arm64.whl", hash = "sha256:b8c198f8c1805dc42708689ed6864951fd2494f924149d3e4bce7710f8eb5232", size = 96490, upload-time = "2026-03-25T20:21:51.474Z" },
261
- { url = "https://files.pythonhosted.org/packages/45/4b/b877b05c8ba62927d9865dd980e34a755de541eb65fffba52b4cc495d4d2/tomli-2.4.1-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:d4d8fe59808a54658fcc0160ecfb1b30f9089906c50b23bcb4c69eddc19ec2b4", size = 164263, upload-time = "2026-03-25T20:21:52.543Z" },
262
- { url = "https://files.pythonhosted.org/packages/24/79/6ab420d37a270b89f7195dec5448f79400d9e9c1826df982f3f8e97b24fd/tomli-2.4.1-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:7008df2e7655c495dd12d2a4ad038ff878d4ca4b81fccaf82b714e07eae4402c", size = 160736, upload-time = "2026-03-25T20:21:53.674Z" },
263
- { url = "https://files.pythonhosted.org/packages/02/e0/3630057d8eb170310785723ed5adcdfb7d50cb7e6455f85ba8a3deed642b/tomli-2.4.1-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1d8591993e228b0c930c4bb0db464bdad97b3289fb981255d6c9a41aedc84b2d", size = 270717, upload-time = "2026-03-25T20:21:55.129Z" },
264
- { url = "https://files.pythonhosted.org/packages/7a/b4/1613716072e544d1a7891f548d8f9ec6ce2faf42ca65acae01d76ea06bb0/tomli-2.4.1-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:734e20b57ba95624ecf1841e72b53f6e186355e216e5412de414e3c51e5e3c41", size = 278461, upload-time = "2026-03-25T20:21:56.228Z" },
265
- { url = "https://files.pythonhosted.org/packages/05/38/30f541baf6a3f6df77b3df16b01ba319221389e2da59427e221ef417ac0c/tomli-2.4.1-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:8a650c2dbafa08d42e51ba0b62740dae4ecb9338eefa093aa5c78ceb546fcd5c", size = 274855, upload-time = "2026-03-25T20:21:57.653Z" },
266
- { url = "https://files.pythonhosted.org/packages/77/a3/ec9dd4fd2c38e98de34223b995a3b34813e6bdadf86c75314c928350ed14/tomli-2.4.1-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:504aa796fe0569bb43171066009ead363de03675276d2d121ac1a4572397870f", size = 283144, upload-time = "2026-03-25T20:21:59.089Z" },
267
- { url = "https://files.pythonhosted.org/packages/ef/be/605a6261cac79fba2ec0c9827e986e00323a1945700969b8ee0b30d85453/tomli-2.4.1-cp314-cp314t-win32.whl", hash = "sha256:b1d22e6e9387bf4739fbe23bfa80e93f6b0373a7f1b96c6227c32bef95a4d7a8", size = 108683, upload-time = "2026-03-25T20:22:00.214Z" },
268
- { url = "https://files.pythonhosted.org/packages/12/64/da524626d3b9cc40c168a13da8335fe1c51be12c0a63685cc6db7308daae/tomli-2.4.1-cp314-cp314t-win_amd64.whl", hash = "sha256:2c1c351919aca02858f740c6d33adea0c5deea37f9ecca1cc1ef9e884a619d26", size = 121196, upload-time = "2026-03-25T20:22:01.169Z" },
269
- { url = "https://files.pythonhosted.org/packages/5a/cd/e80b62269fc78fc36c9af5a6b89c835baa8af28ff5ad28c7028d60860320/tomli-2.4.1-cp314-cp314t-win_arm64.whl", hash = "sha256:eab21f45c7f66c13f2a9e0e1535309cee140182a9cdae1e041d02e47291e8396", size = 100393, upload-time = "2026-03-25T20:22:02.137Z" },
270
- { url = "https://files.pythonhosted.org/packages/7b/61/cceae43728b7de99d9b847560c262873a1f6c98202171fd5ed62640b494b/tomli-2.4.1-py3-none-any.whl", hash = "sha256:0d85819802132122da43cb86656f8d1f8c6587d54ae7dcaf30e90533028b49fe", size = 14583, upload-time = "2026-03-25T20:22:03.012Z" },
271
- ]
272
-
273
- [[package]]
274
- name = "typing-extensions"
275
- version = "4.13.2"
276
- source = { registry = "https://pypi.org/simple" }
277
- resolution-markers = [
278
- "python_full_version < '3.9'",
279
- ]
280
- sdist = { url = "https://files.pythonhosted.org/packages/f6/37/23083fcd6e35492953e8d2aaaa68b860eb422b34627b13f2ce3eb6106061/typing_extensions-4.13.2.tar.gz", hash = "sha256:e6c81219bd689f51865d9e372991c540bda33a0379d5573cddb9a3a23f7caaef", size = 106967, upload-time = "2025-04-10T14:19:05.416Z" }
281
- wheels = [
282
- { url = "https://files.pythonhosted.org/packages/8b/54/b1ae86c0973cc6f0210b53d508ca3641fb6d0c56823f288d108bc7ab3cc8/typing_extensions-4.13.2-py3-none-any.whl", hash = "sha256:a439e7c04b49fec3e5d3e2beaa21755cadbbdc391694e28ccdd36ca4a1408f8c", size = 45806, upload-time = "2025-04-10T14:19:03.967Z" },
283
- ]
284
-
285
- [[package]]
286
- name = "typing-extensions"
287
- version = "4.15.0"
288
- source = { registry = "https://pypi.org/simple" }
289
- resolution-markers = [
290
- "python_full_version >= '3.10'",
291
- "python_full_version == '3.9.*'",
292
- ]
293
- sdist = { url = "https://files.pythonhosted.org/packages/72/94/1a15dd82efb362ac84269196e94cf00f187f7ed21c242792a923cdb1c61f/typing_extensions-4.15.0.tar.gz", hash = "sha256:0cea48d173cc12fa28ecabc3b837ea3cf6f38c6d1136f85cbaaf598984861466", size = 109391, upload-time = "2025-08-25T13:49:26.313Z" }
294
- wheels = [
295
- { url = "https://files.pythonhosted.org/packages/18/67/36e9267722cc04a6b9f15c7f3441c2363321a3ea07da7ae0c0707beb2a9c/typing_extensions-4.15.0-py3-none-any.whl", hash = "sha256:f0fa19c6845758ab08074a0cfa8b7aecb71c999ca73d62883bc25cc018c4e548", size = 44614, upload-time = "2025-08-25T13:49:24.86Z" },
296
- ]
297
-
298
- [[package]]
299
- name = "vcs-versioning"
300
- source = { editable = "." }
301
- dependencies = [
302
- { name = "packaging" },
303
- { name = "tomli", marker = "python_full_version < '3.11'" },
304
- { name = "typing-extensions", version = "4.13.2", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.9'" },
305
- { name = "typing-extensions", version = "4.15.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.9' and python_full_version < '3.11'" },
306
- ]
307
-
308
- [package.dev-dependencies]
309
- test = [
310
- { name = "pytest", version = "8.3.5", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.9'" },
311
- { name = "pytest", version = "8.4.2", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version == '3.9.*'" },
312
- { name = "pytest", version = "9.1.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.10'" },
313
- { name = "pytest-timeout" },
314
- { name = "pytest-xdist", version = "3.6.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.9'" },
315
- { name = "pytest-xdist", version = "3.8.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.9'" },
316
- ]
317
-
318
- [package.metadata]
319
- requires-dist = [
320
- { name = "packaging", specifier = ">=26.2" },
321
- { name = "tomli", marker = "python_full_version < '3.11'", specifier = ">=1" },
322
- { name = "typing-extensions", marker = "python_full_version < '3.11'", specifier = ">=4.1" },
323
- ]
324
-
325
- [package.metadata.requires-dev]
326
- test = [
327
- { name = "pytest" },
328
- { name = "pytest-timeout" },
329
- { name = "pytest-xdist" },
330
- ]
File without changes
File without changes
File without changes