Files
rea/docs/python-packaged-applications.md
T
morluto 7fe5e5ff5e fix(artifacts): retain raw archive keys across entry projections
Publish Godot res:// declarations and PyInstaller CArchive/PYZ keys through
shared occurrence source_path while preserving safe logical extraction paths.
Consolidate PyInstaller file, directory and namespace projection through one
owner, and account for the additional retained source spelling before allocation.

Cover producer inventory, Windows separator conversion, PYZ module/data keys,
CLI extraction bytes and retained MCP inventory views. Format fixtures are
synthetic; real Godot/PyInstaller producer lanes were not run.
2026-10-25 03:30:22 +08:00

11 KiB

Python packaged applications

REA statically inventories PyInstaller executables with an appended CArchive. inspect_artifact and extract_artifact share the same reader through CLI and MCP. They read archive bytes without launching the application. Bytecode source decompilation, encrypted PYZ recovery, zipapp and PEX analysis are outside this capability.

extract_artifact.coverage preserves the inventory producer's source traversal scope and certainty. Successful publication proves that the selected inventoried regular files were written and verified; it does not prove that every source entry was representable or every embedded payload was decoded. For example, a directory containing an invalid UTF-8 filename can publish its representable files successfully while coverage remains unknown. Extraction retains the inventory's command provenance and limitations, plus the selected occurrences' path-qualified derivation notices. A reconstructed .pyc header therefore stays identified as derived bytes in the extraction result.

Facts and focused queries

The root occurrence's format_metadata records the CArchive layout (2.0 or 2.1), archive and cookie offsets, table extent, entry count, raw Python version, normalized major/minor when known, library name and encryption marker. Member metadata retains the original name, table index, type, compression flag, relative offset and known directory record extent. Logical paths follow the carrier's path dialect: backslashes separate components for PE carriers, while they remain literal filename characters for POSIX carriers. The source name always retains its stored spelling in occurrence source_path and format_metadata.source_name. For PYZ rows, that source is the exact module or data key in the PYZ table, not a reconstructed filesystem name; format_metadata.container_name identifies the containing PYZ image. If the carrier dialect is unconfirmed, REA preserves backslashes verbatim instead of inferring POSIX semantics. relative_offset is relative to the CArchive start for CArchive rows, or to the decoded PYZ image for PYZ rows. A CArchive directory record starts at archive_start + toc_offset + directory_record_offset; its size is directory_record_size. PYZ row directory extents remain unknown. CArchive type b retains PyInstaller's executable-member declaration in the generic executable fact; type x remains non-executable. This comes from the archive type code, not the filename or member contents. Distinct CArchive rows retain their table-index identities even when they share a logical path. Inventory can preserve both a file and a decoded PYZ directory at that path, including the PYZ children; extraction refuses a destination conflict instead of silently omitting those children.

Namespace packages remain metadata declarations at their projected query path; they do not claim a destination directory. Their relative_offset and compressed_size preserve any payload declared by older producers, while declared_size is zero because no bytecode is materialized for a namespace. Every declared span must end before the PYZ table of contents. Malformed CArchive TOC rows identify their zero-based table index and byte offset within the TOC, including truncated headers, invalid names, compression flags, and type codes. The failure retains its original format reason. PYZ compression_flag is derived from storage: nonempty payloads are compressed, including legacy namespaces; an empty namespace has no compressed payload