Repository navigation
Conversation
Add a maturin/pyo3 build for blastdns, an async DNS resolver backed by a Rust core (hickory-proto/hickory-resolver). No tag exists on the upstream repo for any release, so pin the 1.9.1 release commit directly (proven byte-identical to the PyPI sdist). Backport PR #130's license fix as a patch: the 1.9.1 sdist/wheels carry no LICENSE file and mislabel the project "GPL-3.0" in Cargo.toml/pyproject.toml, while the actual license is AGPL-3.0. hickory-proto's dnssec-aws-lc-rs feature pulls in aws-lc-sys, which ships prebuilt riscv64gc crypto bindings and needs only cmake (already in the manylinux image) to cross-build. Every interpreter builds its own wheel (pyo3/extension-module, no abi3), matching upstream's own per-interpreter PyPI matrix, minus cp313t (the riscv64 manylinux image has no such interpreter at all). Tests run for cp310-cp314 (dnsmasq-backed, mirroring upstream's python-tests.yml minus the zone-transfer suite, which needs a BIND9 container upstream ships no riscv64 image for); cp39/cp314t get a wheel-content check instead, since pydantic-core (a transitive runtime dependency) has no riscv64 build for those interpreters in this registry.
luhenry
added a commit
that referenced
this pull request
Oct 14, 2026
Member
Author
|
Same mechanic as the other recent campaign PRs:
Generated by Claude Code |
luhenry
marked this pull request as draft
October 15, 2026 12:14
blastdns depends on orjson>=3.11.4 at runtime; PyPI has no riscv64 wheel for it, so --no-index --find-links dist alone can never satisfy that dependency and the install fails before any test runs. Give this step the same registry extra-index-url the test-dependencies step already uses for the identical reason, dropping --no-index so it can reach it; --find-links still makes dist/ win for blastdns itself, the only package that lives there.
Copying the test files out to $RUNNER_TEMP already avoided pytest's own rootdir-prepend shadowing, but `python3 -m pytest` separately prepends the current working directory to sys.path on its own. Invoked from the checkout root (still containing blastdns/__init__.py, with no compiled _native.so), that reintroduces the identical shadowing and the suite fails to even collect: "ImportError: cannot import name '_native' from partially initialized module 'blastdns'". Run pytest from inside $RUNNER_TEMP instead, where no blastdns/ package dir exists to shadow the installed wheel.
Fixes PR #3250's test failure: unpinned, UV_INDEX_STRATEGY=unsafe-best-match makes uv pick the single highest blastdns version available anywhere, and PyPI has since published 2.0.0/2.0.1. Neither has a riscv64 wheel, but both have a buildable sdist uv reaches for instead of dist/'s locally-built 1.9.1 wheel, with a renamed, incompatible ClientConfig (threads_per_resolver -> max_inflight_per_resolver, among others) that fails test_client.py's pinned-version-1.9.1 assertions. Pin the install to $BLASTDNS_VERSION so uv can only ever resolve the local wheel for the package actually built.
Fixes PR #3250's cp314t failure. The wheel itself builds and passes the wheel-content check; it is the install step that dies, source-building blastdns' runtime dependency orjson: "orjson v3.13.0 does not support free-threaded Python". That is orjson's own build.rs gate (it bails unless ORJSON_BUILD_FREETHREADED is set), and orjson has never published a free-threaded wheel for any platform across all of its releases, 3.13.0 being the newest. blastdns' __init__ imports orjson unconditionally, so the cp314t wheel can't be installed and imported anywhere, not just here. Upstream still ships cp314-cp314t blastdns wheels, so keep building the entry and stop at the wheel-content check instead of attempting an install that can't succeed. Also correct the matrix comment: pydantic-core does publish cp314t wheels upstream, so its free-threaded gap is only a missing riscv64 build on this registry, not the reason cp314t can't be installed.
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
blastdns1.9.1Compiles a pyo3/maturin extension wrapping a Rust async DNS resolver (hickory-proto/hickory-resolver). Upstream publishes no riscv64 wheel.
Mirrors upstream's
python-tests.yml/linux-buildjob.Differs from upstream
__init__, and orjson can't be installed under free-threaded Python on any architecture: none of its 151 PyPI releases (newest 3.13.0) ships a free-threaded wheel, and itsbuild.rsstops a source build with "orjson v3.13.0 does not support free-threaded Python" unlessORJSON_BUILD_FREETHREADEDis set (its README: "orjson may support PEP 703 free-threading when it is stable"). Upstream still publishescp314-cp314tblastdns wheels, so the entry stays and stops at the wheel-content check.Matrix: cp39, cp310-cp314, cp314t (no abi3; cp313t dropped per above).
Testing
_native*.soand LICENSE present), per the orjson gap above.License: Wheel ships no LICENSE and mislabels itself "GPL-3.0"; actual license is AGPL-3.0 (upstream fixed this in PR #130, unreleased). The patch backports that fix.
Patches
0001-backport-AGPL-3.0-license-metadata-and-LICENSE-file.patch- Backport [https://github.com/blacklanternsecurity/blastdns/commit/deca67dd384f2eebd628fe98ba048f49517975f5]. Without it the wheel ships no LICENSE file and the wrong license string. Reproduces off riscv64 too.Built on x86_64; 22 passed (mock/exceptions/batching subset).