Python library for parsing, manipulating, and emitting JVM class files
Project description
pytecode
pytecode is a Python 3.12+ library for parsing, inspecting, editing, validating, and emitting JVM class files and JAR archives.
It is built for Python tooling that needs direct access to Java bytecode: classfile readers and writers, archive rewriters, transformation pipelines, control-flow analysis, descriptor utilities, hierarchy-aware frame computation, and verification-oriented workflows.
Why pytecode?
- Parse
.classfiles into typed Python objects backed by the Rust engine. - Edit classes, fields, methods, and bytecode through a mutable symbolic model.
- Rewrite JAR files while preserving non-class resources and ZIP metadata.
- Recompute
max_stack,max_locals, andStackMapTablewhen requested. - Validate parsed classfiles and edited models before emission.
- Work with descriptors, signatures, labels, symbolic operands, constant pools, and debug-info policies.
Installation
Install from PyPI:
pip install pytecode
Or with uv:
uv add pytecode
Published releases ship prebuilt wheels for Windows, macOS, and Linux.
If a matching wheel is unavailable, pip/uv falls back to a source build,
which requires a working Rust toolchain.
pytecode requires Python 3.12+.
Quick start
Parse and roundtrip a class file
from pathlib import Path
from pytecode.classfile import ClassReader, ClassWriter
reader = ClassReader.from_file("HelloWorld.class")
classfile = reader.class_info
print(classfile.major_version)
print(classfile.methods_count)
Path("HelloWorld-copy.class").write_bytes(ClassWriter.write(classfile))
Edit through the Rust-owned model
from pathlib import Path
from pytecode.model import ClassModel
model = ClassModel.from_bytes(Path("HelloWorld.class").read_bytes())
print(model.name)
updated_bytes = model.to_bytes()
Path("HelloWorld-updated.class").write_bytes(updated_bytes)
Import FrameComputationMode from pytecode.archive and use to_bytes_with_options(frame_mode=FrameComputationMode.RECOMPUTE) when an edit changes control flow or stack/local layout.
JAR rewriting example
JarFile.rewrite() can apply in-place transforms to matching classes and methods:
from pytecode import JarFile
from pytecode.classfile.constants import MethodAccessFlag
from pytecode.transforms import (
PipelineBuilder,
add_access_flags,
class_named,
method_is_public,
method_is_static,
method_name_matches,
)
pipeline = (
PipelineBuilder()
.on_methods(
method_name_matches(r"main") & method_is_public() & method_is_static(),
add_access_flags(int(MethodAccessFlag.FINAL)),
owner_matcher=class_named("HelloWorld"),
)
.build()
)
JarFile("input.jar").rewrite(
"output.jar",
transform=pipeline.apply,
)
For code-shape changes, pass frame_mode=FrameComputationMode.RECOMPUTE. To strip debug metadata during rewrite, prefer debug_info=DebugInfoPolicy.STRIP.
JarFile.rewrite() uses the Rust archive layer for in-memory archive edits and
Rust-native transforms. Python-callable transforms are also supported through
the same public API when a workflow needs ClassModel-level mutation.
Public surface
Top-level exports:
pytecode.ClassReader/pytecode.ClassWriterfor Rust-backed raw classfile parsing and emission.pytecode.ClassModelfor Rust-owned mutable editing.pytecode.JarFilefor Rust-backed archive reads and rewrite workflows.
Canonical semantic modules:
pytecode.classfilefor raw Rust-backed classfile reading and writing.pytecode.modelfor editable class models, typed code items, labels, and code metadata wrappers.
Supported submodules:
pytecode.transformsfor Rust-backed class, field, and method transforms.pytecode.analysisfor Rust-backed verification entry points.pytecode.analysis.verifyfor structural validation and diagnostics.pytecode.analysis.hierarchyfor type and override resolution helpers.pytecode.classfile.attributesfor typed raw attribute dataclasses.pytecode.classfile.bytecodefor opcode and array-type enums.pytecode.classfile.constantsfor access flags, opcodes, and verifier constants.pytecode.modelfor editable class, field, method, and code models.
Documentation
- Development docs overview: docs/OVERVIEW.md
- Hosted API reference: https://smithtrenton.github.io/pytecode/
Development
Create a local environment with development tools:
uv sync --extra dev
uv sync --extra dev now builds the local editable package through maturin, so a working Rust toolchain is required alongside Python.
Common checks:
uv run ruff check .
uv run ruff format --check .
uv run basedpyright
uv run pytest -q
uv run python tools/generate_api_docs.py --check
cargo fmt --all --check
cargo clippy --workspace --all-targets -- -D warnings
cargo test --workspace
Workspace smoke and comparison commands:
cargo run --release -p pytecode-cli -- bench-smoke --iterations 5
uv run python tools\benchmark_jar_pipeline.py crates\pytecode-engine\fixtures\jars\byte-buddy-1.17.5.jar --iterations 5
uv run python tools\compare_rust_python_benchmarks.py --jar crates\pytecode-engine\fixtures\jars\byte-buddy-1.17.5.jar --iterations 5 --output output\benchmarks\rust-vs-python-byte-buddy.json
cargo run -p pytecode-cli -- class-summary --path crates\pytecode-engine\fixtures\classes\HelloWorld\HelloWorld.class
cargo run -p pytecode-cli -- rewrite-smoke --jar input.jar --output output.jar --class-name HelloWorld
cargo run -p pytecode-cli -- patch-jar --jar input.jar --output output.jar --rules rules.json
uv run python examples\patch_jar.py --jar input.jar --output output.jar --rules rules.json
cargo run -p pytecode-cli -- deobfuscate analyze --jar path\to\obfuscated-client.jar
cargo run -p pytecode-cli -- deobfuscate rewrite --jar path\to\obfuscated-client.jar --output output\obfuscated-client-cleaned.jar
uv run python examples\deobfuscate.py analyze --jar path\to\obfuscated-client.jar
uv run python examples\deobfuscate.py rewrite --jar path\to\obfuscated-client.jar --output output\obfuscated-client-python-cleaned.jar
patch-jar is the first real config-driven consumer of the Rust archive + transform stack. It reads a JSON rule file, rewrites matching classes in a JAR, and prints a JSON report with per-rule match/change counts.
examples\patch_jar.py mirrors that workflow from Python and accepts the same rules.json shape, but applies it through the Python API.
Example rules.json:
{
"options": {
"debug_info": "preserve",
"frame_mode": "preserve"
},
"rules": [
{
"name": "finalize-main",
"kind": "method",
"owner": {
"name": "HelloWorld"
},
"matcher": {
"name": "main",
"access_all": ["public", "static"],
"has_code": true
},
"action": {
"type": "add-access-flags",
"flags": ["final"]
}
}
]
}
The first version supports:
- class rules for access-flag edits,
set-super-class,add-interface, andremove-interface - field rules for access-flag edits,
rename, andremove - method rules for access-flag edits,
rename, andremove - method
code_actionsfor string replacement, method-call redirection, field-access redirection, opcode-based instruction removal, single-instruction replacement, before/after insertion, contiguous sequence replacement/removal, and groupedsequenceaction blocks
Example sequence rewrite inside code_actions:
{
"type": "replace-sequence",
"pattern": [
{ "ldc_string": "Hello from fixture" },
{
"method_owner": "java/io/PrintStream",
"method_name": "println",
"method_descriptor": "(Ljava/lang/String;)V"
}
],
"replacement": [
{ "type": "ldc-string", "value": "patched via sequence action" },
{
"type": "method",
"opcode": 182,
"owner": "java/io/PrintStream",
"name": "print",
"descriptor": "(Ljava/lang/String;)V"
}
]
}
Sequence patterns use matcher objects (opcode, opcode_any, method_owner, method_name, method_descriptor, field_owner, field_name, field_descriptor, ldc_string, var_slot, type_descriptor, and the is_* category flags). Replacement items support symbolic instructions like raw, ldc-string, field, method, type, var, and iinc, plus label-based control-flow items.
Replacement items can also express symbolic control flow with label, branch, lookup-switch, and table-switch. Branch and switch targets must reference labels declared inside the same replacement block, so malformed control-flow edits fail fast during plan loading instead of producing broken classfiles.
Example grouped rewrite that patches one instruction and brackets another with inserted NOPs:
[
{
"type": "replace-insn",
"matcher": { "ldc_string": "Hello from fixture" },
"replacement": [
{ "type": "ldc-string", "value": "patched via replace-insn" }
]
},
{
"type": "sequence",
"actions": [
{
"type": "insert-before",
"matcher": {
"method_owner": "java/io/PrintStream",
"method_name": "println",
"method_descriptor": "(Ljava/lang/String;)V"
},
"items": [{ "type": "raw", "opcode": 0 }]
},
{
"type": "insert-after",
"matcher": {
"method_owner": "java/io/PrintStream",
"method_name": "println",
"method_descriptor": "(Ljava/lang/String;)V"
},
"items": [{ "type": "raw", "opcode": 0 }]
}
]
}
]
deobfuscate is the higher-level workflow tool built on top of the same archive/model stack. It is aimed at jars like injected-client, where the goal is to inspect obfuscation signals first and then apply safe cleanup passes without hand-authoring JSON rules.
deobfuscate analyze currently reports:
- suspicious short-name class counts and samples
- package concentration (
<root>versus named packages) compilercontrol.jsonJIT exclusion hints- hotspot classes by size/method count
- classes with readable string constants that can anchor reverse-engineering work
deobfuscate rewrite currently applies conservative bytecode cleanup:
- remove
nopinstructions - remove unconditional
gotoinstructions that already target the immediate fallthrough label - collapse unconditional
gotochains to their terminal target
Use patch-jar when you already know the exact bytecode rewrite you want and want a declarative rule file. Use deobfuscate when you want a product-shaped inspection/cleanup pass over an obfuscated jar, especially injected-client.
If you want the same workflow from the Python side, examples\deobfuscate.py
provides the same analyze/rewrite flow on top of pytecode.JarFile,
ClassModel, and Rust-backed Python transforms.
Rust-owned fixtures now live under crates\pytecode-engine\fixtures\. Rust crate tests only read those copied fixture sources and do not invoke Python. The Rust harness lazily compiles crates\pytecode-engine\fixtures\java\*.java into target\pytecode-rust-javac\... and only reruns javac when the source bytes, required --release, or javac identity changes.
bench-smoke now reports isolated-stage timing samples with median+spread summaries instead of only one accumulated elapsed total. tools\benchmark_jar_pipeline.py mirrors that isolated-stage reporting for the wrapper-inclusive Python path, and tools\compare_rust_python_benchmarks.py frames the result as native Rust timings versus Python wrapper overhead on the same jar.
Small Rust examples live under
crates\pytecode-engine\examples\finalize_main.rs and
crates\pytecode-archive\examples\rewrite_jar.rs to show direct transform and
archive rewrite workflows without going through the CLI.
Workspace layout:
pytecode-enginefor classfile parsing, editing, transforms, analysis, and validationpytecode-archivefor JAR handlingpytecode-clifor CLI workflows and benchmarkspytecode-pythonfor PyO3 bindings and wheel packaging
Generate local API reference HTML with:
uv run python tools/generate_api_docs.py
Build source and wheel distributions locally:
uv build
uv build produces both an sdist and a platform wheel for the current machine.
Profile isolated JAR-processing stages without run.py's output overhead:
uv run python tools/profile_jar_pipeline.py path/to/jar.jar
uv run python tools/profile_jar_pipeline.py path/to/jar.jar --stages class-parse model-lift model-lower
uv run python tools/profile_jar_pipeline.py path/to/dir/with/jars --stages model-lift model-lower --summary-json output/profiles/common-libs/summary.json
Compare native Rust vs Python-via-Rust stage timings with the Python extension rebuilt in release mode by default:
uv run python tools/bench_full_comparison.py
uv run python tools/bench_full_comparison.py --extension-build installed
When making runtime-performance changes, prefer checking both a focused jar such as crates\pytecode-engine\fixtures\jars\byte-buddy-1.17.5.jar and the wider common-jar corpus so regressions and wins are not judged from a single artifact. Byte Buddy is the default focused Rust benchmark fixture because it is a common JVM library, carries a much larger class corpus than the old 225.jar fixture, and also includes newer multi-release classes than Guava. A single jar defaults to all stages; directories and multi-jar runs default to model-lift and model-lower.
Release automation
PyPI releases are published from GitHub Actions by pushing an immutable
v<version> tag that matches project.version in pyproject.toml. The same
workflow can also be started manually for an existing tag by supplying a tag
input. In both cases, the workflow checks out the tagged commit, reruns
validation, builds the source distribution plus platform wheels, publishes from
the protected pypi environment via PyPI Trusted Publishing, and then creates
or updates a GitHub Release for the same tag with the built distributions
attached.
Release procedure:
# 1) bump project.version in pyproject.toml
uv run ruff check .
uv run ruff format --check .
uv run basedpyright
uv run pytest -q
uv run python tools/generate_api_docs.py --check
cargo fmt --all --check
cargo clippy --workspace --all-targets -- -D warnings
cargo test --workspace
git commit -am "Bump version to X.Y.Z"
git push origin master
git tag vX.Y.Z
git push origin vX.Y.Z
The release workflow rejects tags that do not match project.version. Treat release tags as immutable: if a tag or published artifact is wrong, bump to a new version and publish a new tag instead of force-pushing the old one. For an existing tag, you can rerun the workflow directly or start it manually from Actions by providing the tag name. The workflow is safe to rerun for the same tag: PyPI uploads skip files that already exist, and the GitHub Release step updates the existing release assets in place if the release was already created.
Repository utilities
run.py is a manual smoke-test helper that parses a JAR file, writes pretty-printed parsed class structures under <jar parent>/output/<jar stem>/parsed/, and writes class-model-derived rewritten .class files plus copied resources under <jar parent>/output/<jar stem>/rewritten/.
Example:
uv run python ./run.py ./path/to/input.jar
The script prints read, parse, lift, write, and rewrite timings plus class and resource counts to stdout.
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distributions
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file pytecode-0.1.0.tar.gz.
File metadata
- Download URL: pytecode-0.1.0.tar.gz
- Upload date:
- Size: 7.9 MB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
2f7f1a6009685ad748a9624d25bdd14f3214cf79c9e94fde03461dbb91cd4e33
|
|
| MD5 |
21e9fb46ec3b73a62d5b82224b5c197b
|
|
| BLAKE2b-256 |
3f1b79fd63cd530ff047caca468fa6140fcf51d3719aed0fa5c2e797db1b9ec8
|
Provenance
The following attestation bundles were made for pytecode-0.1.0.tar.gz:
Publisher:
release.yml on smithtrenton/pytecode
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pytecode-0.1.0.tar.gz -
Subject digest:
2f7f1a6009685ad748a9624d25bdd14f3214cf79c9e94fde03461dbb91cd4e33 - Sigstore transparency entry: 1282822509
- Sigstore integration time:
-
Permalink:
smithtrenton/pytecode@45d4d7dc59e0136e67a82fecea6549585630e615 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/smithtrenton
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@45d4d7dc59e0136e67a82fecea6549585630e615 -
Trigger Event:
push
-
Statement type:
File details
Details for the file pytecode-0.1.0-cp312-abi3-win_arm64.whl.
File metadata
- Download URL: pytecode-0.1.0-cp312-abi3-win_arm64.whl
- Upload date:
- Size: 1.6 MB
- Tags: CPython 3.12+, Windows ARM64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
54e3f25e0eb2d88c751d66713a7f6148b043e6b9c508f37cb9f01e81cda57799
|
|
| MD5 |
917110342de7d3a707e6f7d39d6393f5
|
|
| BLAKE2b-256 |
c573b0ff54dc08245862fcca2a3716ed3bf4564d85a03b91bf0a4e79ca35634f
|
Provenance
The following attestation bundles were made for pytecode-0.1.0-cp312-abi3-win_arm64.whl:
Publisher:
release.yml on smithtrenton/pytecode
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pytecode-0.1.0-cp312-abi3-win_arm64.whl -
Subject digest:
54e3f25e0eb2d88c751d66713a7f6148b043e6b9c508f37cb9f01e81cda57799 - Sigstore transparency entry: 1282822530
- Sigstore integration time:
-
Permalink:
smithtrenton/pytecode@45d4d7dc59e0136e67a82fecea6549585630e615 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/smithtrenton
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@45d4d7dc59e0136e67a82fecea6549585630e615 -
Trigger Event:
push
-
Statement type:
File details
Details for the file pytecode-0.1.0-cp312-abi3-win_amd64.whl.
File metadata
- Download URL: pytecode-0.1.0-cp312-abi3-win_amd64.whl
- Upload date:
- Size: 1.7 MB
- Tags: CPython 3.12+, Windows x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
437d49e3716cd91a4b378b35483b81ca25979ae8f81f43bb007fcd0a0e3476c3
|
|
| MD5 |
d2ea3a521319c3be91fc63996e00e715
|
|
| BLAKE2b-256 |
c478db40a7cbc3c648b2c72c4b2e156addb82ae394599ceea51f1cf1cc3e375f
|
Provenance
The following attestation bundles were made for pytecode-0.1.0-cp312-abi3-win_amd64.whl:
Publisher:
release.yml on smithtrenton/pytecode
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pytecode-0.1.0-cp312-abi3-win_amd64.whl -
Subject digest:
437d49e3716cd91a4b378b35483b81ca25979ae8f81f43bb007fcd0a0e3476c3 - Sigstore transparency entry: 1282822522
- Sigstore integration time:
-
Permalink:
smithtrenton/pytecode@45d4d7dc59e0136e67a82fecea6549585630e615 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/smithtrenton
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@45d4d7dc59e0136e67a82fecea6549585630e615 -
Trigger Event:
push
-
Statement type:
File details
Details for the file pytecode-0.1.0-cp312-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.
File metadata
- Download URL: pytecode-0.1.0-cp312-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
- Upload date:
- Size: 1.9 MB
- Tags: CPython 3.12+, manylinux: glibc 2.17+ x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
1f87773f074379c72a1230fe2b5e6772945b38447dcdf6a4bc58f955a57bfa0f
|
|
| MD5 |
7fd7220d7ff44c9017b3badc54ca9f71
|
|
| BLAKE2b-256 |
f23821146657b09f305a4f410b65c1a70a92abb07eb898f25920dd056abea790
|
Provenance
The following attestation bundles were made for pytecode-0.1.0-cp312-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl:
Publisher:
release.yml on smithtrenton/pytecode
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pytecode-0.1.0-cp312-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl -
Subject digest:
1f87773f074379c72a1230fe2b5e6772945b38447dcdf6a4bc58f955a57bfa0f - Sigstore transparency entry: 1282822521
- Sigstore integration time:
-
Permalink:
smithtrenton/pytecode@45d4d7dc59e0136e67a82fecea6549585630e615 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/smithtrenton
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@45d4d7dc59e0136e67a82fecea6549585630e615 -
Trigger Event:
push
-
Statement type:
File details
Details for the file pytecode-0.1.0-cp312-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.
File metadata
- Download URL: pytecode-0.1.0-cp312-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
- Upload date:
- Size: 1.8 MB
- Tags: CPython 3.12+, manylinux: glibc 2.17+ ARM64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
cabd96d213944267d1ace79f01c0c917e87b02daf754fef44cc67ce882dae4cf
|
|
| MD5 |
738d93811dc17afbad336f58ff224c7e
|
|
| BLAKE2b-256 |
4714567900c7c0297533d489c84ce4d5954f416ff5116677ab89e12b24217920
|
Provenance
The following attestation bundles were made for pytecode-0.1.0-cp312-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl:
Publisher:
release.yml on smithtrenton/pytecode
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pytecode-0.1.0-cp312-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl -
Subject digest:
cabd96d213944267d1ace79f01c0c917e87b02daf754fef44cc67ce882dae4cf - Sigstore transparency entry: 1282822512
- Sigstore integration time:
-
Permalink:
smithtrenton/pytecode@45d4d7dc59e0136e67a82fecea6549585630e615 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/smithtrenton
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@45d4d7dc59e0136e67a82fecea6549585630e615 -
Trigger Event:
push
-
Statement type:
File details
Details for the file pytecode-0.1.0-cp312-abi3-macosx_11_0_arm64.whl.
File metadata
- Download URL: pytecode-0.1.0-cp312-abi3-macosx_11_0_arm64.whl
- Upload date:
- Size: 1.7 MB
- Tags: CPython 3.12+, macOS 11.0+ ARM64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
761319f6bd74f74101d63bb3a187f447595a571e1e5a03f7609550d7ac71f5a2
|
|
| MD5 |
59db26fd01df9202dbe70465e5644d84
|
|
| BLAKE2b-256 |
d68a08f2d62d4ccfdbdff36bf36cbbdb7d8fa7f440503c8ebe367cc2c07c9650
|
Provenance
The following attestation bundles were made for pytecode-0.1.0-cp312-abi3-macosx_11_0_arm64.whl:
Publisher:
release.yml on smithtrenton/pytecode
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pytecode-0.1.0-cp312-abi3-macosx_11_0_arm64.whl -
Subject digest:
761319f6bd74f74101d63bb3a187f447595a571e1e5a03f7609550d7ac71f5a2 - Sigstore transparency entry: 1282822517
- Sigstore integration time:
-
Permalink:
smithtrenton/pytecode@45d4d7dc59e0136e67a82fecea6549585630e615 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/smithtrenton
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@45d4d7dc59e0136e67a82fecea6549585630e615 -
Trigger Event:
push
-
Statement type:
File details
Details for the file pytecode-0.1.0-cp312-abi3-macosx_10_12_x86_64.whl.
File metadata
- Download URL: pytecode-0.1.0-cp312-abi3-macosx_10_12_x86_64.whl
- Upload date:
- Size: 1.8 MB
- Tags: CPython 3.12+, macOS 10.12+ x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b1949e5a9ba685f253b065690013d7cfd7e4c04fdc1cfda87871b434455928e1
|
|
| MD5 |
089cccbcd22f233e26fb5818e5b63a1f
|
|
| BLAKE2b-256 |
f240059944bb2d093dd097863fdbe58a24e68e90840fdca55cc9735643a6f906
|
Provenance
The following attestation bundles were made for pytecode-0.1.0-cp312-abi3-macosx_10_12_x86_64.whl:
Publisher:
release.yml on smithtrenton/pytecode
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pytecode-0.1.0-cp312-abi3-macosx_10_12_x86_64.whl -
Subject digest:
b1949e5a9ba685f253b065690013d7cfd7e4c04fdc1cfda87871b434455928e1 - Sigstore transparency entry: 1282822526
- Sigstore integration time:
-
Permalink:
smithtrenton/pytecode@45d4d7dc59e0136e67a82fecea6549585630e615 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/smithtrenton
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@45d4d7dc59e0136e67a82fecea6549585630e615 -
Trigger Event:
push
-
Statement type: