patchcraft 0.2.1__tar.gz → 0.5.0__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 (66) hide show
  1. {patchcraft-0.2.1 → patchcraft-0.5.0}/.github/workflows/release.yml +203 -128
  2. {patchcraft-0.2.1 → patchcraft-0.5.0}/.github/workflows/test.yml +43 -1
  3. {patchcraft-0.2.1 → patchcraft-0.5.0}/.gitignore +3 -0
  4. {patchcraft-0.2.1 → patchcraft-0.5.0}/CHANGELOG.md +481 -271
  5. patchcraft-0.5.0/CONTRIBUTING.md +161 -0
  6. patchcraft-0.5.0/PKG-INFO +187 -0
  7. patchcraft-0.5.0/README.md +167 -0
  8. patchcraft-0.5.0/README.pt-BR.md +167 -0
  9. patchcraft-0.5.0/README.pypi.md +144 -0
  10. {patchcraft-0.2.1 → patchcraft-0.5.0}/docs/ADR/0001-patch-extraction-api.md +100 -100
  11. {patchcraft-0.2.1 → patchcraft-0.5.0}/docs/ADR/0002-patchify-transform.md +101 -101
  12. patchcraft-0.5.0/docs/ADR/0003-reversibility-classes.md +107 -0
  13. {patchcraft-0.2.1 → patchcraft-0.5.0}/docs/AUXILIARY.md +169 -169
  14. patchcraft-0.5.0/docs/FOCO-1.0.md +110 -0
  15. patchcraft-0.5.0/docs/GUIDE.md +851 -0
  16. {patchcraft-0.2.1 → patchcraft-0.5.0}/docs/ROADMAP.md +111 -111
  17. {patchcraft-0.2.1 → patchcraft-0.5.0}/docs/SCOPE.md +296 -293
  18. {patchcraft-0.2.1 → patchcraft-0.5.0}/docs/STUDIES/2026-08-04-patch-techniques.md +31 -5
  19. {patchcraft-0.2.1 → patchcraft-0.5.0}/docs/THEORY.md +461 -460
  20. {patchcraft-0.2.1 → patchcraft-0.5.0}/docs/USAGE.md +499 -485
  21. patchcraft-0.5.0/docs/superpowers/plans/2026-09-01-fase1-bugs-performance.md +1179 -0
  22. patchcraft-0.5.0/docs/superpowers/plans/2026-09-01-fase2-acel.md +1643 -0
  23. patchcraft-0.5.0/docs/superpowers/plans/2026-09-01-fase3-g1-predicado.md +1705 -0
  24. patchcraft-0.5.0/docs/superpowers/specs/2026-09-01-fase1-bugs-performance-design.md +151 -0
  25. patchcraft-0.5.0/docs/superpowers/specs/2026-09-01-fase2-acel-design.md +168 -0
  26. patchcraft-0.5.0/docs/superpowers/specs/2026-09-01-fase3-g1-predicado-design.md +260 -0
  27. {patchcraft-0.2.1 → patchcraft-0.5.0}/pyproject.toml +112 -100
  28. {patchcraft-0.2.1 → patchcraft-0.5.0}/src/patchcraft/__init__.py +42 -40
  29. patchcraft-0.5.0/src/patchcraft/_accel.py +115 -0
  30. patchcraft-0.5.0/src/patchcraft/_foldgeom.py +87 -0
  31. {patchcraft-0.2.1 → patchcraft-0.5.0}/src/patchcraft/cache.py +254 -247
  32. {patchcraft-0.2.1 → patchcraft-0.5.0}/src/patchcraft/extract.py +147 -116
  33. {patchcraft-0.2.1 → patchcraft-0.5.0}/src/patchcraft/geometry.py +298 -290
  34. {patchcraft-0.2.1 → patchcraft-0.5.0}/src/patchcraft/metrics.py +167 -159
  35. {patchcraft-0.2.1 → patchcraft-0.5.0}/src/patchcraft/pair.py +166 -161
  36. patchcraft-0.5.0/src/patchcraft/reconstruct.py +137 -0
  37. {patchcraft-0.2.1 → patchcraft-0.5.0}/src/patchcraft/resize.py +205 -202
  38. {patchcraft-0.2.1 → patchcraft-0.5.0}/src/patchcraft/stitch.py +229 -239
  39. {patchcraft-0.2.1 → patchcraft-0.5.0}/tests/_datasets.py +117 -117
  40. patchcraft-0.5.0/tests/_rng.py +108 -0
  41. {patchcraft-0.2.1 → patchcraft-0.5.0}/tests/conftest.py +1 -1
  42. patchcraft-0.5.0/tests/test_accel.py +223 -0
  43. {patchcraft-0.2.1 → patchcraft-0.5.0}/tests/test_cache.py +276 -254
  44. patchcraft-0.5.0/tests/test_exactness.py +164 -0
  45. {patchcraft-0.2.1 → patchcraft-0.5.0}/tests/test_extract.py +311 -250
  46. {patchcraft-0.2.1 → patchcraft-0.5.0}/tests/test_geometry.py +361 -333
  47. {patchcraft-0.2.1 → patchcraft-0.5.0}/tests/test_import.py +20 -14
  48. {patchcraft-0.2.1 → patchcraft-0.5.0}/tests/test_metrics.py +260 -213
  49. {patchcraft-0.2.1 → patchcraft-0.5.0}/tests/test_pair.py +241 -212
  50. patchcraft-0.5.0/tests/test_public_api.py +249 -0
  51. {patchcraft-0.2.1 → patchcraft-0.5.0}/tests/test_reconstruct.py +321 -262
  52. patchcraft-0.5.0/tests/test_reference.py +92 -0
  53. {patchcraft-0.2.1 → patchcraft-0.5.0}/tests/test_resize.py +240 -229
  54. patchcraft-0.5.0/tests/test_rng.py +109 -0
  55. {patchcraft-0.2.1 → patchcraft-0.5.0}/tests/test_stitch.py +354 -283
  56. patchcraft-0.5.0/uv.lock +1172 -0
  57. patchcraft-0.2.1/CONTRIBUTING.md +0 -98
  58. patchcraft-0.2.1/PKG-INFO +0 -208
  59. patchcraft-0.2.1/README.md +0 -168
  60. patchcraft-0.2.1/src/patchcraft/reconstruct.py +0 -148
  61. patchcraft-0.2.1/uv.lock +0 -1041
  62. {patchcraft-0.2.1 → patchcraft-0.5.0}/.python-version +0 -0
  63. {patchcraft-0.2.1 → patchcraft-0.5.0}/LICENSE +0 -0
  64. {patchcraft-0.2.1 → patchcraft-0.5.0}/src/patchcraft/py.typed +0 -0
  65. {patchcraft-0.2.1 → patchcraft-0.5.0}/tests/__init__.py +0 -0
  66. {patchcraft-0.2.1 → patchcraft-0.5.0}/tests/test_datasets_helper.py +0 -0
