Everything after the header is one object in Python’s marshal format,
always the module’s code object. An object is one type byte followed by whatever that
type needs. Containers hold further objects, each with its own type byte. Every length
and number is little-endian. There is no index and no sharing: to find an object you
read everything before it.
Object types
Types are taken from CPython’s Python/marshal.c at the 1.5.2 and 2.0.1
tags. Python 1.6 has no final tag in CPython’s repository. The file layout of 1.6 is
taken to be the same; which release first wrote u is not confirmed here,
only that 2.0 writes it and 1.5.2 does not.
| Byte | Name | What follows | Releases |
|---|---|---|---|
0 | TYPE_NULL | Nothing. Marks the end of a dictionary | All |
N | TYPE_NONE | Nothing. The value None | All |
. | TYPE_ELLIPSIS | Nothing. The value Ellipsis | All |
i | TYPE_INT | A signed 32-bit integer | All |
I | TYPE_INT64 | A signed 64-bit integer. Written by a Python whose C long is more than 32 bits wide, for a value that needs more than 32 bits; on other machines the value is stored as i and cut to 32 bits | All |
l | TYPE_LONG | A signed 32-bit count of digits, negative for a negative number, then that many unsigned 16-bit digits in base 32768, lowest digit first. Used for Python’s long integers | All |
f | TYPE_FLOAT | One length byte, then the number written as ASCII text | All |
x | TYPE_COMPLEX | The real part as one length byte and ASCII text, then the imaginary part the same way | All |
s | TYPE_STRING | A signed 32-bit length, then that many bytes. Holds text, the bytecode itself and the line number table | All |
u | TYPE_UNICODE | A signed 32-bit length in bytes, then the text in UTF-8 | 2.0 |
( | TYPE_TUPLE | A signed 32-bit item count, then that many objects | All |
[ | TYPE_LIST | A signed 32-bit item count, then that many objects | All |
{ | TYPE_DICT | Key and value objects, in pairs, until a 0 byte where a key would be | All |
c | TYPE_CODE | The fields of a code object | All |
? is TYPE_UNKNOWN. CPython writes it for an object it
cannot marshal and reports an error, and no release reads it back as a value, so it
does not occur in a good file. The explorer treats it as an unknown type.
Bytes no release here writes
The explorer’s reader is shared by every Python version, so it accepts these type bytes in any file. Python 1.5, 1.6 and 2.0 neither write them nor read them; a file of these releases should not contain them. The layouts are those later Pythons use, in case a damaged or hand-made file does.
| Byte | Name | Meaning here |
|---|---|---|
F | TYPE_FALSE | The value False; nothing follows |
T | TYPE_TRUE | The value True; nothing follows |
S | TYPE_STOPITER | The StopIteration exception; nothing follows |
g | TYPE_BINARY_FLOAT | An 8-byte floating-point number |
y | TYPE_BINARY_COMPLEX | Two 8-byte floating-point numbers, real then imaginary |
t | TYPE_INTERNED | Laid out like s |
R | TYPE_STRINGREF | A 32-bit index into the list of t strings |
a | TYPE_ASCII | A 32-bit length, then the text |
A | TYPE_ASCII_INTERNED | Laid out like a |
z | TYPE_SHORT_ASCII | One length byte, then the text |
Z | TYPE_SHORT_ASCII_INTERNED | Laid out like z |
) | TYPE_SMALL_TUPLE | One count byte, then that many objects |
< | TYPE_SET | A 32-bit count, then that many objects |
> | TYPE_FROZENSET | A 32-bit count, then that many objects |
r | TYPE_REF | A 32-bit index of an earlier object that was saved |
: | TYPE_SLICE | Three objects: start, stop and step |