Code Objects
ACodeObject is a built-in Python type representing compiled executable code, such as a function body or class definition.
Overview
Code objects contain:- Bytecode instructions - The executable code
- Associated metadata - Constants, names, variable info
- Context information - Source locations, exception table
Structure
Key Fields
ThePyCodeObject C struct is defined in Include/cpython/code.h.
Important fields:
co_code_adaptive- Bytecode array (since 3.11, wasco_codebytes object before)co_consts- Tuple of constants used (numbers, strings, etc.)co_names- Tuple of global/attribute namesco_varnames- Tuple of local variable namesco_cellvars- Tuple of cell variable names (for closures)co_freevars- Tuple of free variable names (from outer scopes)co_exceptiontable- Exception handling tableco_linetable- Source code location tableco_stacksize- Maximum stack depth neededco_firstlineno- First source line number
Bytecode Array
Since Python 3.11, bytecode is stored directly in the code object asco_code_adaptive:
- Saves an allocation (no separate bytes object)
- Allows mutation for specialization
- Enables inline caches
The array is declared with size
[1] but actually extends to the required length. This is a C flexible array member pattern.Creation and Initialization
Code objects are typically created by the compiler:- Compiler generates instruction sequence
_PyAssemble_MakeCodeObject()createsPyCodeObject(Python/assemble.c)_PyCode_Quicken()initializes inline caches (Python/specialize.c)
Quickening
Quickening initializes adaptive instruction caches:Immutability
Code objects are nominally immutable:- Most fields are read-only after creation
- Exceptions:
co_code_adaptive,_co_monitoring(runtime info) - Immutable fields are used for hashing and comparison
Sharing Code Objects
Code objects can be safely shared:- Between function objects
- Across threads
- When cached on disk (.pyc files)
co_code_adaptive) use appropriate synchronization.
Source Code Locations
Theco_linetable field maps bytecode offsets to source locations.
Why Source Locations Matter
When an exception occurs:- Interpreter adds traceback entry for current frame
tb_linenocomputed fromco_linetableviaPyCode_Addr2Line()- Full location (line, column, end line, end column) available
Location Table Format
The locations table is a compressed format storing 4-tuples:Accessing Locations
From Python:Locations Table Encoding
The locations table uses variable-length encoding to save space. See the format specification for details.
- Length (in code units)
- Start line delta
- End line delta
- Start column
- End column
| Code | Form | Use Case |
|---|---|---|
| 0-9 | Short form | Single line, column fits in byte |
| 10-12 | One line form | Single line, full column info |
| 13 | No column info | Line only |
| 14 | Long form | Multi-line, all details |
| 15 | No location | Synthetic instructions |
Variable-Length Integers
Locations table uses two integer encodings: Unsigned (varint):Serialization
Code objects are serialized using the marshal protocol..pyc Files
Compiled modules are cached as .pyc files:- Source code compiled to code object
- Code object marshalled to bytes
- Magic number + timestamp/hash + marshalled code written to .pyc
- On import, .pyc loaded and unmarshalled
Magic Number
The magic number identifies bytecode version:Lib/importlib/_bootstrap_external.pyPC/launcher.c(Windows launcher)
Code Object Methods
Python API
Replacement
Execution
Code objects are executed by the interpreter:Example: Examining Code Objects
Related Topics
- Compiler Design - How code objects are created
- Bytecode Interpreter - How code objects are executed
- Exception Handling - Exception table format
- Frames - Runtime execution context
