pathlib-next 0.9.2__tar.gz → 0.9.4__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 (181) hide show
  1. pathlib_next-0.9.4/.gitignore +43 -0
  2. pathlib_next-0.9.4/AGENTS.md +116 -0
  3. {pathlib_next-0.9.2 → pathlib_next-0.9.4}/CHANGELOG.md +498 -4
  4. pathlib_next-0.9.4/PKG-INFO +283 -0
  5. pathlib_next-0.9.4/README.md +215 -0
  6. pathlib_next-0.9.4/docs/api/cli.md +6 -0
  7. pathlib_next-0.9.4/docs/api/mempath.md +6 -0
  8. pathlib_next-0.9.4/docs/api/protocols.md +11 -0
  9. pathlib_next-0.9.4/docs/api/schemes/archive.md +11 -0
  10. pathlib_next-0.9.4/docs/api/schemes/ftp.md +9 -0
  11. pathlib_next-0.9.4/docs/api/schemes/git.md +26 -0
  12. pathlib_next-0.9.4/docs/api/schemes/http.md +17 -0
  13. pathlib_next-0.9.4/docs/api/schemes/local.md +8 -0
  14. pathlib_next-0.9.4/docs/api/schemes/objstore.md +30 -0
  15. pathlib_next-0.9.4/docs/api/schemes/sftp.md +14 -0
  16. pathlib_next-0.9.4/docs/api/uri.md +19 -0
  17. {pathlib_next-0.9.2 → pathlib_next-0.9.4}/docs/api/utils.md +9 -2
  18. pathlib_next-0.9.4/docs/benchmarks.md +249 -0
  19. {pathlib_next-0.9.2 → pathlib_next-0.9.4}/docs/divergences.md +37 -17
  20. pathlib_next-0.9.4/docs/guides/cli.md +55 -0
  21. pathlib_next-0.9.4/docs/guides/extending.md +200 -0
  22. pathlib_next-0.9.4/docs/guides/schemes.md +248 -0
  23. pathlib_next-0.9.4/docs/index.md +110 -0
  24. {pathlib_next-0.9.2 → pathlib_next-0.9.4}/examples/az_listing.py +4 -1
  25. {pathlib_next-0.9.2 → pathlib_next-0.9.4}/examples/data_and_archive.py +6 -5
  26. {pathlib_next-0.9.2 → pathlib_next-0.9.4}/examples/ftp_listing.py +20 -8
  27. {pathlib_next-0.9.2 → pathlib_next-0.9.4}/examples/github_listing.py +5 -1
  28. {pathlib_next-0.9.2 → pathlib_next-0.9.4}/examples/gitlab_listing.py +5 -1
  29. {pathlib_next-0.9.2 → pathlib_next-0.9.4}/examples/gs_listing.py +4 -1
  30. {pathlib_next-0.9.2 → pathlib_next-0.9.4}/examples/http_listing.py +7 -6
  31. {pathlib_next-0.9.2 → pathlib_next-0.9.4}/examples/local_and_mem.py +1 -0
  32. {pathlib_next-0.9.2 → pathlib_next-0.9.4}/examples/s3_listing.py +5 -1
  33. {pathlib_next-0.9.2 → pathlib_next-0.9.4}/examples/sftp_sync.py +19 -7
  34. {pathlib_next-0.9.2 → pathlib_next-0.9.4}/examples/webdav_roundtrip.py +27 -17
  35. {pathlib_next-0.9.2 → pathlib_next-0.9.4}/mkdocs.yml +11 -1
  36. {pathlib_next-0.9.2 → pathlib_next-0.9.4}/pyproject.toml +25 -8
  37. pathlib_next-0.9.4/src/pathlib_next/AGENTS.md +653 -0
  38. {pathlib_next-0.9.2 → pathlib_next-0.9.4}/src/pathlib_next/fspath.py +195 -12
  39. pathlib_next-0.9.4/src/pathlib_next/mempath.py +349 -0
  40. {pathlib_next-0.9.2 → pathlib_next-0.9.4}/src/pathlib_next/path.py +601 -104
  41. {pathlib_next-0.9.2 → pathlib_next-0.9.4}/src/pathlib_next/protocols/checksum.py +2 -2
  42. {pathlib_next-0.9.2 → pathlib_next-0.9.4}/src/pathlib_next/protocols/fs.py +12 -8
  43. pathlib_next-0.9.4/src/pathlib_next/protocols/io.py +198 -0
  44. pathlib_next-0.9.4/src/pathlib_next/testing.py +557 -0
  45. pathlib_next-0.9.4/src/pathlib_next/tools/uripath.py +360 -0
  46. {pathlib_next-0.9.2 → pathlib_next-0.9.4}/src/pathlib_next/uri/__init__.py +325 -42
  47. {pathlib_next-0.9.2 → pathlib_next-0.9.4}/src/pathlib_next/uri/query.py +10 -2
  48. pathlib_next-0.9.4/src/pathlib_next/uri/schemes/__init__.py +72 -0
  49. pathlib_next-0.9.4/src/pathlib_next/uri/schemes/_gitrepo.py +255 -0
  50. pathlib_next-0.9.4/src/pathlib_next/uri/schemes/archive/_base.py +541 -0
  51. pathlib_next-0.9.4/src/pathlib_next/uri/schemes/archive/tar.py +89 -0
  52. pathlib_next-0.9.4/src/pathlib_next/uri/schemes/archive/zip.py +346 -0
  53. pathlib_next-0.9.4/src/pathlib_next/uri/schemes/az.py +544 -0
  54. {pathlib_next-0.9.2 → pathlib_next-0.9.4}/src/pathlib_next/uri/schemes/data.py +24 -9
  55. pathlib_next-0.9.4/src/pathlib_next/uri/schemes/dav.py +397 -0
  56. pathlib_next-0.9.4/src/pathlib_next/uri/schemes/file.py +136 -0
  57. pathlib_next-0.9.4/src/pathlib_next/uri/schemes/ftp.py +593 -0
  58. pathlib_next-0.9.4/src/pathlib_next/uri/schemes/git/_base.py +50 -0
  59. {pathlib_next-0.9.2 → pathlib_next-0.9.4}/src/pathlib_next/uri/schemes/github.py +70 -24
  60. pathlib_next-0.9.4/src/pathlib_next/uri/schemes/gitlab.py +230 -0
  61. pathlib_next-0.9.4/src/pathlib_next/uri/schemes/gs.py +419 -0
  62. {pathlib_next-0.9.2 → pathlib_next-0.9.4}/src/pathlib_next/uri/schemes/http.py +383 -69
  63. pathlib_next-0.9.4/src/pathlib_next/uri/schemes/s3.py +590 -0
  64. {pathlib_next-0.9.2 → pathlib_next-0.9.4}/src/pathlib_next/uri/schemes/sftp/__init__.py +258 -37
  65. {pathlib_next-0.9.2 → pathlib_next-0.9.4}/src/pathlib_next/uri/schemes/sftp/_asyncssh.py +387 -122
  66. pathlib_next-0.9.4/src/pathlib_next/uri/schemes/sftp/_paramiko.py +426 -0
  67. pathlib_next-0.9.4/src/pathlib_next/uri/schemes/sftp/_sshconfig.py +77 -0
  68. {pathlib_next-0.9.2 → pathlib_next-0.9.4}/src/pathlib_next/uri/source.py +85 -10
  69. {pathlib_next-0.9.2 → pathlib_next-0.9.4}/src/pathlib_next/utils/__init__.py +129 -14
  70. pathlib_next-0.9.4/src/pathlib_next/utils/archive.py +235 -0
  71. {pathlib_next-0.9.2 → pathlib_next-0.9.4}/src/pathlib_next/utils/checksum.py +7 -17
  72. pathlib_next-0.9.4/src/pathlib_next/utils/glob.py +302 -0
  73. {pathlib_next-0.9.2 → pathlib_next-0.9.4}/src/pathlib_next/utils/stat.py +27 -5
  74. pathlib_next-0.9.4/src/pathlib_next/utils/sync.py +1057 -0
  75. {pathlib_next-0.9.2 → pathlib_next-0.9.4}/tests/conftest.py +316 -103
  76. pathlib_next-0.9.4/tests/test_archive_parity.py +483 -0
  77. pathlib_next-0.9.4/tests/test_archive_safety.py +589 -0
  78. {pathlib_next-0.9.2 → pathlib_next-0.9.4}/tests/test_archive_uri.py +17 -0
  79. {pathlib_next-0.9.2 → pathlib_next-0.9.4}/tests/test_az.py +4 -4
  80. pathlib_next-0.9.4/tests/test_az_fake.py +619 -0
  81. {pathlib_next-0.9.2 → pathlib_next-0.9.4}/tests/test_checksum.py +24 -0
  82. {pathlib_next-0.9.2 → pathlib_next-0.9.4}/tests/test_contract.py +81 -29
  83. pathlib_next-0.9.4/tests/test_contract_helpers.py +180 -0
  84. pathlib_next-0.9.4/tests/test_destructive_safety.py +328 -0
  85. {pathlib_next-0.9.2 → pathlib_next-0.9.4}/tests/test_ftp.py +79 -0
  86. pathlib_next-0.9.4/tests/test_ftp_objstore_parity.py +578 -0
  87. pathlib_next-0.9.4/tests/test_gitrepo.py +698 -0
  88. {pathlib_next-0.9.2 → pathlib_next-0.9.4}/tests/test_glob.py +9 -10
  89. pathlib_next-0.9.4/tests/test_glob_parity.py +305 -0
  90. {pathlib_next-0.9.2 → pathlib_next-0.9.4}/tests/test_gs.py +23 -4
  91. pathlib_next-0.9.4/tests/test_gs_fake.py +532 -0
  92. {pathlib_next-0.9.2 → pathlib_next-0.9.4}/tests/test_http.py +217 -10
  93. pathlib_next-0.9.4/tests/test_httpdav_safety.py +505 -0
  94. pathlib_next-0.9.4/tests/test_io_parity.py +296 -0
  95. pathlib_next-0.9.4/tests/test_low_core.py +659 -0
  96. pathlib_next-0.9.4/tests/test_low_schemes.py +358 -0
  97. pathlib_next-0.9.4/tests/test_low_sync.py +469 -0
  98. {pathlib_next-0.9.2 → pathlib_next-0.9.4}/tests/test_mempath.py +54 -2
  99. {pathlib_next-0.9.2 → pathlib_next-0.9.4}/tests/test_mro_precedence.py +43 -1
  100. {pathlib_next-0.9.2 → pathlib_next-0.9.4}/tests/test_parity_io.py +6 -2
  101. {pathlib_next-0.9.2 → pathlib_next-0.9.4}/tests/test_path_gaps.py +150 -0
  102. {pathlib_next-0.9.2 → pathlib_next-0.9.4}/tests/test_pathname.py +45 -9
  103. {pathlib_next-0.9.2 → pathlib_next-0.9.4}/tests/test_plugins.py +28 -4
  104. {pathlib_next-0.9.2 → pathlib_next-0.9.4}/tests/test_properties.py +165 -21
  105. pathlib_next-0.9.4/tests/test_pure_parity.py +664 -0
  106. pathlib_next-0.9.4/tests/test_routing.py +316 -0
  107. {pathlib_next-0.9.2 → pathlib_next-0.9.4}/tests/test_s3.py +159 -1
  108. {pathlib_next-0.9.2 → pathlib_next-0.9.4}/tests/test_sftp.py +493 -45
  109. {pathlib_next-0.9.2 → pathlib_next-0.9.4}/tests/test_sftp_asyncssh.py +272 -5
  110. pathlib_next-0.9.4/tests/test_sftp_transport.py +875 -0
  111. pathlib_next-0.9.4/tests/test_smoke.py +250 -0
  112. {pathlib_next-0.9.2 → pathlib_next-0.9.4}/tests/test_source.py +36 -1
  113. {pathlib_next-0.9.2 → pathlib_next-0.9.4}/tests/test_sync.py +4 -116
  114. pathlib_next-0.9.4/tests/test_sync_safety.py +896 -0
  115. pathlib_next-0.9.4/tests/test_sync_sftp.py +142 -0
  116. pathlib_next-0.9.4/tests/test_sync_sftp_parity.py +508 -0
  117. pathlib_next-0.9.4/tests/test_transport_security.py +635 -0
  118. pathlib_next-0.9.4/tests/test_uri_core_parity.py +375 -0
  119. {pathlib_next-0.9.2 → pathlib_next-0.9.4}/tests/test_uri_parse.py +8 -2
  120. {pathlib_next-0.9.2 → pathlib_next-0.9.4}/tests/test_uri_path.py +58 -0
  121. pathlib_next-0.9.4/tests/test_uripath_tool.py +393 -0
  122. {pathlib_next-0.9.2 → pathlib_next-0.9.4}/tests/test_utils.py +45 -5
  123. {pathlib_next-0.9.2 → pathlib_next-0.9.4}/tests/test_walk.py +0 -2
  124. {pathlib_next-0.9.2 → pathlib_next-0.9.4}/tests/test_webdav.py +118 -0
  125. pathlib_next-0.9.2/.gitignore +0 -29
  126. pathlib_next-0.9.2/PKG-INFO +0 -255
  127. pathlib_next-0.9.2/README.md +0 -196
  128. pathlib_next-0.9.2/docs/api/mempath.md +0 -3
  129. pathlib_next-0.9.2/docs/api/uri.md +0 -5
  130. pathlib_next-0.9.2/docs/benchmarks.md +0 -238
  131. pathlib_next-0.9.2/docs/guides/cli.md +0 -34
  132. pathlib_next-0.9.2/docs/guides/extending.md +0 -171
  133. pathlib_next-0.9.2/docs/guides/schemes.md +0 -133
  134. pathlib_next-0.9.2/docs/index.md +0 -99
  135. pathlib_next-0.9.2/src/pathlib_next/AGENTS.md +0 -407
  136. pathlib_next-0.9.2/src/pathlib_next/mempath.py +0 -237
  137. pathlib_next-0.9.2/src/pathlib_next/protocols/io.py +0 -125
  138. pathlib_next-0.9.2/src/pathlib_next/testing.py +0 -198
  139. pathlib_next-0.9.2/src/pathlib_next/tools/uripath.py +0 -180
  140. pathlib_next-0.9.2/src/pathlib_next/uri/schemes/__init__.py +0 -34
  141. pathlib_next-0.9.2/src/pathlib_next/uri/schemes/_gitrepo.py +0 -133
  142. pathlib_next-0.9.2/src/pathlib_next/uri/schemes/archive/_base.py +0 -297
  143. pathlib_next-0.9.2/src/pathlib_next/uri/schemes/archive/tar.py +0 -42
  144. pathlib_next-0.9.2/src/pathlib_next/uri/schemes/archive/zip.py +0 -160
  145. pathlib_next-0.9.2/src/pathlib_next/uri/schemes/az.py +0 -306
  146. pathlib_next-0.9.2/src/pathlib_next/uri/schemes/dav.py +0 -225
  147. pathlib_next-0.9.2/src/pathlib_next/uri/schemes/file.py +0 -84
  148. pathlib_next-0.9.2/src/pathlib_next/uri/schemes/ftp.py +0 -245
  149. pathlib_next-0.9.2/src/pathlib_next/uri/schemes/git/_base.py +0 -39
  150. pathlib_next-0.9.2/src/pathlib_next/uri/schemes/gitlab.py +0 -131
  151. pathlib_next-0.9.2/src/pathlib_next/uri/schemes/gs.py +0 -255
  152. pathlib_next-0.9.2/src/pathlib_next/uri/schemes/s3.py +0 -265
  153. pathlib_next-0.9.2/src/pathlib_next/uri/schemes/sftp/_paramiko.py +0 -239
  154. pathlib_next-0.9.2/src/pathlib_next/uri/schemes/sftp/_sshconfig.py +0 -34
  155. pathlib_next-0.9.2/src/pathlib_next/utils/archive.py +0 -156
  156. pathlib_next-0.9.2/src/pathlib_next/utils/glob.py +0 -176
  157. pathlib_next-0.9.2/src/pathlib_next/utils/sync.py +0 -617
  158. pathlib_next-0.9.2/tests/test_az_fake.py +0 -164
  159. pathlib_next-0.9.2/tests/test_gitrepo.py +0 -295
  160. pathlib_next-0.9.2/tests/test_gs_fake.py +0 -145
  161. pathlib_next-0.9.2/tests/test_smoke.py +0 -140
  162. pathlib_next-0.9.2/tests/test_uripath_tool.py +0 -90
  163. {pathlib_next-0.9.2 → pathlib_next-0.9.4}/LICENSE +0 -0
  164. {pathlib_next-0.9.2 → pathlib_next-0.9.4}/docs/api/path.md +0 -0
  165. {pathlib_next-0.9.2 → pathlib_next-0.9.4}/docs/api/testing.md +0 -0
  166. {pathlib_next-0.9.2 → pathlib_next-0.9.4}/docs/changelog.md +0 -0
  167. {pathlib_next-0.9.2 → pathlib_next-0.9.4}/src/pathlib_next/__init__.py +0 -0
  168. {pathlib_next-0.9.2 → pathlib_next-0.9.4}/src/pathlib_next/protocols/__init__.py +0 -0
  169. {pathlib_next-0.9.2 → pathlib_next-0.9.4}/src/pathlib_next/py.typed +0 -0
  170. {pathlib_next-0.9.2 → pathlib_next-0.9.4}/src/pathlib_next/tools/__init__.py +0 -0
  171. {pathlib_next-0.9.2 → pathlib_next-0.9.4}/src/pathlib_next/uri/schemes/archive/__init__.py +0 -0
  172. {pathlib_next-0.9.2 → pathlib_next-0.9.4}/src/pathlib_next/uri/schemes/git/__init__.py +0 -0
  173. {pathlib_next-0.9.2 → pathlib_next-0.9.4}/src/pathlib_next/uri/schemes/git/github.py +0 -0
  174. {pathlib_next-0.9.2 → pathlib_next-0.9.4}/src/pathlib_next/uri/schemes/git/gitlab.py +0 -0
  175. {pathlib_next-0.9.2 → pathlib_next-0.9.4}/tests/test_data_uri.py +0 -0
  176. {pathlib_next-0.9.2 → pathlib_next-0.9.4}/tests/test_dav.py +0 -0
  177. {pathlib_next-0.9.2 → pathlib_next-0.9.4}/tests/test_http_live.py +0 -0
  178. {pathlib_next-0.9.2 → pathlib_next-0.9.4}/tests/test_http_parser.py +0 -0
  179. {pathlib_next-0.9.2 → pathlib_next-0.9.4}/tests/test_local.py +0 -0
  180. {pathlib_next-0.9.2 → pathlib_next-0.9.4}/tests/test_parity_pure.py +0 -0
  181. {pathlib_next-0.9.2 → pathlib_next-0.9.4}/tests/test_query.py +0 -0
