Skip to content

Commit 72e0f2a

Browse files
committed
pyo3 bindings
Advantages ========== - Can do the entire loading in one shot in pure rust from a python iterable. - Work using rust semantics. - Really just works. - Only requires a pyi for type declarations (?). Drawbacks ========= - Likely slower than cffi for pypy, but unlikely to be slower than the slog of pure python. - Graal don't work in tox (oracle/graalpython#427).
1 parent 40e44d1 commit 72e0f2a

14 files changed

+945
-7
lines changed

.github/workflows/pychecks.yaml

+41
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
name: py checks
2+
3+
on:
4+
pull_request:
5+
push:
6+
branches:
7+
- main
8+
9+
permissions:
10+
contents: read
11+
12+
jobs:
13+
checks:
14+
runs-on: ubuntu-latest
15+
steps:
16+
- name: Checkout working copy
17+
uses: actions/checkout@v4
18+
- name: ruff check
19+
uses: chartboost/ruff-action@v1
20+
with:
21+
args: check
22+
- name: ruff format
23+
if: always()
24+
uses: chartboost/ruff-action@v1
25+
with:
26+
args: format --diff
27+
- name: Set up Python
28+
id: setup_python
29+
if: always()
30+
uses: actions/setup-python@v5
31+
with:
32+
python-version: "3.x"
33+
- name: Install mypy
34+
id: install_mypy
35+
if: ${{ always() && steps.setup_python.conclusion == 'success' }}
36+
run: |
37+
python -mpip install --upgrade pip
38+
python -mpip install mypy pytest types-PyYaml
39+
- name: mypy
40+
if: ${{ always() && steps.install_mypy.conclusion == 'success' }}
41+
run: mypy --strict .

.github/workflows/pyo3-wheels.yml

