Skip to content

Commit 1d1f4b1

Browse files
committed
Merge branch 'main' into optimize-dict-set-item
# Conflicts: # src/lib.rs
2 parents 596ea37 + 0f7dec9 commit 1d1f4b1

21 files changed

Lines changed: 946 additions & 133 deletions

.github/workflows/codspeed.yml

Lines changed: 38 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -10,17 +10,23 @@ on:
1010
permissions:
1111
contents: read
1212

13+
env:
14+
UV_FROZEN: true
15+
UV_PYTHON: 3.13 # use the latest version of Python because it is faster
16+
1317
jobs:
1418
benchmarks:
1519
runs-on: ubuntu-latest
1620
steps:
1721
- uses: actions/checkout@v4
18-
- uses: actions/setup-python@v5
22+
- uses: actions/setup-python@v5 # required for correct CodSpeed integration
1923
with:
20-
python-version: "3.12" # use the latest version of Python because it is faster
24+
python-version: ${{ env.UV_PYTHON }}
2125

22-
- name: Install python dependencies.
23-
run: pip install -r pytests/requirements.txt
26+
- name: Install UV.
27+
uses: astral-sh/setup-uv@v6
28+
with:
29+
enable-cache: true
2430

2531
- name: Install rust.
2632
id: rust-toolchain
@@ -31,24 +37,45 @@ jobs:
3137
- name: Cache rust.
3238
uses: Swatinem/rust-cache@v2
3339

34-
- name: Compile.
35-
run: pip install -v -e .
40+
- name: Build wheel with profile generation.
41+
uses: PyO3/maturin-action@v1
42+
with:
43+
manylinux: auto
44+
args: --release --out pgo-wheel --interpreter ${{ env.UV_PYTHON }}
45+
rust-toolchain: 1.76.0
46+
docker-options: -e CI
3647
env:
3748
RUSTFLAGS: "-Cprofile-generate=${{ github.workspace }}/profdata"
3849

3950
- name: Gather PGO data.
40-
run: pytest . --benchmark-enable
51+
run: |
52+
uv sync --group testing
53+
uv pip install libipld --no-index --no-deps --find-links pgo-wheel --force-reinstall
54+
55+
uv run pytest . --benchmark-enable
4156
4257
- name: Prepare merged PGO data.
4358
run: rustup run 1.76.0 bash -c '$RUSTUP_HOME/toolchains/$RUSTUP_TOOLCHAIN/lib/rustlib/x86_64-unknown-linux-gnu/bin/llvm-profdata merge -o ${{ github.workspace }}/merged.profdata ${{ github.workspace }}/profdata'
4459

45-
- name: Compile with profile.
46-
run: pip install -v -e .
60+
- name: Build PGO-optimized wheel.
61+
uses: PyO3/maturin-action@v1
62+
with:
63+
manylinux: auto
64+
args: --release --out dist --interpreter ${{ env.UV_PYTHON }}
65+
rust-toolchain: 1.76.0
66+
docker-options: -e CI
4767
env:
4868
RUSTFLAGS: "-Cprofile-use=${{ github.workspace }}/merged.profdata"
4969

50-
- name: Run benchmarks.
70+
- name: Find PGO built wheel.
71+
id: pgo-wheel
72+
run: echo "path=$(ls dist/*.whl)" | tee -a "$GITHUB_OUTPUT"
73+
74+
- name: Install PGO wheel.
75+
run: uv pip install ${{ steps.pgo-wheel.outputs.path }} --force-reinstall
76+
77+
- name: Run CodSpeed benchmarks.
5178
uses: CodSpeedHQ/action@v3
5279
with:
5380
token: ${{ secrets.CODSPEED_TOKEN }}
54-
run: pytest . --codspeed -n auto
81+
run: uv run --group=codspeed pytest . --codspeed -n auto

.github/workflows/release.yml

Lines changed: 26 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -25,39 +25,39 @@ jobs:
2525

