Skip to content

Commit 9bb89c1

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 9bb89c1

File tree

13 files changed

+745
-7
lines changed

13 files changed

+745
-7
lines changed

.github/workflows/pychecks.yaml

Lines changed: 41 additions & 0 deletions
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

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

.github/workflows/rust.yml

Lines changed: 5 additions & 6 deletions
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

Lines changed: 2 additions & 0 deletions
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

Lines changed: 1 addition & 1 deletion
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

Lines changed: 13 additions & 0 deletions
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.22", features = ["extension-module", "abi3", "abi3-py38"] }
13+
ua-parser = { version = "0.2.0", path = "../ua-parser" }

ua-parser-py/pyproject.toml

Lines changed: 15 additions & 0 deletions
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)