+193
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,193 @@
1+
name: Wheels and Tests
2+
3+
on:
4+
push:
5+
branches: [ main ]
6+
pull_request:
7+
workflow_dispatch:
8+
9+
permissions:
10+
contents: read
11+
12+
jobs:
13+
wheels:
14+
strategy:
15+
matrix:
16+
python-version:
17+
- "3.x"
18+
- "pypy-3.10"
19+
- "graalpy-24"
20+
arch:
21+
- x86_64
22+
- aarch64
23+
platform:
24+
- linux
25+
- musllinux
26+
- windows
27+
- macos
28+
29+
exclude:
30+
- platform: windows
31+
arch: aarch64
32+
- platform: windows
33+
python-version: graalpy-24
34+
35+
include:
36+
- platform: linux
37+
manylinux: auto
38+
- platform: musllinux
39+
manylinux: musllinux_1_2
40+
41+
- args: --release --out dist -m ua-parser-py/Cargo.toml -i python
42+
- platform: linux
43+
args: --release --out dist -m ua-parser-py/Cargo.toml -i python --zig
44+
- platform: musllinux
45+
args: --release --out dist -m ua-parser-py/Cargo.toml
46+
47+
- runs: ubuntu-latest
48+
- platform: windows
49+
runs: windows-latest
50+
- platform: macos
51+
runs: macos-latest
52+
53+
runs-on: ${{ matrix.runs }}
54+
55+
steps:
56+
- uses: actions/checkout@v4
57+
- uses: actions/setup-python@v5
58+
with:
59+
python-version: ${{ matrix.python-version }}
60+
- name: Build wheels
61+
uses: PyO3/maturin-action@v1
62+
with:
63+
target: ${{ matrix.arch }}
64+
args: ${{ matrix.args }}
65+
sccache: 'true'
66+
manylinux: ${{ matrix.manylinux }}
67+
- name: Upload wheels
68+
uses: actions/upload-artifact@v4
69+
with:
70+
name: wheels-${{ matrix.platform }}-${{ matrix.arch }}-${{ matrix.python-version }}
71+
path: dist/*
72+
73+
sdist:
74+
runs-on: ubuntu-latest
75+
steps:
76+
- uses: actions/checkout@v4
77+
- name: Build sdist
78+
uses: PyO3/maturin-action@v1
79+
with:
80+
command: sdist
81+
args: --out dist -m ua-parser-py/Cargo.toml
82+
- name: Upload sdist
83+
uses: actions/upload-artifact@v4
84+
with:
85+
name: wheels-sdist
86+
path: dist
87+
88+
# TODO: tags don't work because multiple crates in same repo, so
89+
# needs some other method of picking versions
90+
release:
91+
name: Release
92+
runs-on: ubuntu-latest
93+
if: ${{ github.event_name == 'workflow_dispatch' }}
94+
needs: [wheels, sdist]
95+
permissions:
96+
# Use to sign the release artifacts
97+
id-token: write
98+
# Used to upload release artifacts
99+
contents: write
100+
# Used to generate artifact attestation
101+
attestations: write
102+
steps:
103+
- uses: actions/download-artifact@v4
104+
- name: Generate artifact attestation
105+
uses: actions/attest-build-provenance@v1
106+
with:
107+
subject-path: 'wheels-*/*'
108+
- name: Publish to PyPI
109+
uses: PyO3/maturin-action@v1
110+
env:
111+
MATURIN_PYPI_TOKEN: ${{ secrets.PYPI_API_TOKEN }}
112+
with:
113+
command: upload
114+
args: --non-interactive --skip-existing wheels-*/*
115+
116+
tests:
117+
needs: wheels
118+
119+
strategy:
120+
fail-fast: false
121+
matrix:
122+
python-version:
123+
- "3.9"
124+
- "3.10"
125+
- "3.11"
126+
- "3.12"
127+
- "3.13"
128+
- "pypy-3.10"
129+
- "graalpy-24"
130+
platform:
131+
- linux
132+
# probably requires a custom image of some sort
133+
# - musllinux
134+
- windows
135+
- macos
136+
137+
exclude:
138+
- platform: windows
139+
python-version: graalpy-24
140+
141+
include:
142+
# would probably need to run qemu inside the thing to full
143+
# test the archs...
144+
- arch: x86_64
145+
- platform: macos
146+
arch: aarch64
147+
148+
- wheel: "3.x"
149+
- python-version: "pypy-3.10"
150+
wheel: "pypy-3.10"
151+
- python-version: "graalpy-24"
152+
wheel: "graalpy-24"
153+
154+
- runs: ubuntu-latest
155+
- platform: windows
156+
runs: windows-latest
157+
- platform: macos
158+
runs: macos-latest
159+
160+
runs-on: ${{ matrix.runs }}
161+
162+
steps:
163+
- name: Checkout working copy
164+
uses: actions/checkout@v4
165+
with:
166+
submodules: true
167+
- name: Set up Python ${{ matrix.python-version }}
168+
uses: actions/setup-python@v5
169+
with:
170+
python-version: ${{ matrix.python-version }}
171+
allow-prereleases: true
172+
- name: Retrieve wheel
173+
uses: actions/download-artifact@v4
174+
with:
175+
name: wheels-${{ matrix.platform }}-${{ matrix.arch }}-${{ matrix.wheel }}
176+
path: dist
177+
- name: Update pip
178+
run: python -mpip install --upgrade pip
179+
- name: Maybe install libyaml-dev
180+
if: matrix.runs == 'ubuntu-latest'
181+
run: |
182+
# if binary wheels are not available for the current
183+
# package install libyaml-dev so we can install pyyaml
184+
# from source
185+
if ! pip download --only-binary :all: pyyaml > /dev/null 2>&1; then
186+
sudo apt install libyaml-dev
187+
fi
188+
- name: Install test dependencies
189+
run: python -mpip install pytest pyyaml
190+
- name: Install wheel
191+
run: pip install --find-links dist ua_parser_rs
192+
- name: Run tests
193+
run: pytest -v -Werror -ra ua-parser-py

.github/workflows/rust.yml

+5-6
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,24 @@
11
name: Rust
22

33
on:
4-
push:
5-
branches: [ "main" ]
64
pull_request:
7-
branches: [ "main" ]
5+
push:
6+
branches:
7+
- main
88

99
env:
1010
CARGO_TERM_COLOR: always
1111

1212
jobs:
1313
checks:
14-
1514
runs-on: ubuntu-latest
1615

1716
steps:
1817
- uses: actions/checkout@v4
1918
with:
2019
submodules: true
21-
- name: Build
22-
run: cargo build --verbose
20+
- name: Check
21+
run: cargo check
2322
- name: Format
2423
run: cargo fmt --check
2524
- name: clippy

.gitignore

+2
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,5 @@ Cargo.lock
44
*.dSYM/
55
regex-filtered/re2/flake.lock
66
regex-filtered/re2/bench
7+
.tox/
8+
__pycache__

Cargo.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
[workspace]
2-
members = ["regex-filtered", "ua-parser"]
2+
members = ["regex-filtered", "ua-parser", "ua-parser-py"]
33
resolver = "2"
44

55
[profile.release]

ua-parser-py/Cargo.toml

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
[package]
2+
name = "ua-parser-rs"
3+
version = "0.1.0"
4+
edition = "2021"
5+
license = "Apache 2.0"
6+
7+
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
8+
[lib]
9+
name = "ua_parser_rs"
10+
crate-type = ["cdylib"]
11+
12+
[dependencies]
13+
pyo3 = { version = "0.22", features = ["extension-module", "abi3", "abi3-py38"] }
14+
ua-parser = { version = "0.2.0", path = "../ua-parser" }

0 commit comments

Comments
 (0)