2626
- os: windows
2727
target: x86_64
28-
interpreter: pypy3.9 pypy3.10
28+
interpreter: pypy3.9 pypy3.10 pypy3.11
2929
- os: windows
3030
target: i686
3131
python-architecture: x86
32-
interpreter: 3.7 3.8 3.9 3.10 3.11 3.12
32+
interpreter: 3.8 3.9 3.10 3.11 3.12 3.13
3333
- os: windows
3434
target: aarch64
35-
interpreter: 3.11 3.12
35+
interpreter: 3.11 3.12 3.13
3636

3737
- os: macos
3838
target: x86_64
39-
interpreter: pypy3.8 pypy3.9 pypy3.10
39+
interpreter: pypy3.9 pypy3.10 pypy3.11
4040
- os: macos
4141
target: aarch64
4242
# actions/setup-python@v5 does not support 3.8 and 3.9 on arm64
43-
interpreter: 3.7 3.8 3.9 pypy3.8 pypy3.9 pypy3.10
43+
interpreter: 3.8 3.9 pypy3.9 pypy3.10 pypy3.11
4444

4545
- os: ubuntu
4646
target: x86_64
47-
interpreter: pypy3.9 pypy3.10
47+
interpreter: pypy3.9 pypy3.10 pypy3.11
4848
- os: ubuntu
4949
target: i686
5050
- os: ubuntu
5151
target: aarch64
5252
- os: ubuntu
5353
target: armv7
54-
interpreter: 3.7 3.8 3.9 3.10 3.11 3.12
54+
interpreter: 3.8 3.9 3.10 3.11 3.12 3.13
5555
- os: ubuntu
5656
target: ppc64le
57-
interpreter: 3.7 3.8 3.9 3.10 3.11 3.12
57+
interpreter: 3.8 3.9 3.10 3.11 3.12 3.13
5858
- os: ubuntu
5959
target: s390x
60-
interpreter: 3.7 3.8 3.9 3.10 3.11 3.12
60+
interpreter: 3.8 3.9 3.10 3.11 3.12 3.13
6161

6262
- os: ubuntu
6363
target: x86_64
@@ -89,8 +89,7 @@ jobs:
8989
with:
9090
target: ${{ matrix.target }}
9191
manylinux: ${{ matrix.manylinux || 'auto' }}
92-
container: ${{ matrix.container }}
93-
args: --release --out dist --interpreter ${{ matrix.maturin-interpreter || matrix.interpreter || '3.7 3.8 3.9 3.10 3.11 3.12 pypy3.7 pypy3.8 pypy3.9 pypy3.10' }} ${{ matrix.extra-build-args }}
92+
args: --release --out dist --interpreter ${{ matrix.interpreter || '3.8 3.9 3.10 3.11 3.12 3.13 pypy3.9 pypy3.10 pypy3.11' }}
9493
rust-toolchain: 1.76.0
9594
docker-options: -e CI
9695

@@ -108,11 +107,9 @@ jobs:
108107
strategy:
109108
fail-fast: false
110109
matrix:
111-
os: [ ubuntu-latest, windows-latest, macos-12, macos-14 ]
112-
interpreter: [ '3.7', '3.8', '3.9', '3.10', '3.11', '3.12' ]
110+
os: [ ubuntu-latest, windows-latest, macos-13, macos-14 ]
111+
interpreter: [ '3.8', '3.9', '3.10', '3.11', '3.12', '3.13' ]
113112
exclude:
114-
- os: macos-14
115-
interpreter: '3.7'
116113
# actions/setup-python@v5 does not support 3.8 and 3.9 on arm64
117114
- os: macos-14
118115
interpreter: '3.8'
@@ -126,8 +123,16 @@ jobs:
126123
run: |
127124
git config --global core.autocrlf false
128125
git config --global core.eol lf
129-
- uses: actions/checkout@v4
130-
- uses: actions/setup-python@v5
126+
127+
- name: Checkout repository.
128+
uses: actions/checkout@v4
129+
130+
- uses: actions/setup-python@v5 # required for macos-13 with Python 3.8-3.10... otherwise UV uses PyPy...
131+
with:
132+
python-version: ${{ matrix.interpreter }}
133+
134+
- name: Install UV.
135+
uses: astral-sh/setup-uv@v6
131136
with:
132137
python-version: ${{ matrix.interpreter }}
133138

