This release is a pre-release and may not be stable for production use.
English | 한국어
torchnative
Run the real PyTorch ecosystem on device, not a reimplementation of it.
Guide · Status in detail · Design · 한국어
torchnative replaces PyTorch's compiled core, torch._C, with a native Rust extension. The
genuine torch and transformers packages then run on a phone the way they run on a workstation.
Models are not ported, converted or re-expressed. They are imported.
from transformers import AutoModelForCausalLM # the real one
model = AutoModelForCausalLM.from_pretrained("...")
model.generate(...) # on the device
💡 Why not a reimplementation
Every other route to on-device inference re-expresses the model somewhere else.
| approach | cost | |
|---|---|---|
| llama.cpp | architectures rewritten in C++ | each new architecture is a porting task |
| ExecuTorch · CoreML | ahead-of-time compiled graph | an export step, and what runs is not what you wrote |
| MLC | lowered to its own runtime | same |
| torchnative | the real Python package | the substrate is hard; architectures are free |
Nobody runs the real thing because torch._C cannot be built for mobile: PyTorch's build sets
INTERN_BUILD_MOBILE for any Android or iOS toolchain, and that path forces BUILD_PYTHON off.
torchnative supplies that one module. Everything above it is upstream source, unmodified.
✨ Features
- 🤖 LLM inference with real
transformers:from_pretrainedloads bit-identical weights,generateemits upstream's tokens infloat32, and streaming works across threads. - 🎯 Agreement, not just reachability: 302 ATen operators compared against upstream; 297 of 297 swept architectures forward and 284 of 285 judgeable ones agree numerically, at a tolerance derived from upstream's own float32 error.
- 🔁 Test-time adaptation:
adapt.wrap(model, method=adapt.Tent())adapts in place; a weight delta over the base reverts bit-identically. - 🌐 Federated learning on
torch.distributed: FedAvg across processes equals the same average computed centrally, element for element. - ⚡ Accelerators without silent fallback: Metal and Vulkan compute on the real GPU, a CoreML graph runs on the Apple Neural Engine, and anything that would fall back to the host refuses by name instead.
- 🧩 NPUs by module replacement:
model.to(torchnative.device.npu)lowers leaves for the host's NPU and hands back the samenn.Module, so it still trains and still generates. - 📦 One wheel per platform:
cp313-abi3, so one binary loads on CPython 3.13 and later.
🚀 Quick start
uv add --prerelease allow torchnative
# or, with pypackpack
ppp core add "torchnative==0.1.0b4"
Stream tokens from a real Hugging Face model:
import torch
from threading import Thread
from transformers import AutoModelForCausalLM, AutoTokenizer, TextIteratorStreamer
name = "HuggingFaceTB/SmolLM2-135M"
model = AutoModelForCausalLM.from_pretrained(name, dtype=torch.float32)
tok = AutoTokenizer.from_pretrained(name)
streamer = TextIteratorStreamer(tok, skip_prompt=True, skip_special_tokens=True)
inputs = tok("On-device inference is", return_tensors="pt")
Thread(target=model.generate, kwargs=dict(**inputs, max_new_tokens=32, streamer=streamer)).start()
for piece in streamer: # yields as the model decodes
print(piece, end="", flush=True)
On an M-series desktop the first token arrives in 34 ms, then 47 tokens/s. In float32
the tokens are the ones upstream emits; in bfloat16 they diverge, because upstream disagrees with
itself under a change of accumulation order.
Adapt at test time, then put the base weights back:
from torchnative import adapt
model = adapt.wrap(model, method=adapt.Tent(), lr=1e-3)
model.online() # adapt as it serves
model.revert() # the base weights are back, byte for byte
Send it to the NPU without giving up the module:
from torchnative import device
model.to(device.npu) # resolves the host's NPU, lowers what it can, returns the same nn.Module;
# a UserWarning names anything that stayed on the CPU
More task pages are in the guide.
🧩 How it works
flowchart TB
A["your code · transformers · torch/*.py<br/><i>upstream Python, unmodified</i>"]
B["torch._C, replaced<br/><b>_aten_dispatch</b>: the single door every operator passes"]
C["kernels, Rust, backed by candle"]
D["CPU · Metal · Vulkan"]
E["CoreML · OpenVINO · QNN<br/><i>whole subgraphs, behind a module</i>"]
A --> B --> C --> D
B -- "graph capture" --> E
- One door. Every operator reaches its kernel through
_aten_dispatch, and nothing bypasses it. An unimplemented operator names itself instead of failing downstream, and graph capture has exactly one place to attach. - Fixed front end, swapped back end. The user keeps the real
transformersmodel; an NPU back end replaces leaves or submodules in place, and a vendor blob is never something you hold. - Refuse by name. What is not supported says so, with the reason. A silent CPU fallback is made unrepresentable rather than merely avoided.
- Stable ABI. Built against CPython's limited API (
abi3-py313): one binary per platform.
📊 Status
Every number below has a run behind it. The long form, with the measurement and caveat for every
row, is docs/platform/STATUS.md.
| ATen operators | 302, each compared against upstream |
| Golden comparison cases | 11,420 / 11,420, values, shapes, dtypes, through the door and through the member |
| Smoke tests | 480 in test_shim.py alone; the gate runs every suite in tests/ |
| Signature and schema tables | 5,024 of 5,037 entries checked against upstream |
| Architectures, forward | 297 of 297 swept (reachability; not a fresh full sweep, see the long form) |
| Architectures, agree with upstream | 284 of 285 judgeable, at a derived tolerance (AGREE.md) |
| Training | loss.backward() through upstream's own autograd path, matching upstream to one float32 ulp |
| Test-time adaptation | Tent on SmolLM2-135M: entropy 4.1604 → 2.9828, revert bit-identical (ADAPT.md) |
torch.distributed |
eleven collectives agree with upstream gloo at world 3 and 4 (COLLECT2.md) |
| Accelerators | Metal and Vulkan compute on the real GPU; CoreML runs on the Neural Engine; NNAPI executes on the CPU reference driver only (NPU2.md) |
| Not working | torch.compile (refused permanently, COMPILE.md), CUDA never run, Intel NPU never run on hardware |
🖥️ Platform support
Legend: ✅ measured working · ❌ measured refusing · ⚠️ built, never executed · 🔲 not built · n/a not applicable to that platform
| macOS arm64 |
Android arm64 |
Android x86_64 |
iOS sim arm64 |
iOS device arm64 |
Linux x86_64 |
Linux aarch64 |
Windows x86_64 |
Windows arm64 |
WASM | |
|---|---|---|---|---|---|---|---|---|---|---|
| in the target matrix | ✅ | ✅ | ✅ listed, refuses | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | n/a deliberately |
| rust target installed | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
| target CPython | ✅ | ✅ | ❌ none exists, none downloadable | ✅ | ✅ | ✅ | ✅ PBS 20260825 |
✅ | ✅ PBS 20260825 |
✅ Pyodide 3.14 |
| candle builds | ✅ | ✅ | 🔲 | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
| candle computes | ✅ | ✅ | 🔲 | ✅ | ⚠️ | ✅ CI | ✅ here | ✅ CI | ⚠️ | ✅ under Node |
| CUDA extension builds | n/a | n/a | n/a | n/a | n/a | 🔲 CI job written, never run | 🔲 not targeted | 🔲 | n/a | n/a |
| CUDA computes | n/a | n/a | n/a | n/a | n/a | ⚠️ | 🔲 not targeted | ⚠️ | n/a | n/a |
| extension builds | ✅ | ✅ | 🔲 | ✅ | ✅ | ✅ cargo-zigbuild |
✅ cargo-zigbuild |
✅ cargo-xwin |
✅ cargo-xwin |
✅ emscripten |
| wheel builds | ✅ | ✅ | ❌ refuses by name | ✅ | ✅ | ✅ manylinux_2_17_x86_64 |
✅ manylinux_2_17_aarch64 |
✅ win_amd64 |
✅ win_arm64 |
⚠️ by hand, not by build.py |
| symbols resolve | ✅ | ✅ | n/a | ✅ | ✅ 118 names against the device framework | ⚠️ weaker: ELF names only versioned imports | ⚠️ same | ✅ PE names every one | ✅ PE names every one | ✅ stub behaviour proven against the real host |
dlopen + PyInit_ runs |
n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | n/a | ✅ |
| installs | ✅ | ✅ | n/a | ✅ | ⚠️ | ✅ | ✅ pip matched the tag on real aarch64 Linux | ✅ | ⚠️ | ✅ mounted, no wheel |
import torch |
✅ | ✅ | n/a | ✅ | ⚠️ | ✅ | ✅ | ✅ | ⚠️ | ✅ |
| computes | ✅ | ✅ | n/a | ✅ | ⚠️ | ✅ | ✅ glibc 2.17 and modern | ✅ | ⚠️ | ✅ |
on PyPI 0.1.0b0 |
✅ | ✅ | 🔲 refuses | ✅ | ✅ | ✅ | ✅ first published here | ✅ | ✅ first published here | ✅ |
| can be run here | ✅ | emulator | ❌ no x86-64 emulator on Apple Silicon | simulator | ❌ | CI | ✅ Docker, native aarch64 | CI | ❌ | ✅ Node |
| device | macOS | Android | iOS | Linux | Windows | WASM | what it is |
|---|---|---|---|---|---|---|---|
cpu |
✅ | ✅ | ⚠️ | ⚠️ | ⚠️ | ✅ | the only device that holds a tensor |
meta |
✅ | ✅ | ⚠️ | ⚠️ | ⚠️ | 🔲 | shape and dtype, no storage |
mps |
✅ | n/a | 🔲 | n/a | n/a | n/a | candle's Metal backend, on. An op whose kernel would compute on the CPU under an mps label is refused at the door, naming the op, 89 of them (this cell said 54), listed at runtime by _C._shim_mps_host_readback_ops(). A transformer forwards here (MPSATTN.md) |
vulkan |
✅ | ❌ | n/a | 🔲 | 🔲 | n/a | thirty-one ops through real VkBuffers; a pretrained BERT forwards and agrees with upstream (VULKAN7.md) |
| NNAPI · CoreML | ✅ CoreML | ✅ NNAPI | 🔲 | n/a | n/a | n/a | both execute; CoreML reaches the Neural Engine, NNAPI has met only a CPU driver |
cuda |
n/a | n/a | n/a | ⚠️ | ⚠️ | n/a | wired, never compiled or run (CUDA.md) |
The dtype and quantisation matrices, and the reasoning behind every cell, are in
docs/platform/STATUS.md and
docs/platform/WHEELMATRIX.md.
🗺️ Roadmap
| ✅ implemented: device abstraction | torch.device vocabulary, per-device dispatch, a Repr arm per device; torchnative.device with cpu · mps · vulkan · cuda · npu |
✅ implemented: torchnative.transformers |
all 49 Auto* classes, enumerated from transformers, returning real models |
| 🟡 partial: NPU back ends (#21) | Intel NPU is wired through OpenVINO and no hardware has run it. Apple ANE and Hexagon refuse by name after resolving |
| 🟡 partial: eager training (#10) | Backward and optimizer steps agree. Double-backward, autograd.Function and hooks refuse |
| 🟡 partial: federated learning (#20) | Multi-process FedAvg works. Secure aggregation, privacy and participant selection do not exist yet |
This table records what has been measured, not what is planned. No row promises more than a run shows. Last re-measured 2026-09-07 (
docs/verification/REMEASURE2.md); where it disagrees with adocs/file, the file is the measurement and this is the summary.
Planned, not measured (#18): kernel bundles that satisfy the Hugging Face kernels contract and
resolve at build time (DESIGN.md §8). Not on the roadmap:
torch.compile, which is refused by name permanently. torch.export is the direction. The long-form
roadmap and the API it is heading for are in
docs/platform/STATUS.md.
📦 Install
uv add --prerelease allow torchnative
# or, with pypackpack
ppp core add "torchnative==0.1.0b4"
Nine platform wheels, all cp313-abi3. Each carries the _C extension and the vendored
upstream tree, so import torch resolves to this build. It cannot coexist with an installed
PyTorch. 0.0.1a0 on PyPI is a broken py3-none-any skeleton; ask for 0.1.0b0 or later. There
is no sdist.
Build from source (Rust toolchain, CPython 3.13+):
bash scripts/vendor/vendor_torch.sh # assemble the vendored torch tree
bash scripts/vendor/install_shim.sh # build the extension and install it
python scripts/wheel/build.py # -> dist/*.whl
python scripts/wheel/verify.py dist/torchnative-*.whl # clean venv, real import
Cross-compilation: docs/platform/RUST_CROSSBUILD.md.
🧪 Verification
Correctness here means agreeing with upstream PyTorch, so the strategy is comparison, not assertion.
- Golden comparison: every operator runs on upstream torch and on this shim, compared on value, shape and dtype.
- The harness tests itself:
--self-testinjects plausible misimplementations into each comparator and fails if any is accepted. - Tokens are not enough: a wrong
geluproduced identical tokens with logits off by 5.9e-04, so end-to-end tests compare logits too. - Documentation is checked: DOCWATCH markers tie the numbers on this page to live runs.
bash tests/run.sh # the gate
python tests/golden/compare.py # golden comparison against upstream
📖 Documentation
- 🌐 Guide: getting started, concepts, task
guides, English and Korean (source in
docs/guide/) - 📊 Status in detail: every measurement and caveat behind the tables above
- 🏛️ Design: why only
torch._C, and the decisions that constrain the rest - 🇰🇷 한국어 README
docs/ records what was measured, what was assumed, and where an earlier conclusion turned out to
be wrong. Corrections stay visible so that a reader can see what changed.
🤝 Contributing
Work starts from an issue and lands through a pull request into develop; tests come first. The
contributing page of the guide
explains the workflow and the verification standard.
🔗 Ecosystem
- PythonMultiplatform: embeds CPython 3.13 in Kotlin Multiplatform, the deployment target for this library
- pypackpack: the build and bundling tool
- Hugging Face
kernels: the fused-kernel contract this adopts, with resolution moved from runtime download to build time
📜 License
Apache-2.0: see LICENSE.
The repository and the wheel carry different licences. This repository contains only this
project's code; the vendored PyTorch tree is assembled at build time and not redistributed here. A
platform wheel carries upstream PyTorch's entire Python tree with torch._C replaced, so most
of its files are upstream's, under upstream's terms, which is why pyproject.toml's license is
torch 2.13.0's own License-Expression, verbatim:
Apache-2.0 AND Apache-2.0 WITH LLVM-exception AND BSD-2-Clause
AND BSD-3-Clause AND BSL-1.0 AND MIT
scripts/wheel/build.py ships torch's dist-info, third-party notices included.
Metadata
Release files for torchnative 0.1.0b5
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Built distributions (wheels)
Total release size: 135.4 MB
Release files / torchnative-0.1.0b5-cp313-abi3-win_arm64.whl
| Download URL | torchnative-0.1.0b5-cp313-abi3-win_arm64.whl |
|---|---|
| Size | 15.0 MB |
| Tags | CPython 3.13 Windows ARM64 abi3 |
|
SHA-256 checksum How to use checksums |
7786d16784d4b9dc026e49ad212a5e521ce081f05877b379c6e2999dd56af8d2
|
|
BLAKE2b-256 checksum How to use checksums |
c118ff5fcf5658c0ffe9914d31fe6221f3f58c2303d58de447b4967928aa595b
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 5, 2026.
Transparency logRelease files / torchnative-0.1.0b5-cp313-abi3-win_amd64.whl
| Download URL | torchnative-0.1.0b5-cp313-abi3-win_amd64.whl |
|---|---|
| Size | 15.3 MB |
| Tags | CPython 3.13 Windows x86-64 abi3 |
|
SHA-256 checksum How to use checksums |
2a6bea9f533eca3c3c9e6dc98704f42ea4dc912e6b031ae7ef0ac8c598449b4f
|
|
BLAKE2b-256 checksum How to use checksums |
69a6e3d150f624f68f69117befb263f5f4f7aa0632e24468f772e20abb089ee9
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 5, 2026.
Transparency logRelease files / torchnative-0.1.0b5-cp313-abi3-pyemscripten_2026_0_wasm32.whl
| Download URL | torchnative-0.1.0b5-cp313-abi3-pyemscripten_2026_0_wasm32.whl |
|---|---|
| Size | 14.1 MB |
| Tags | CPython 3.13 PyEmscripten 2026.0+ WebAssembly abi3 |
|
SHA-256 checksum How to use checksums |
28b837f628d5baeee305c4ad45c1cde060eb998496a035d80199daa8c39c11f6
|
|
BLAKE2b-256 checksum How to use checksums |
69a54724aae5562afbc2c07ebe3cafda07760d1ecbcbc6dc894339aea7df58a4
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 5, 2026.
Transparency logRelease files / torchnative-0.1.0b5-cp313-abi3-manylinux_2_17_x86_64.whl
| Download URL | torchnative-0.1.0b5-cp313-abi3-manylinux_2_17_x86_64.whl |
|---|---|
| Size | 15.3 MB |
| Tags | CPython 3.13 Linux glibc 2.17+ x86-64 abi3 |
|
SHA-256 checksum How to use checksums |
4065806ce81f1b22c46259056a06ef5fb3706f180eb81883a98df7f848c44e4f
|
|
BLAKE2b-256 checksum How to use checksums |
5ca68198d5f6d72181397afd01b6a6bd802d99799a0c11202f279f1690c98402
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 5, 2026.
Transparency logRelease files / torchnative-0.1.0b5-cp313-abi3-manylinux_2_17_aarch64.whl
| Download URL | torchnative-0.1.0b5-cp313-abi3-manylinux_2_17_aarch64.whl |
|---|---|
| Size | 15.0 MB |
| Tags | CPython 3.13 Linux glibc 2.17+ ARM64 abi3 |
|
SHA-256 checksum How to use checksums |
0c1660a47052a51d15e8eb2154276998a946e63eda926fac6465498218ca6838
|
|
BLAKE2b-256 checksum How to use checksums |
4f863f6b2600b9a3e4c4e32b7e5414abfaf4f951a4cd950629af954deb376967
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 5, 2026.
Transparency logRelease files / torchnative-0.1.0b5-cp313-abi3-macosx_11_0_arm64.whl
| Download URL | torchnative-0.1.0b5-cp313-abi3-macosx_11_0_arm64.whl |
|---|---|
| Size | 15.2 MB |
| Tags | CPython 3.13 abi3 macOS 11.0+ ARM64 |
|
SHA-256 checksum How to use checksums |
89bf1869502f5c29e54aa3d14820cb7a6a1504f5c8205f6b6bf84d3dd1a45d84
|
|
BLAKE2b-256 checksum How to use checksums |
237059aae3c7ca51ab04d584afee7cb269fdc6e1bcb245ee01fd4a308bb91a9f
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 5, 2026.
Transparency logRelease files / torchnative-0.1.0b5-cp313-abi3-ios_14_0_arm64_iphonesimulator.whl
| Download URL | torchnative-0.1.0b5-cp313-abi3-ios_14_0_arm64_iphonesimulator.whl |
|---|---|
| Size | 15.1 MB |
| Tags | CPython 3.13 abi3 iOS 14.0+ ARM64 Simulator |
|
SHA-256 checksum How to use checksums |
7a00abb26d57b00e62f6f291f490ea6127be954fd47cbab198d4382a27f99b4a
|
|
BLAKE2b-256 checksum How to use checksums |
abae5a7c6a03e3c9ad7f0a0614f8649b1cee62f6d820f37bed5b29e410aeacce
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 5, 2026.
Transparency logRelease files / torchnative-0.1.0b5-cp313-abi3-ios_12_0_arm64_iphoneos.whl
| Download URL | torchnative-0.1.0b5-cp313-abi3-ios_12_0_arm64_iphoneos.whl |
|---|---|
| Size | 15.2 MB |
| Tags | CPython 3.13 abi3 iOS 12.0+ ARM64 Device |
|
SHA-256 checksum How to use checksums |
880afc72c6553defddbe958ff1106a20d664b98a49823c7207446678a4326372
|
|
BLAKE2b-256 checksum How to use checksums |
2e68ec48396dce5d755644870a3de501f3e27e6f8c9bca08794f004ca4c8a5c5
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 5, 2026.
Transparency logRelease files / torchnative-0.1.0b5-cp313-abi3-android_21_arm64_v8a.whl
| Download URL | torchnative-0.1.0b5-cp313-abi3-android_21_arm64_v8a.whl |
|---|---|
| Size | 15.2 MB |
| Tags | Android API level 21+ ARM64 v8a CPython 3.13 abi3 |
|
SHA-256 checksum How to use checksums |
2b809c3c4bca7744ea1e64b7f3cab3877c12c773588728ee759be4d003e8d7cd
|
|
BLAKE2b-256 checksum How to use checksums |
6a28cafe49e9f074e71d1984786883b9597d526f4a26c3b6bd681cc7aea16ef1
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 5, 2026.
Transparency log