@@ -0,0 +1,43 @@
1
+ # Category rule: nothing dot-prefixed at the repo root gets tracked except the
2
+ # files re-included below (a category beats a list). Root-anchored on purpose;
3
+ # nested dotfiles are governed by the specific rules further down.
4
+ /.*
5
+ !/.gitignore
6
+ !/.gitattributes
7
+ !/.github/
8
+ # Shared editor settings (black on save, pytest discovery, build task) are
9
+ # tracked deliberately.
10
+ !/.vscode/
11
+
12
+ # Private agent config. No trailing slash on `.agents` on purpose: it may be a
13
+ # symlink, which git treats as a file, so a directory-only `.agents/` would not
14
+ # match it. These stay even though /.* covers the root: they also catch nested
15
+ # copies. *.local.* is an unshared, machine- or user-specific override and is
16
+ # never committed (it is also excluded from the build in pyproject.toml).
17
+ .agents
18
+ *.local.*
19
+ CLAUDE*
20
+ .claude
21
+
22
+ # Build/dist output and generated docs site
23
+ build/
24
+ dist/
25
+ site/
26
+
27
+ # Python
28
+ __pycache__/
29
+ *.py[cod]
30
+ .pytest_cache/
31
+ .hypothesis/
32
+ .mypy_cache/
33
+ .ruff_cache/
34
+ .coverage*
35
+ htmlcov/
36
+ *.egg-info/
37
+ .venv/
38
+ .pyvenv/
39
+
40
+ # OS/editor
41
+ .DS_Store
42
+ Thumbs.db
43
+ .idea/
@@ -0,0 +1,116 @@
1
+ # pathlib_next — contributor orientation
2
+
3
+ Orientation for working in a checkout of this repository: layout, environments,
4
+ commands, CI and release. It is not the API reference and it does not ship.
5
+
6
+ - **Public API contract** (every export, signature and gotcha):
7
+ [`src/pathlib_next/AGENTS.md`](src/pathlib_next/AGENTS.md). That file ships in
8
+ the wheel, so it must stay self-contained (no repo-relative links) and must be
9
+ updated in the same commit as any public API change.
10
+ - **Deliberate differences from `pathlib.Path`**:
11
+ [`docs/divergences.md`](docs/divergences.md). `pathlib.Path` parity is the
12
+ contract; a behavioral divergence that is not recorded there is a bug.
13
+
14
+ ## Layout
15
+
16
+ | Path | Contents |
17
+ | --- | --- |
18
+ | `src/pathlib_next/` | The package (`src/` layout). `py.typed` and the API header ship with it. |
19
+ | `src/pathlib_next/uri/schemes/` | One module per URI scheme; registered through the `pathlib_next.schemes` entry points in `pyproject.toml`. |
20
+ | `tests/` | The pytest suite. |
21
+ | `benchmarks/` | `bench.py` and committed JSON results; see [`benchmarks/README.md`](benchmarks/README.md). Not shipped. |
22
+ | `examples/` | Runnable scripts. Networked ones skip (exit 0) unless their environment variables are set. |
23
+ | `docs/`, `mkdocs.yml` | MkDocs site: hand-written pages plus a `mkdocstrings` API reference. |
24
+ | `CHANGELOG.md` | Keep a Changelog. Released sections are frozen records. |
25
+
26
+ ## Environments
27
+
28
+ Python 3.9 is the floor (`requires-python = ">=3.9"`) and 3.14 is the latest
29
+ supported. Test on both ends before claiming a change works.
30
+
31
+ Keep one virtualenv per interpreter under `.venv/<version>-<os>-<arch>/`
32
+ (gitignored), where `<os>` is `os.name` (`nt`/`posix`) or `darwin`, and `<arch>`
33
+ is the architecture the interpreter was built for:
34
+
35
+ ```bash
36
+ python -m venv .venv/3.14-posix-x86_64
37
+ .venv/3.14-posix-x86_64/bin/python -m pip install -e ".[dev,docs,uri,http,sftp,sftp-async,s3,gs,az]"
38
+ ```
39
+
40
+ On Windows the interpreter is `.venv\<name>\Scripts\python.exe`.
41
+
42
+ Install every extra that has tests. A missing extra does not fail the suite:
43
+ its tests are skipped instead, so check `pytest -rs` before trusting a green run.
44
+ The `gs`/`az` SDKs are the ones most likely to be unavailable for an older
45
+ interpreter or a less common platform; without them their contract suites skip.
46
+
47
+ ## Everyday commands
48
+
49
+ ```bash
50
+ python -m pytest -q # full suite (pythonpath=src is configured)
51
+ python -m pytest -q --cov=pathlib_next --cov-report=term-missing
52
+ python -m black src/ tests/ benchmarks/ examples/ # formatting; --check to verify
53
+ mkdocs build --strict # docs must build with no warnings
54
+ python -m build # sdist + wheel into dist/
55
+ ```
56
+
57
+ - **Formatting is black**, pinned to `target-version = ["py39"]` so it never
58
+ emits syntax the floor cannot parse. No linter or type checker is enforced.
59
+ - **Every file is LF** (`.gitattributes` sets `* text=auto eol=lf`). On Windows,
60
+ black writes CRLF: convert the files back to LF after formatting and check
61
+ `git diff --stat` for whitespace-only churn.
62
+ - **3.9 compatibility**: any module using `X | Y` in a runtime-evaluated
63
+ annotation needs `from __future__ import annotations`.
64
+ - **`*.local.*` files** are per-machine overrides: gitignored and excluded from
65
+ both build targets. Keep hostnames and credentials in those, never in tracked
66
+ files.
67
+
68
+ ## Benchmarks
69
+
70
+ `python benchmarks/bench.py --help` lists the suites. `--save` writes a JSON
71
+ result per (version, interpreter, platform) into `benchmarks/results/`; the
72
+ schema and the reproduce command are in
73
+ [`benchmarks/README.md`](benchmarks/README.md). A local run is a sanity check;
74
+ performance claims in the changelog or release notes come from CI runs.
75
+
76
+ ## CI
77
+
78
+ Workflows live in `.github/workflows/`:
79
+
80
+ - `test.yml` runs on `workflow_dispatch` (optional `ref` input) or on a pushed
81
+ `ci-*` tag, never on ordinary pushes. To test a commit without the dashboard,
82
+ push a uniquely named throwaway tag (`ci-<topic>-<timestamp>`), follow the run
83
+ to completion, then delete the tag locally and on the remote.
84
+ - `release.yml` runs on a `v*` tag: test gate, build, PyPI publish through
85
+ Trusted Publishing, and a GitHub release whose notes come from that
86
+ version's `CHANGELOG.md` section. Its docs job only checks that the site
87
+ builds strictly; it never deploys.
88
+ - `docs.yml` owns every GitHub Pages deploy: on a published release, on a push
89
+ to `main` that touches the docs sources, and on `workflow_dispatch`.
90
+
91
+ ## Releasing
92
+
93
+ 1. Move the `[Unreleased]` entries under a new `## [x.y.z] - <date>` heading and
94
+ add its link definition at the bottom of `CHANGELOG.md`.
95
+ 2. Bump `version` in `pyproject.toml` in the same commit (PEP 440 syntax there;
96
+ SemVer in tags and the changelog).
97
+ 3. Before 1.0, bump the minor only when the documented API breaks. New methods,
98
+ new optional arguments and fixes are patch releases.
99
+ 4. Run the full suite on the floor and latest interpreters, `mkdocs build
100
+ --strict`, `python -m build`, and the maintainer's leak check (a scan for
101
+ private references and agent-attribution commit trailers). Judge it by exit
102
+ code.
103
+ 5. Push `main`, then the `v*` tag. Publishing is irreversible, so the tag is
104
+ pushed only with the maintainer's explicit consent for that specific
105
+ release.
106
+
107
+ Changelog entries say what changed and what a user must do about it. They do
108
+ not describe how the work was done.
109
+
110
+ ## Commits
111
+
112
+ - Logical commits in `type: description` form (`feat:`, `fix:`, `docs:`,
113
+ `chore:`); keep code with its tests, and docs/config/CI in separate commits.
114
+ - No agent attribution in commit messages: no `Co-Authored-By:` naming a model
115
+ or assistant, no `*-Session:` trailers, no session URLs, no "generated with"
116
+ footers.