Skip to content

blastdns: Add version 1.9.1 - #3250

Draft
luhenry wants to merge 5 commits into
mainfrom
blastdns
Draft

luhenry wants to merge 5 commits into
mainfrom
blastdns

Conversation

@luhenry

@luhenry luhenry commented Oct 14, 2026 •

Copy link
Copy Markdown
Member

Compiles 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-build job.

Differs from upstream

  • No git tag exists for any release, so the checkout pins the release commit by SHA instead of a tag.
  • cp313t dropped - the riscv64 manylinux image has no such interpreter.
  • test_zone_transfer.py skipped - needs a BIND9 docker image upstream ships no riscv64 build of.
  • cp314t is built but never installed. blastdns imports orjson (a hard runtime dependency) from its __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 its build.rs stops a source build with "orjson v3.13.0 does not support free-threaded Python" unless ORJSON_BUILD_FREETHREADED is set (its README: "orjson may support PEP 703 free-threading when it is stable"). Upstream still publishes cp314-cp314t blastdns wheels, so the entry stays and stops at the wheel-content check.

Matrix: cp39, cp310-cp314, cp314t (no abi3; cp313t dropped per above).

Testing

  • dnsmasq-backed suite runs for cp310-cp314.
  • cp39 gets an import check instead, since pydantic-core (a runtime dependency) has no cp39 riscv64 build here yet.
  • cp314t gets only the wheel-content check (_native*.so and 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).

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

luhenry commented Oct 14, 2026

Copy link
Copy Markdown
Member Author

Same mechanic as the other recent campaign PRs: check_commit_messages (job 116107332608) failed on check_no_ai_attribution against the pull_request "opened" webhook's frozen body snapshot, captured before create_pull_request's auto-injected "Generated by Claude Code" footer was stripped via update_pull_request. The live PR body has been clean since right after creation.

pr-checks.yml already triggers on edited for exactly this case; that run should pass once it clears the backlog. No fix to push — watching for it.


Generated by Claude Code

@luhenry
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

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant