marshal
The Python marshal module implements a compact binary format for serializing a limited set of built-in Python objects. It was designed to support internal use cases, such as reading and writing the compiled code objects stored in .pyc files, rather than as a general-purpose persistence format.
Here’s a quick example:
>>> import marshal
>>> blob = marshal.dumps({"name": "Ada", "tags": ["math", "cs"]})
>>> marshal.loads(blob)
{'name': 'Ada', 'tags': ['math', 'cs']}
The format is versioned and specific to the running interpreter, so it is not guaranteed to be compatible between Python versions. For general object persistence, the standard library also provides the pickle module.
Note: The marshal module isn’t secure against maliciously crafted data. Loading untrusted input can trigger crashes or other unsafe behavior, especially when code objects are involved. Every load, loads, dump, and dumps function accepts allow_code=False to disable code object handling, and callers that need interoperability or stronger safety guarantees are advised to use pickle or a text format, such as json instead.
Key Features
- Serializes a small, fixed set of built-in types to a compact binary representation
- Handles
int,bool,float,complex,str,bytes,tuple,list,dict,set,frozenset, and singletons likeNoneandEllipsis - Supports Python code objects, which makes it suitable for
.pycfiles - Exposes both file-based (
dump,load) and in-memory (dumps,loads) interfaces - Provides an
allow_codekeyword on every function so callers can refuse to deserialize code objects - Tracks the format through
marshal.version, which is bumped when new features are added
Frequently Used Classes and Functions
| Object | Type | Description |
|---|---|---|
marshal.dump() |
Function | Writes a value to an open binary file |
marshal.load() |
Function | Reads one value from an open binary file |
marshal.dumps() |
Function | Serializes a value and returns the resulting bytes object |
marshal.loads() |
Function | Deserializes a value from a bytes object |
marshal.version |
Attribute | Reports the current format version understood by the module |
Examples
Round-tripping a value through the dumps() and loads() functions:
>>> import marshal
>>> blob = marshal.dumps((1, 2, 3, [4, 5]))
>>> marshal.loads(blob)
(1, 2, 3, [4, 5])
Writing and reading a serialized value with a binary file:
>>> import marshal
>>> from pathlib import Path
>>> path = Path("/tmp/snapshot.bin")
>>> with path.open("wb") as fp:
... marshal.dump({"status": "ok", "items": 42}, fp)
...
>>> with path.open("rb") as fp:
... marshal.load(fp)
...
{'status': 'ok', 'items': 42}
Attempting to serialize an unsupported object raises an exception:
>>> import marshal
>>> marshal.dumps(object())
Traceback (most recent call last):
...
ValueError: unmarshallable object
Checking the format version used by the current interpreter:
Python 3.14
>>> import marshal
>>> marshal.version
5
Common Use Cases
The most common tasks for marshal include:
- Reading and writing the compiled code stored inside
.pycfiles - Serializing code objects produced by the built-in
compile()function - Caching precomputed structures made of plain built-in types within a single program
- Implementing custom import hooks or loaders that need to emit bytecode to disk
- Interoperating with CPython internals that exchange data in
marshalformat
Real-World Example
Consider a helper that inspects a .pyc file and prints information about the top-level code object. Python writes these files using a fixed 16-byte header followed by a marshal-encoded code object, so marshal.load() is all that is needed to decode the payload:
>>> import marshal
>>> import py_compile
>>> from pathlib import Path
>>> source = Path("/tmp/demo_module.py")
>>> _ = source.write_text(
... "def greet(name):\n"
... " return f'Hello, {name}!'\n"
... )
>>> pyc = Path(py_compile.compile(str(source)))
>>> with pyc.open("rb") as fp:
... _ = fp.read(16)
... code = marshal.load(fp)
...
>>> code.co_name
'<module>'
>>> code.co_names
('greet',)
The returned value is a regular code object that exposes the same attributes, such as co_name and co_names, that the interpreter uses when it imports the original module. Tools like profilers, bytecode rewriters, and custom loaders rely on this round trip to examine or transform compiled Python before execution.
Related Resources
Tutorial
The Python pickle Module: How to Persist Objects in Python
In this tutorial, you'll learn how you can use the Python pickle module to convert your objects into a stream of bytes that can be saved to a disk or sent over a network. You'll also learn the security implications of using this process on objects from an untrusted source.
For additional information on related topics, take a look at the following resources:
- Serialize Your Data With Python (Tutorial)
- Working With JSON Data in Python (Tutorial)
- Python import: Advanced Techniques and Tips (Tutorial)
- Python Modules and Packages – An Introduction (Tutorial)
- Serializing Objects With the Python pickle Module (Course)
- Working With JSON in Python (Course)
- Working With JSON Data in Python (Quiz)
- Advanced Python import Techniques (Course)
- Python import: Advanced Techniques and Tips (Quiz)
- Python Modules and Packages: An Introduction (Course)
- Python Modules and Packages (Quiz)
By Leodanis Pozo Ramos • Updated May 5, 2026