Skip to content

pack_ipa: pack beside an earlier IPA on Windows - #15

Open
wagcbjr wants to merge 1 commit into
zenvyzenshiro:mainfrom
wagcbjr:fix/win-pack-ipa-pread
Open

wagcbjr wants to merge 1 commit into
zenvyzenshiro:mainfrom
wagcbjr:fix/win-pack-ipa-pread

Conversation

@wagcbjr

@wagcbjr wagcbjr commented Nov 13, 2026

Copy link
Copy Markdown

What and why

On Windows, a second build beside an earlier IPA stopped at the pack, in two places in turn:

  1. AttributeError: module 'os' has no attribute 'pread' in match(): pack_ipa.py compares and copies entries of the earlier IPA with os.pread, which Windows' Python does not have. pread() now uses os.pread where it exists and seek + read otherwise.
  2. Then PermissionError: [WinError 5] Access denied: '<ipa>.partial' -> '<ipa>': the earlier IPA was still open when os.replace put the new one in its place (load_index keeps it open for the reused entries), and Windows refuses to replace an open file. It is now closed once every entry is written, before the replace.

The first build only worked because there was no earlier IPA yet.

Checked

  • Tests: packing the same folder twice with os.pread removed and an os.replace that refuses an open destination (as on Windows) fails with each error before the change. After it, the pack writes a valid IPA (zipfile.testzip).
  • Games run, with title ID and version: Pokémon Legends: Z-A (0100F43008C44000) 2.0.2, split data build on Windows 11. The pack failed with error 1, then with error 2 after the first fix, and packed the 32 MB IPA after both. The IPA installed and ran on an iPhone (A18 Pro, iOS 27.2).
  • Not checked: macOS / Linux packs. On those, os.pread exists and the early close changes nothing, but no pack was run there.

Docs

  • No docs changed.
  • No game files, keys or data extracted from a game in the change or the attachments.

🤖 Generated with Claude Code

https://claude.ai/code/session_01VDGHF5LyEKSqoK23EvYr6W

A second build beside an earlier IPA stopped at the pack on Windows,
twice over:

- "AttributeError: module 'os' has no attribute 'pread'" in match():
  pack_ipa.py compares and copies entries of the earlier IPA with
  os.pread, which Windows' Python does not have. pread() now uses
  os.pread where it exists and seek + read otherwise.
- then "PermissionError: [WinError 5] Access denied: '<ipa>.partial'
  -> '<ipa>'": the earlier IPA was still open (load_index keeps it for
  the reused entries) when os.replace put the new one in its place, and
  Windows refuses to replace an open file. It is closed once every entry
  is written, before the replace.

The first build passed only because there was no earlier IPA.

Checked: packing the same folder twice with os.pread removed and an
os.replace that refuses an open destination (as on Windows) fails with
each error before the change and writes a valid IPA (zipfile testzip)
after it. Pokémon Legends: Z-A split build on Windows 11: the pack after
the first change failed with the second error, as described.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VDGHF5LyEKSqoK23EvYr6W
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