@@ -153,11 +158,10 @@ jobs:
153158

154159
- name: Gather PGO data.
155160
run: |
156-
pip install -U pip
157-
pip install -r pytests/requirements.txt
161+
uv sync --group testing
162+
uv pip install libipld --no-index --no-deps --find-links pgo-wheel --force-reinstall
158163
159-
pip install libipld --no-index --no-deps --find-links pgo-wheel --force-reinstall
160-
pytest . --benchmark-enable
164+
uv run pytest . --benchmark-enable
161165
162166
# we can't use github.workspace here because of Windows with backslashes
163167
rustup run 1.76.0 bash -c 'echo LLVM_PROFDATA=$RUSTUP_HOME/toolchains/$RUSTUP_TOOLCHAIN/lib/rustlib/${{ env.RUST_HOST }}/bin/llvm-profdata >> "$GITHUB_ENV"'
@@ -207,7 +211,7 @@ jobs:
207211
- uses: actions/checkout@v4
208212
- uses: actions/setup-python@v5
209213
with:
210-
python-version: '3.12'
214+
python-version: '3.13'
211215

212216
- name: Get dist artifacts.
213217
uses: actions/download-artifact@v4

.github/workflows/test.yml

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@ on: [ pull_request ]
55
permissions:
66
contents: read
77

8+
env:
9+
UV_PYTHON: 3.8 # minimum supported version
10+
811
jobs:
912
unit_tests:
1013
runs-on: ubuntu-latest
@@ -13,15 +16,16 @@ jobs:
1316
- name: Checkout repository.
1417
uses: actions/checkout@v4
1518

16-
- name: Set up Python.
17-
uses: actions/setup-python@v5
18-
with:
19-
python-version: 3.7
19+
- name: Install UV.
20+
uses: astral-sh/setup-uv@v6
2021

2122
- name: Install dependencies.
22-
run: |
23-
pip install -r pytests/requirements.txt
24-
pip install -v -e .
23+
run: uv sync --group testing
24+
25+
- name: Compile.
26+
run: uv pip install -v -e .
27+
env:
28+
RUST_BACKTRACE: 1
2529

2630
- name: Run Tests.
27-
run: pytest
31+
run: uv run pytest

.gitignore

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
*.py[cod]
2+
13
# Generated by Cargo
24
# will have compiled files and executables
35
debug/
@@ -15,6 +17,7 @@ Cargo.lock
1517

1618
# IDE
1719
.idea
20+
*.iml
1821
.vscode
1922

2023
# Python virtual environment
@@ -28,3 +31,6 @@ test.py
2831
__pycache__
2932
.benchmarks
3033
.pytest_cache
34+
35+
# Build artifacts
36+
*.so

Cargo.toml

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,23 @@
11
[package]
22
name = "libipld"
3-
version = "2.0.0"
3+
version = "3.1.0"
44
edition = "2021"
55
license = "MIT"
66
description = "Python binding to the Rust IPLD library"
77
authors = ["Ilya (Marshal) <ilya@marshal.dev>"]
8-
keywords = ["python", "binding", "library", "lib", "ipld", "cid", "multibase", "multihash", "dag", "cbor", "json", "pb", "dag-cbor", "dag-json", "dag-pb"]
8+
keywords = ["ipld", "cid", "multibase", "multihash", "dag-cbor"]
99

1010
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
1111
[lib]
1212
name = "libipld"
1313
crate-type = ["rlib", "cdylib"]
1414

