A code object is a marshal
object with the type byte c: one piece of compiled Python, a module, class
or function. The file’s body is the module’s code object, and each function or class
defined in it is another code object among its constants. List, dictionary and set
comprehensions have no code object of their own: Python 3.13 compiles them into the code
that contains them.
Fields
The fields are written in this order with no separators. An “i32” field is a little-endian 32-bit number with no type byte of its own; every other field is a marshal object.
| Field | Kind | Meaning |
|---|---|---|
co_argcount | i32 | How many positional parameters, positional-only ones included. |
co_posonlyargcount | i32 | How many of them are positional-only. |
co_kwonlyargcount | i32 | How many keyword-only parameters. |
co_stacksize | i32 | The most values the code needs on the stack at one time. |
co_flags | i32 | Facts about the code, as bits. |
co_code | bytes | The instructions. Inline cache entries are present and zero. |
co_consts | tuple | Constants used by the code, including nested code objects. In a function the first item is its docstring, or None if it has none. |
co_names | tuple of text | Names of globals, attributes and imported modules used by the code. |
co_localsplusnames | tuple of text | The names of all fast locals, cells and free variables, in slot order: arguments first, then other locals and cells, then free variables. Local-variable instructions index this list. |
co_localspluskinds | bytes | One byte per name in co_localsplusnames, saying what kind of variable it is. |
co_filename | text | The source file’s path as given to the compiler. |
co_name | text | The short name: f, or <module>. |
co_qualname | text | The qualified name, such as outer.<locals>.inner. |
co_firstlineno | i32 | The source line where this code begins. |
co_linetable | bytes | The source location of each instruction, in the location table format. |
co_exceptiontable | bytes | The exception table. Empty bytes if the code has no exception handlers. |
There are no co_nlocals, co_varnames,
co_cellvars or co_freevars fields in the file. Python rebuilds
them from the two localsplus fields when it loads the file.
co_flags
Each bit is named by Python’s inspect module with the prefix
CO_, or for a future feature in the __future__ module.
| Bit | Name | Meaning |
|---|---|---|
| 0x00000001 | OPTIMIZED | Uses fast locals. Set on functions |
| 0x00000002 | NEWLOCALS | A new local namespace is made for each call. Set on functions |
| 0x00000004 | VARARGS | Takes *args |
| 0x00000008 | VARKEYWORDS | Takes **kwargs |
| 0x00000010 | NESTED | A nested function |
| 0x00000020 | GENERATOR | A generator function |
| 0x00000040 | NOFREE | Not set. Python 3.13’s headers do not define this bit, though dis still names it |
| 0x00000080 | COROUTINE | A coroutine function |
| 0x00000100 | ITERABLE_COROUTINE | A generator that can be awaited (types.coroutine) |
| 0x00000200 | ASYNC_GENERATOR | An async generator function |
| 0x00020000 | FUTURE_DIVISION | division: see below |
| 0x00040000 | FUTURE_ABSOLUTE_IMPORT | absolute_import: see below |
| 0x00080000 | FUTURE_WITH_STATEMENT | with_statement: see below |
| 0x00100000 | FUTURE_PRINT_FUNCTION | print_function: see below |
| 0x00200000 | FUTURE_UNICODE_LITERALS | unicode_literals: see below |
| 0x00400000 | FUTURE_BARRY_AS_BDFL | from __future__ import barry_as_FLUFL |
| 0x00800000 | FUTURE_GENERATOR_STOP | generator_stop: see below |
| 0x01000000 | FUTURE_ANNOTATIONS | from __future__ import annotations |
| 0x02000000 | NO_MONITORING_EVENTS | Set by CPython only on code objects it builds for itself while running, so that sys.monitoring skips them. The compiler does not set it, so it is not found in a file |
Only barry_as_FLUFL and annotations set their bit when the
source imports them. The other __future__ features are already on in
Python 3, so the compiler accepts their import and sets nothing; their bits appear only
in code compiled by compile() with that flag passed explicitly, never in a
.pyc file written by the importer.
co_localspluskinds
Each byte describes the name at the same position in
co_localsplusnames. Python 3.13 uses four bits, which combine; the lower
bits are always clear.
| Bit | Meaning |
|---|---|
| 0x10 | Hidden: a variable of a comprehension compiled inline in a module or class body. The module’s or class’s code keeps it as a fast local, but it does not show in locals() |
| 0x20 | A fast local: a parameter or a local variable |
| 0x40 | A cell: a variable captured by an inner function. A captured parameter is also a fast local, so its byte is 60 |
| 0x80 | A free variable, supplied by an enclosing function |
Parameters come first, in the order co_argcount,
co_kwonlyargcount and the flags imply: positional ones, then keyword-only
ones, then *args, then **kwargs. Other locals follow, then
cells that are not parameters, then free variables.
For example, this function compiled under Python 3.13 has four names,
a b inner c, whose kinds are the bytes 60 20 20 40:
def outer(a, b):
c = 1
def inner():
return a + c
return inner
| Name | Byte | Meaning |
|---|---|---|
a | 60 | A parameter captured by inner: fast local and cell |
b | 20 | A parameter |
inner | 20 | A local variable |
c | 40 | A cell, captured by inner |
The nested function inner has two names, a and
c, whose kind bytes are 80 80, both free variables.
A module of one line, z = [y for y in range(3)], has one name in
co_localsplusnames, y, with the kind byte 30:
hidden and a fast local. Inside a function the same comprehension’s y is an
ordinary local, 20.
Worked example
Here is marshal.dumps(f) of a code object f, compiled under
Python 3.13 from this function in t.py, starting at line 1.
def f(a):
try:
return a + 1
except KeyError:
return 0
| Bytes | Field | Value |
|---|---|---|
E3 | Type c with FLAG_REF | Saved as #0 |
01 00 00 00 | co_argcount | 1 |
00 00 00 00 | co_posonlyargcount | 0 |
00 00 00 00 | co_kwonlyargcount | 0 |
04 00 00 00 | co_stacksize | 4 |
03 00 00 00 | co_flags | OPTIMIZED, NEWLOCALS |
F3 2E 00 00 00 … | co_code | 46 bytes, saved as #1 |
29 03 4E E9 01 00 00 00 E9 00 00 00 00 | co_consts | (None, 1, 0); the integers are saved as #2 and #3 |
29 01 DA 08 4B 65 79 45 72 72 6F 72 | co_names | ('KeyError',), saved as #4 |
29 01 DA 01 61 | co_localsplusnames | ('a',), saved as #5 |
73 01 00 00 00 20 | co_localspluskinds | 0x20: a fast local |
DA 04 74 2E 70 79 | co_filename | 't.py', interned, saved as #6 |
DA 01 66 | co_name | 'f', saved as #7 |
72 07 00 00 00 | co_qualname | Reference to #7, 'f' |
01 00 00 00 | co_firstlineno | 1 |
73 22 00 00 00 … | co_linetable | 34 bytes |
73 0C 00 00 00 … | co_exceptiontable | 12 bytes |
The same code’s location table and exception table are decoded on their own pages.