@@ -1,128 +1,203 @@
1
- name: release
2
-
3
- # Triggered when a version tag is pushed (vX.Y.Z[.aN, .bN, .rcN]).
4
- # Steps:
5
- # 1. Re-run the test job that test.yml uses (sanity check on the
6
- # exact ref being released).
7
- # 2. Build the wheel + sdist with `uv build`.
8
- # 3. Publish to PyPI via Trusted Publishing (OIDC) -- no token,
9
- # no secret. The pypi.org side must have a configured publisher
10
- # pointing at THIS repo + THIS workflow + the `pypi` environment.
11
- # 4. Create / update the GitHub Release page and attach the
12
- # `dist/*.whl` and `dist/*.tar.gz` files.
13
-
14
- on:
15
- push:
16
- tags:
17
- - "v[0-9]+.[0-9]+.[0-9]+"
18
- - "v[0-9]+.[0-9]+.[0-9]+.[ab][0-9]+"
19
- - "v[0-9]+.[0-9]+.[0-9]+.rc[0-9]+"
20
-
21
- permissions:
22
- contents: read
23
-
24
- jobs:
25
- validate:
26
- name: re-run tests at tag ref
27
- runs-on: ubuntu-latest
28
- env:
29
- UV_PYTHON: "3.13"
30
- steps:
31
- - uses: actions/checkout@v4
32
- - uses: astral-sh/setup-uv@v3
33
- with:
34
- enable-cache: true
35
- - run: uv python install
36
- - run: uv sync --locked --extra cache --extra dev
37
- - name: Tag must match __version__
38
- run: |
39
- tag="${GITHUB_REF_NAME#v}"
40
- pkg="$(uv run python -c 'import patchcraft; print(patchcraft.__version__)')"
41
- if [ "$tag" != "$pkg" ]; then
42
- echo "::error::tag ${GITHUB_REF_NAME} implies version '${tag}' but patchcraft.__version__ is '${pkg}'"
43
- exit 1
44
- fi
45
- echo "tag ${GITHUB_REF_NAME} matches __version__ ${pkg}"
46
- - run: uv run ruff check src tests
47
- - run: uv run mypy --strict src
48
- - run: uv run pytest -m "not gpu"
49
-
50
- build:
51
- name: build wheel + sdist
52
- runs-on: ubuntu-latest
53
- needs: validate
54
- steps:
55
- - uses: actions/checkout@v4
56
- - uses: astral-sh/setup-uv@v3
57
- - run: uv build
58
- - name: Inspect dist metadata
59
- run: |
60
- uv run --with twine twine check dist/*
61
- ls -la dist/
62
- - uses: actions/upload-artifact@v4
63
- with:
64
- name: dist
65
- path: dist/
66
-
67
- publish-pypi:
68
- name: publish to PyPI (Trusted Publishing)
69
- runs-on: ubuntu-latest
70
- needs: build
71
- environment:
72
- name: pypi
73
- url: https://pypi.org/project/patchcraft/
74
- permissions:
75
- id-token: write # required for OIDC token exchange with PyPI
76
- steps:
77
- - uses: actions/download-artifact@v4
78
- with:
79
- name: dist
80
- path: dist/
81
- - name: Publish via Trusted Publishing
82
- uses: pypa/gh-action-pypi-publish@release/v1
83
- with:
84
- # A version already on PyPI is a no-op instead of a hard failure.
85
- # Without this, re-running the pipeline (or tagging a version that
86
- # was uploaded by hand) fails here, and `github-release` never runs
87
- # because it is `needs: publish-pypi`.
88
- skip-existing: true
89
- # No `password` field -- OIDC handles authentication.
90
- # The pypi.org "Pending publisher" config must match:
91
- # PyPI project name: patchcraft
92
- # Owner: LeoPR
93
- # Repository: PatchCraft
94
- # Workflow: release.yml
95
- # Environment: pypi
96
-
97
- github-release:
98
- name: create GitHub Release with assets
99
- runs-on: ubuntu-latest
100
- needs: publish-pypi
101
- permissions:
102
- contents: write # required to create a Release
103
- steps:
104
- - uses: actions/checkout@v4
105
- - uses: actions/download-artifact@v4
106
- with:
107
- name: dist
108
- path: dist/
109
- - name: Extract version from tag
110
- id: ver
111
- run: echo "version=${GITHUB_REF_NAME#v}" >> "$GITHUB_OUTPUT"
112
- - name: Create Release + attach assets
113
- uses: softprops/action-gh-release@v2
114
- with:
115
- name: "PatchCraft ${{ github.ref_name }}"
116
- body: |
117
- See [`CHANGELOG.md`](https://github.com/LeoPR/PatchCraft/blob/main/CHANGELOG.md) for the full notes.
118
-
119
- Install:
120
- ```
121
- pip install patchcraft==${{ steps.ver.outputs.version }}
122
- ```
123
- files: |
124
- dist/*.whl
125
- dist/*.tar.gz
126
- fail_on_unmatched_files: true
127
- draft: false
128
- prerelease: false
1
+ name: release
2
+
3
+ # Triggered when a version tag is pushed (vX.Y.Z[.aN, .bN, .rcN]).
4
+ # Steps:
5
+ # 1. Re-run the test job that test.yml uses (sanity check on the
6
+ # exact ref being released).
7
+ # 2. Build the wheel + sdist with `uv build`.
8
+ # 3. Publish to PyPI via Trusted Publishing (OIDC) -- no token,
9
+ # no secret. The pypi.org side must have a configured publisher
10
+ # pointing at THIS repo + THIS workflow + the `pypi` environment.
11
+ # 4. Create / update the GitHub Release page and attach the
12
+ # `dist/*.whl` and `dist/*.tar.gz` files.
13
+
14
+ on:
15
+ push:
16
+ tags:
17
+ - "v[0-9]+.[0-9]+.[0-9]+"
18
+ - "v[0-9]+.[0-9]+.[0-9]+.[ab][0-9]+"
19
+ - "v[0-9]+.[0-9]+.[0-9]+.rc[0-9]+"
20
+
21
+ permissions:
22
+ contents: read
23
+
24
+ jobs:
25
+ validate:
26
+ name: re-run tests at tag ref
27
+ runs-on: ubuntu-latest
28
+ env:
29
+ UV_PYTHON: "3.13"
30
+ steps:
31
+ - uses: actions/checkout@v4
32
+ - uses: astral-sh/setup-uv@v3
33
+ with:
34
+ enable-cache: true
35
+ - run: uv python install
36
+ - run: uv sync --locked --extra cache --extra dev
37
+ - name: Tag must match __version__
38
+ run: |
39
+ tag="${GITHUB_REF_NAME#v}"
40
+ pkg="$(uv run python -c 'import patchcraft; print(patchcraft.__version__)')"
41
+ if [ "$tag" != "$pkg" ]; then
42
+ echo "::error::tag ${GITHUB_REF_NAME} implies version '${tag}' but patchcraft.__version__ is '${pkg}'"
43
+ exit 1
44
+ fi
45
+ echo "tag ${GITHUB_REF_NAME} matches __version__ ${pkg}"
46
+ - run: uv run ruff check src tests
47
+ - run: uv run mypy --strict src
48
+ - run: uv run pytest -m "not gpu"
49
+
50
+ build:
51
+ name: build wheel + sdist
52
+ runs-on: ubuntu-latest
53
+ needs: validate
54
+ steps:
55
+ - uses: actions/checkout@v4
56
+ - uses: astral-sh/setup-uv@v3
57
+ - run: uv build
58
+ - name: Inspect dist metadata
59
+ run: |
60
+ uv run --with twine twine check dist/*
61
+ ls -la dist/
62
+ - uses: actions/upload-artifact@v4
63
+ with:
64
+ name: dist
65
+ path: dist/
66
+
67
+ build-accel:
68
+ name: accel wheel (${{ matrix.target }})
69
+ runs-on: ${{ matrix.os }}
70
+ needs: validate
71
+ strategy:
72
+ fail-fast: false
73
+ matrix:
74
+ include:
75
+ # macos-13 is the Intel runner; macos-latest is arm64.
76
+ - os: windows-latest
77
+ target: x86_64-pc-windows-msvc
78
+ - os: ubuntu-latest
79
+ target: x86_64-unknown-linux-gnu
80
+ - os: macos-latest
81
+ target: aarch64-apple-darwin
82
+ - os: macos-13
83
+ target: x86_64-apple-darwin
84
+ steps:
85
+ - uses: actions/checkout@v4
86
+
87
+ - name: Build accel wheel
88
+ uses: PyO3/maturin-action@v1
89
+ with:
90
+ target: ${{ matrix.target }}
91
+ args: --release --out dist-accel --manifest-path accel/Cargo.toml
92
+
93
+ - name: Build accel sdist (linux only)
94
+ # The sdist is OS-independent; one is enough. Building it from source
95
+ # requires a Rust toolchain -- documented in accel/README.md.
96
+ if: matrix.target == 'x86_64-unknown-linux-gnu'
97
+ run: pipx run maturin sdist --manifest-path accel/Cargo.toml --out dist-accel
98
+
99
+ - name: Check accel artifacts
100
+ run: pipx run twine check dist-accel/*
101
+
102
+ - uses: actions/upload-artifact@v4
103
+ with:
104
+ name: accel-${{ matrix.target }}
105
+ path: dist-accel/
106
+
107
+ publish-pypi:
108
+ name: publish to PyPI (Trusted Publishing)
109
+ runs-on: ubuntu-latest
110
+ needs: build
111
+ environment:
112
+ name: pypi
113
+ url: https://pypi.org/project/patchcraft/
114
+ permissions:
115
+ id-token: write # required for OIDC token exchange with PyPI
116
+ steps:
117
+ - uses: actions/download-artifact@v4
118
+ with:
119
+ name: dist
120
+ path: dist/
121
+ - name: Publish via Trusted Publishing
122
+ uses: pypa/gh-action-pypi-publish@release/v1
123
+ with:
124
+ # A version already on PyPI is a no-op instead of a hard failure.
125
+ # Without this, re-running the pipeline (or tagging a version that
126
+ # was uploaded by hand) fails here, and `github-release` never runs
127
+ # because it is `needs: publish-pypi`.
128
+ skip-existing: true
129
+ # No `password` field -- OIDC handles authentication.
130
+ # The pypi.org "Pending publisher" config must match:
131
+ # PyPI project name: patchcraft
132
+ # Owner: LeoPR
133
+ # Repository: PatchCraft
134
+ # Workflow: release.yml
135
+ # Environment: pypi
136
+
137
+ publish-accel:
138
+ name: publish patchcraft-accel to PyPI (Trusted Publishing)
139
+ runs-on: ubuntu-latest
140
+ needs: build-accel
141
+ environment:
142
+ name: pypi
143
+ url: https://pypi.org/project/patchcraft-accel/
144
+ permissions:
145
+ id-token: write # required for OIDC token exchange with PyPI
146
+ steps:
147
+ - uses: actions/download-artifact@v4
148
+ with:
149
+ pattern: accel-*
150
+ path: dist-accel
151
+ merge-multiple: true
152
+ - name: Publish via Trusted Publishing
153
+ uses: pypa/gh-action-pypi-publish@release/v1
154
+ with:
155
+ skip-existing: true
156
+ packages-dir: dist-accel/
157
+ # FIRST RELEASE REQUIRES a one-time "pending publisher" config on
158
+ # pypi.org (user action, not this repo's):
159
+ # PyPI project name: patchcraft-accel
160
+ # Owner: LeoPR
161
+ # Repository: PatchCraft
162
+ # Workflow: release.yml
163
+ # Environment: pypi
164
+
165
+ github-release:
166
+ name: create GitHub Release with assets
167
+ runs-on: ubuntu-latest
168
+ needs: [publish-pypi, build-accel]
169
+ permissions:
170
+ contents: write # required to create a Release
171
+ steps:
172
+ - uses: actions/checkout@v4
173
+ - uses: actions/download-artifact@v4
174
+ with:
175
+ name: dist
176
+ path: dist/
177
+ - uses: actions/download-artifact@v4
178
+ with:
179
+ pattern: accel-*
180
+ path: dist-accel
181
+ merge-multiple: true
182
+ - name: Extract version from tag
183
+ id: ver
184
+ run: echo "version=${GITHUB_REF_NAME#v}" >> "$GITHUB_OUTPUT"
185
+ - name: Create Release + attach assets
186
+ uses: softprops/action-gh-release@v2
187
+ with:
188
+ name: "PatchCraft ${{ github.ref_name }}"
189
+ body: |
190
+ See [`CHANGELOG.md`](https://github.com/LeoPR/PatchCraft/blob/main/CHANGELOG.md) for the full notes.
191
+
192
+ Install:
193
+ ```
194
+ pip install patchcraft==${{ steps.ver.outputs.version }}
195
+ ```
196
+ files: |
197
+ dist/*.whl
198
+ dist/*.tar.gz
199
+ dist-accel/*.whl
200
+ dist-accel/*.tar.gz
201
+ fail_on_unmatched_files: true
202
+ draft: false
203
+ prerelease: false
@@ -18,7 +18,7 @@ jobs:
18
18
  fail-fast: false
19
19
  matrix:
20
20
  os: [ubuntu-latest, windows-latest]
21
- python: ["3.12", "3.13"]
21
+ python: ["3.12", "3.13", "3.14"]
22
22
  env:
23
23
  # Force uv to use the matrix Python in every uv* invocation
24
24
  # (otherwise `uv run` re-resolves to its default, which is the
@@ -49,3 +49,45 @@ jobs:
49
49
 
50
50
  - name: Pytest (skip GPU markers)
51
51
  run: uv run pytest -m "not gpu"
52
+
53
+ test-accel:
54
+ name: ${{ matrix.os }} / py3.12 / accel
55
+ runs-on: ${{ matrix.os }}
56
+ env:
57
+ UV_PYTHON: "3.12"
58
+ strategy:
59
+ fail-fast: false
60
+ matrix:
61
+ os: [ubuntu-latest, windows-latest]
62
+ steps:
63
+ - uses: actions/checkout@v4
64
+
65
+ - name: Install uv
66
+ uses: astral-sh/setup-uv@v3
67
+ with:
68
+ enable-cache: true
69
+
70
+ - name: Install Rust
71
+ uses: dtolnay/rust-toolchain@stable
72
+
73
+ - name: Set up Python
74
+ run: uv python install
75
+
76
+ - name: Install project with dev + cache extras
77
+ run: uv sync --locked --extra cache --extra dev
78
+
79
+ - name: Rust unit tests
80
+ # The venv's interpreter on PATH lets the pyo3 build script resolve
81
+ # libpython (extension-module is off outside maturin builds).
82
+ run: uv run cargo test --manifest-path accel/Cargo.toml
83
+
84
+ - name: Build + install the accelerator
85
+ run: |
86
+ uv pip install maturin
87
+ uv run maturin develop --manifest-path accel/Cargo.toml --release
88
+
89
+ - name: Accelerator is detected
90
+ run: uv run python -c "import patchcraft; assert patchcraft.accel_available()"
91
+
92
+ - name: Pytest (accelerated mode)
93
+ run: uv run pytest -m "not gpu"
@@ -53,3 +53,6 @@ runs/
53
53
 
54
54
  # Datasets and caches live on Z:
55
55
  data/
56
+
57
+ # Rust accelerator build artifacts (accel/Cargo.lock IS committed)
58
+ accel/target/