Skip to content

Download the macOS build that matches the running architecture - #450

Open
jim-daf wants to merge 2 commits into
JessicaTegner:masterfrom
jim-daf:fix/match-download-arch-on-apple-silicon
Open

jim-daf wants to merge 2 commits into
JessicaTegner:masterfrom
jim-daf:fix/match-download-arch-on-apple-silicon

Conversation

@jim-daf

@jim-daf jim-daf commented Sep 7, 2026

Copy link
Copy Markdown

The problem

The asset regex in _get_pandoc_urls puts x86 and mac outside the architecture branch, so they match whatever architecture was detected:

processor_architecture = (
    "arm" if uname.startswith("arm") or uname.startswith("aarch") else "amd"
)
regex = re.compile(
    rf"/jgm/pandoc/releases/download/.*"
    rf"(?:{processor_architecture}|x86|mac).*\.(?:msi|deb|pkg)"
)

On Apple Silicon both macOS packages match:

pandoc-3.7.0.2-arm64-macOS.pkg     matched via "arm"
pandoc-3.7.0.2-x86_64-macOS.pkg    matched via "x86", and also "mac"

The collect loop assigns pandoc_urls[ext2platform[ext]] on every match, so the later asset wins and download_pandoc() installs the Intel build on arm64 and aarch64.

Running the current matcher over a real release's asset list:

machine   platform  picked
x86_64    darwin    pandoc-3.7.0.2-x86_64-macOS.pkg
arm64     darwin    pandoc-3.7.0.2-x86_64-macOS.pkg   <-- wrong
aarch64   darwin    pandoc-3.7.0.2-x86_64-macOS.pkg   <-- wrong

Linux is unaffected, neither x86 nor mac appears in pandoc-*-arm64.deb, so it already picks correctly.

It runs under Rosetta, which is presumably why this has gone unnoticed, but it is the wrong binary and it fails outright where Rosetta is not installed. CI is affected too, since the workflow calls download_pandoc() directly and GitHub now offers ARM runners.

The change

Two lines. Move the alternatives inside the architecture branch so each only matches its own builds:

processor_architecture = (
    "arm|aarch" if uname.startswith("arm") or uname.startswith("aarch") else "amd|x86"
)
regex = re.compile(
    rf"/jgm/pandoc/releases/download/.*"
    rf"(?:{processor_architecture}).*\.(?:msi|deb|pkg)"
)

After, over the same asset list:

machine   platform  picked
x86_64    darwin    pandoc-3.7.0.2-x86_64-macOS.pkg
arm64     darwin    pandoc-3.7.0.2-arm64-macOS.pkg
aarch64   darwin    pandoc-3.7.0.2-arm64-macOS.pkg

Linux and Windows picks are unchanged on Intel hosts.

Two things worth checking in review

Windows still works. Its only installer is windows-x86_64.msi, matched by x86 on the Intel branch. Windows on ARM reports "ARM64" from platform.uname()[4], and the existing startswith checks are lowercase, so it takes the Intel branch and gets that msi which is the only one that exists.

An ARM Linux or macOS host no longer gets a win32 entry. download_pandoc never reads it: it looks up sys.platform only, and already guards with if pf not in pandoc_urls. _get_pandoc_urls is private, so nothing public depends on the map being complete for other platforms.

Tests

TestArchitectureSelection added to tests/test_pandoc_download.py, using the same MagicMock + patch style as the existing tests and a stubbed release payload, so it needs no network and no pandoc install.

without the fix:  2 failed, 3 passed      (arm64 and aarch64 mac fail)
with the fix:     16 passed, 2 subtests passed

jim-daf and others added 2 commits September 7, 2026 12:19
The asset regex accepted "x86" and "mac" whatever architecture was
detected, so on Apple Silicon both macOS packages matched:

  pandoc-3.7.0.2-arm64-macOS.pkg    matched via "arm"
  pandoc-3.7.0.2-x86_64-macOS.pkg   matched via "x86" and "mac"

The loop assigns pandoc_urls["darwin"] for every match, so the later
asset wins and download_pandoc() installed the Intel build on arm64 and
aarch64 machines.

Linux was unaffected, because neither "x86" nor "mac" appears in
pandoc-*-arm64.deb.

Move the alternatives into the architecture branch so each one only
matches its own builds: "amd|x86" for Intel, "arm|aarch" for ARM.

Windows keeps working. Its only installer is windows-x86_64.msi, and
Windows on ARM reports "ARM64" from platform.uname()[4], which does not
match the lowercase startswith checks and so takes the Intel branch.
An ARM Linux or macOS host no longer gets a win32 entry, which
download_pandoc never reads: it looks up sys.platform only, and guards
with "if pf not in pandoc_urls".
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