Skip to content

Commit ffe4fae

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.
1 parent 40e44d1 commit ffe4fae

14 files changed

+779
-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

+177
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,177 @@
1+
# This file is autogenerated by maturin v1.7.4
2+
# To update, run
3+
#
4+
# maturin generate-ci --zig github
5+
#
6+
name: build wheels
7+
8+
on:
9+
push:
10+
branches:
11+
- main
12+
- master
13+
tags:
14+
- '*'
15+
pull_request:
16+
workflow_dispatch:
17+
18+
permissions:
19+
contents: read
20+
21+
jobs:
22+
linux:
23+
runs-on: ${{ matrix.platform.runner }}
24+
strategy:
25+
matrix:
26+
platform:
27+
- runner: ubuntu-latest
28+
target: x86_64
29+
- runner: ubuntu-latest
30+
target: x86
31+
- runner: ubuntu-latest
32+
target: aarch64
33+
- runner: ubuntu-latest
34+
target: armv7
35+
steps:
36+
- uses: actions/checkout@v4
37+
- uses: actions/setup-python@v5
38+
with:
39+
python-version: 3.x
40+
- name: Build wheels
41+
uses: PyO3/maturin-action@v1
42+
with:
43+
target: ${{ matrix.platform.target }}
44+
args: --release --out dist --zig
45+
sccache: 'true'
46+
manylinux: auto
47+
- name: Upload wheels
48+
uses: actions/upload-artifact@v4
49+
with:
50+
name: wheels-linux-${{ matrix.platform.target }}
51+
path: dist
52+
53+
musllinux:
54+
runs-on: ${{ matrix.platform.runner }}
55+
strategy:
56+
matrix:
57+
platform:
58+
- runner: ubuntu-latest
59+
target: x86_64
60+
- runner: ubuntu-latest
61+
target: x86
62+
- runner: ubuntu-latest
63+
target: aarch64
64+
- runner: ubuntu-latest
65+
target: armv7
66+
steps:
67+
- uses: actions/checkout@v4
68+
- uses: actions/setup-python@v5
69+
with:
70+
python-version: 3.x
71+
- name: Build wheels
72+
uses: PyO3/maturin-action@v1
73+
with:
74+
target: ${{ matrix.platform.target }}
75+
args: --release --out dist
76+
sccache: 'true'
77+
manylinux: musllinux_1_2
78+
- name: Upload wheels
79+
uses: actions/upload-artifact@v4
80+
with:
81+
name: wheels-musllinux-${{ matrix.platform.target }}
82+
path: dist
83+
84+
windows:
85+
runs-on: ${{ matrix.platform.runner }}
86+
strategy:
87+
matrix:
88+
platform:
89+
- runner: windows-latest
90+
target: x64
91+
- runner: windows-latest
92+
target: x86
93+
steps:
94+
- uses: actions/checkout@v4
95+
- uses: actions/setup-python@v5
96+
with:
97+
python-version: 3.x
98+
architecture: ${{ matrix.platform.target }}
99+
- name: Build wheels
100+
uses: PyO3/maturin-action@v1
101+
with:
102+
target: ${{ matrix.platform.target }}
103+
args: --release --out dist
104+
sccache: 'true'
105+
- name: Upload wheels
106+
uses: actions/upload-artifact@v4
107+
with:
108+
name: wheels-windows-${{ matrix.platform.target }}
109+
path: dist
110+
111+
macos:
112+
runs-on: ${{ matrix.platform.runner }}
113+
strategy:
114+
matrix:
115+
platform:
116+
- runner: macos-12
117+
target: x86_64
118+
- runner: macos-14
119+
target: aarch64
120+
steps:
121+
- uses: actions/checkout@v4
122+
- uses: actions/setup-python@v5
123+
with:
124+
python-version: 3.x
125+
- name: Build wheels
126+
uses: PyO3/maturin-action@v1
127+
with:
128+
target: ${{ matrix.platform.target }}
129+
args: --release --out dist
130+
sccache: 'true'
131+
- name: Upload wheels
132+
uses: actions/upload-artifact@v4
133+
with:
134+
name: wheels-macos-${{ matrix.platform.target }}
135+
path: dist
136+
137+
sdist:
138+
runs-on: ubuntu-latest
139+
steps:
140+
- uses: actions/checkout@v4
141+
- name: Build sdist
142+
uses: PyO3/maturin-action@v1
143+
with:
144+
command: sdist
145+
args: --out dist
146+
- name: Upload sdist
147+
uses: actions/upload-artifact@v4
148+
with:
149+
name: wheels-sdist
150+
path: dist
151+
152+
release:
153+
name: Release
154+
runs-on: ubuntu-latest
155+
if: ${{ startsWith(github.ref, 'refs/tags/') || github.event_name == 'workflow_dispatch' }}
156+
needs: [linux, musllinux, windows, macos, sdist]
157+
permissions:
158+
# Use to sign the release artifacts
159+
id-token: write
160+
# Used to upload release artifacts
161+
contents: write
162+
# Used to generate artifact attestation
163+
attestations: write
164+
steps:
165+
- uses: actions/download-artifact@v4
166+
- name: Generate artifact attestation
167+
uses: actions/attest-build-provenance@v1
168+
with:
169+
subject-path: 'wheels-*/*'
170+
- name: Publish to PyPI
171+
if: "startsWith(github.ref, 'refs/tags/')"
172+
uses: PyO3/maturin-action@v1
173+
env:
174+
MATURIN_PYPI_TOKEN: ${{ secrets.PYPI_API_TOKEN }}
175+
with:
176+
command: upload
177+
args: --non-interactive --skip-existing wheels-*/*

.github/workflows/pytests.yaml

+55
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
name: py tests
2+
3+
on:
4+
pull_request:
5+
push:
6+
branches:
7+
- main
8+
9+
permissions:
10+
contents: read
11+
12+
jobs:
13+
tests:
14+
runs-on: ubuntu-latest
15+
strategy:
16+
fail-fast: false
17+
matrix:
18+
python-version:
19+
- "3.8"
20+
- "3.9"
21+
- "3.10"
22+
- "3.11"
23+
- "3.12"
24+
- "3.13"
25+
- "pypy-3.8"
26+
- "pypy-3.9"
27+
- "pypy-3.10"
28+
- "graalpy-24"
29+
steps:
30+
- name: Checkout working copy
31+
uses: actions/checkout@v4
32+
with:
33+
submodules: true
34+
- name: Set up Python ${{ matrix.python-version }}
35+
uses: actions/setup-python@v5
36+
with:
37+
python-version: ${{ matrix.python-version }}
38+
allow-prereleases: true
39+
- name: Install test dependencies
40+
run: |
41+
python -mpip install --upgrade pip
42+
# cyaml is outright broken on pypy
43+
#if ! ${{ startsWith(matrix.python-version, 'pypy-') }}; then
44+
# if binary wheels are not available for the current
45+
# package install libyaml-dev so we can install pyyaml
46+
# from source
47+
if ! pip download --only-binary pyyaml > /dev/null 2>&1; then
48+
sudo apt install libyaml-dev
49+
fi
50+
#fi
51+
python -mpip install pytest pyyaml
52+
- name: install package
53+
run: pip install ./ua-parser-py
54+
- name: run tests
55+
run: pytest -v -Werror -ra .

.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

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

ua-parser-py/pyproject.toml

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
[build-system]
2+
requires = ["maturin>=1.5,<2.0"]
3+
build-backend = "maturin"
4+
5+
[project]
6+
name = "ua_parser_rs"
7+
requires-python = ">=3.8"
8+
classifiers = [
9+
"Programming Language :: Rust",
10+
"Programming Language :: Python :: Implementation :: CPython",
11+
"Programming Language :: Python :: Implementation :: PyPy",
12+
]
13+
dynamic = ["version"]
14+
[tool.maturin]
15+
features = ["pyo3/extension-module"]

0 commit comments

Comments
 (0)