1515
[dependencies]
16-
pyo3 = { version = "0.22.2", features = ["generate-import-lib", "anyhow"] }
17-
python3-dll-a = "0.2.7"
18-
anyhow = "1.0.75"
16+
pyo3 = { version = "0.25.1", features = ["generate-import-lib", "anyhow"] }
17+
python3-dll-a = "0.2.14"
18+
anyhow = "1.0.95"
1919
libipld = { version = "0.16.0", features = ["dag-cbor"] }
20-
multibase = "0.9"
20+
multibase = "0.9.1"
2121
byteorder = "1.5.0"
2222
multihash = "0.18.1"
2323

LICENSE

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
MIT License
22

3-
Copyright (c) 2023 Ilya Siamionau
3+
Copyright (c) 2025 Ilya Siamionau
44

55
Permission is hereby granted, free of charge, to any person obtaining a copy
66
of this software and associated documentation files (the "Software"), to deal

README.md

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -28,26 +28,32 @@ print(libipld.encode_multibase('u', b'yes mani !'))
2828

2929
### Features
3030

31-
- Decode DAG-CBOR (`decode_dag_cbor(bytes) -> dict`, `decode_dag_cbor_multi(bytes) -> list[dict]`)
32-
- Encode DAG-CBOR (`encode_dag_cbor(obj) -> bytes`)
33-
- Decode CID (`decode_cid(str | bytes) -> dict`). Accepts CID stringified form or CID raw byte form.
34-
- Encode CID (`encode_cid(bytes) -> str`). Encodes CID raw byte form to stringified form.
35-
- Decode Multibase (`decode_multibase(str) -> tuple[str, bytes]`). Returns base and data.
36-
- Encode Multibase (`encode_multibase(str, bytes) -> str`). Accepts base and data.
37-
- Decode CAR (`decode_car(bytes) -> tuple[dict, dict[str, dict]]`). Returns a header and blocks mapped by CID. CIDs in raw byte form.
31+
#### 🔗 CID (Content Identifier) Operations
32+
- **`decode_cid(data: str | bytes) -> dict`** - Decode CIDs from string representation (e.g., `'bafy...'`) or raw bytes into structured data containing version, codec, and hash information
33+
- **`encode_cid(data: str | bytes) -> str`** - Encode CID raw bytes to string representation, or return string CIDs as-is
3834

39-
Note: stub file will be provided in the future.
35+
#### 📦 DAG-CBOR (Directed Acyclic Graph CBOR) Operations
36+
- **`decode_dag_cbor(data: bytes) -> Any`** - Decode DAG-CBOR binary data into Python objects (dicts, lists, primitives)
37+
- **`decode_dag_cbor_multi(data: bytes) -> list[Any]`** - Decode multiple concatenated DAG-CBOR objects from a single byte stream
38+
- **`encode_dag_cbor(data: Any) -> bytes`** - Encode Python objects into DAG-CBOR binary format
4039

41-
## Requirements
40+
#### 🌐 Multibase Operations
41+
- **`decode_multibase(data: str) -> tuple[str, bytes]`** - Decode multibase-encoded strings, returning the base identifier and decoded data
42+
- **`encode_multibase(code: str, data: str | bytes) -> str`** - Encode data using specified multibase encoding (e.g., base58btc with code `'u'`)
4243

43-
- Python 3.7 or higher.
44+
#### 🚗 CAR (Content Addressable Archives) Operations
45+
- **`decode_car(data: bytes) -> tuple[dict, dict[bytes, dict]]`** - Decode CAR files into header metadata and a mapping of CID bytes to block data
4446

45-
## Installing
47+
### Requirements
48+
49+
- Python 3.8 or higher.
50+
51+
### Installing
4652

4753
You can install or upgrade `libipld` via
4854

4955
```bash
50-
pip install libipld
56+
pip install -U libipld
5157
```
5258

5359
### Contributing
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
�`������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������e$typerapp.bsky.feed.psot

data/torture_nested_lists.dagcbor

Lines changed: 1 addition & 0 deletions
Large diffs are not rendered by default.

0 commit comments

Comments
 (0)