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.
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. A docstring, if there is one, is the first item, and the HAS_DOCSTRING flag is set. |
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 | Has no free or cell variables. dis still names it, but CPython 3.15 neither defines it in its C headers nor sets 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 | Defined in CPython’s C headers for code objects the interpreter makes for its own use. Not expected in a file |
| 0x04000000 | HAS_DOCSTRING | The first constant is the docstring |
| 0x08000000 | METHOD | A function defined in a class body |
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. Bits combine.
| Bit | Meaning |
|---|---|
| 0x02 | A positional argument. Also set with 0x08 on *args |
| 0x04 | A keyword argument. Also set with 0x08 on **kwargs |
| 0x08 | *args or **kwargs |
| 0x10 | Hidden: a variable of a comprehension that was inlined into the code around it |
| 0x20 | A plain local |
| 0x40 | A cell: a variable captured by an inner function. A captured parameter has this bit as well as 0x20 and its argument bits, so a positional-or-keyword one is 66 |
| 0x80 | A free variable, supplied by an enclosing function |
For example, this function has seven names. Worked out from the rules, their kinds are
the bytes 22 26 24 2A 2C 20 40:
def outer(a, /, b, *c, d=1, **e):
x = a
def inner():
return x
return inner
| Name | Byte | Bits | Meaning |
|---|---|---|---|
a | 22 | 0x20, 0x02 | Positional-only argument |
b | 26 | 0x20, 0x04, 0x02 | Positional or keyword argument |
d | 24 | 0x20, 0x04 | Keyword-only argument |
c | 2A | 0x20, 0x08, 0x02 | *c |
e | 2C | 0x20, 0x08, 0x04 | **e |
inner | 20 | 0x20 | A plain local |
x | 40 | 0x40 | A cell, captured by inner |
Keyword-only arguments come after the positional ones and before *args and
**kwargs. The nested function inner has one name,
x, whose kind byte is 80, a free variable.
Worked example
This code object was built by hand to show the layout, for the function below in
t.py, starting at line 1. Its instructions are RESUME with its
cache unit, LOAD_FAST_BORROW 0 and RETURN_VALUE. It is a valid
Python 3.15 code object, but there is no 3.15 interpreter here to compare it with, and
the compiler’s own output may differ in details such as co_consts.
def f(a):
return a
| 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 |
01 00 00 00 | co_stacksize | 1 |
03 00 00 00 | co_flags | OPTIMIZED, NEWLOCALS |
F3 08 00 00 00 80 00 00 00 55 00 21 00 | co_code | 8 bytes, saved as #1: RESUME 0 (128), its cache unit, LOAD_FAST_BORROW 0 (85), RETURN_VALUE (33) |
29 01 4E | co_consts | (None,) |
A9 00 | co_names | (), saved as #2 |
29 01 DA 01 61 | co_localsplusnames | ('a',); the name is saved as #3 |
73 01 00 00 00 26 | co_localspluskinds | 0x26: a plain local, positional or keyword |
DA 04 74 2E 70 79 | co_filename | 't.py', saved as #4 |
DA 01 66 | co_name | 'f', saved as #5 |
72 05 00 00 00 | co_qualname | Reference to #5, 'f' |
01 00 00 00 | co_firstlineno | 1 |
73 07 00 00 00 81 00 D8 0B 0C 80 48 | co_linetable | 7 bytes: line 1 for RESUME and its cache; line 2, columns 11–12 for a; columns 4–12 for the return |
F3 00 00 00 00 | co_exceptiontable | Empty, saved as #6 |
The line numbers page explains the location table’s entries, and the exception table page a table with handlers.