<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/"><channel><title>Code on Opensource internals</title><link>https://articles.9j.nz/tags/code/</link><description>Posts filed under Code on Opensource internals.</description><generator>Hugo</generator><language>en-US</language><managingEditor>Jay Hubbert</managingEditor><lastBuildDate>Tue, 20 Oct 2026 09:00:00 +0000</lastBuildDate><atom:link href="https://articles.9j.nz/tags/code/index.xml" rel="self" type="application/rss+xml"/><item><title>CPython's code Implementation in C: Where the Bytecode Actually Lives</title><link>https://articles.9j.nz/posts/how-cpython-code-is-implemented/</link><pubDate>Tue, 20 Oct 2026 09:00:00 +0000</pubDate><dc:creator>Jay Hubbert</dc:creator><guid isPermaLink="true">https://articles.9j.nz/posts/how-cpython-code-is-implemented/</guid><category>python</category><category>cpython</category><category>internals</category><category>code</category><description>PyCodeObject holds the bytecode, constants, names, unified localsplus layout, linetable, exception table and adaptive specialization — traced through CPython 3.15.</description><content:encoded>&lt;blockquote&gt;&#10;&lt;p&gt;&lt;strong&gt;TL;DR:&lt;/strong&gt; &lt;code&gt;types.CodeType&lt;/code&gt; is the compiled body of a function, class or module: bytecode, constants, names, variable layout, source locations and the exception handling table. The bytecode is specialized &lt;em&gt;in place&lt;/em&gt;, and &lt;code&gt;co_code&lt;/code&gt; is a lazy de-specialized view of it. Everything funnels through &lt;code&gt;_PyCode_New&lt;/code&gt; → &lt;code&gt;init_code&lt;/code&gt;.&lt;/p&gt;&#10;&lt;/blockquote&gt;&#10;&lt;p&gt;Python&amp;rsquo;s &lt;code&gt;code&lt;/code&gt; type (&lt;code&gt;types.CodeType&lt;/code&gt;) is the compiled representation of a function body, class body, or module.&lt;/p&gt;&#10;&lt;p&gt;It holds the bytecode, constants, names, variable layout, source locations and exception handling table. Functions bind one to globals and closure cells, but the code object itself is pure, shareable syntax.&lt;/p&gt;&#10;&lt;p&gt;In CPython that&amp;rsquo;s implemented by &lt;code&gt;PyCodeObject&lt;/code&gt; in &lt;code&gt;Objects/codeobject.c&lt;/code&gt;. This article traces the representation and the hot paths through the 3.15 source.&lt;/p&gt;&#10;&lt;h2 id="the-object-struct"&gt;The object struct&lt;/h2&gt;&#10;&lt;p&gt;&lt;code&gt;PyCodeObject&lt;/code&gt; is a variable-size object: the trailing &lt;code&gt;co_code_adaptive&lt;/code&gt; array holds the bytecode and is sized by &lt;code&gt;PyObject_NewVar(..., size)&lt;/code&gt; where &lt;code&gt;size&lt;/code&gt; is the number of &lt;code&gt;_Py_CODEUNIT&lt;/code&gt;s.&lt;/p&gt;&#10;&lt;p&gt;The struct is defined via the &lt;code&gt;_PyCode_DEF(SIZE)&lt;/code&gt; macro in &lt;code&gt;Include/cpython/code.h&lt;/code&gt;:&lt;/p&gt;&#10;&lt;div class="code-block"&gt;&#10; &lt;div class="code-block-head"&gt;&#10; &lt;span class="code-lang"&gt;c&lt;/span&gt;&#10; &lt;button class="code-copy" type="button" data-copy&gt;Copy&lt;/button&gt;&#10; &lt;/div&gt;&#10; &lt;div class="code-block-body"&gt;&#10; &lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-c" data-lang="c"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// Include/cpython/code.h&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;PyCodeObject&lt;/span&gt; &lt;span class="nf"&gt;_PyCode_DEF&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// expands to:&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;typedef&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;PyObject_VAR_HEAD&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;PyObject&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;co_consts&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="cm"&gt;/* tuple of constants used */&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;PyObject&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;co_names&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="cm"&gt;/* tuple of strings (names used) */&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;PyObject&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;co_exceptiontable&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="cm"&gt;/* bytes encoding exception handling */&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;co_flags&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="cm"&gt;/* CO_..., see below */&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;co_argcount&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="cm"&gt;/* #arguments, except *args */&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;co_posonlyargcount&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="cm"&gt;/* #positional only arguments */&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;co_kwonlyargcount&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="cm"&gt;/* #keyword only arguments */&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;co_stacksize&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="cm"&gt;/* #entries needed for eval stack */&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;co_firstlineno&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="cm"&gt;/* first source line number */&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;co_nlocalsplus&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="cm"&gt;/* locals + cell + free slots */&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;co_framesize&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="cm"&gt;/* size of frame in words */&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;co_nlocals&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="cm"&gt;/* number of local variables */&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;co_ncellvars&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="cm"&gt;/* total number of cell variables */&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;co_nfreevars&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="cm"&gt;/* number of free variables */&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kt"&gt;uint32_t&lt;/span&gt; &lt;span class="n"&gt;co_version&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="cm"&gt;/* version number */&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;PyObject&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;co_localsplusnames&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="cm"&gt;/* tuple mapping offsets to names */&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;PyObject&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;co_localspluskinds&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="cm"&gt;/* bytes: one kind byte per variable */&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;PyObject&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;co_filename&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="cm"&gt;/* unicode (where loaded from) */&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;PyObject&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;co_name&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="cm"&gt;/* unicode (name, for reference) */&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;PyObject&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;co_qualname&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="cm"&gt;/* unicode (qualname, for reference) */&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;PyObject&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;co_linetable&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="cm"&gt;/* bytes holding location info */&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;PyObject&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;co_weakreflist&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="cm"&gt;/* weak references to code objects */&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;_PyExecutorArray&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;co_executors&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="cm"&gt;/* executors from optimizer */&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;_PyCoCached&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;_co_cached&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="cm"&gt;/* cached co_* attributes */&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kt"&gt;uintptr_t&lt;/span&gt; &lt;span class="n"&gt;_co_instrumentation_version&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;_PyCoMonitoringData&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;_co_monitoring&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;Py_ssize_t&lt;/span&gt; &lt;span class="n"&gt;_co_unique_id&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="cm"&gt;/* id for per-thread refcounting */&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;_co_firsttraceable&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="cm"&gt;/* index of first traceable insn */&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;co_extra&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="cm"&gt;/* scratch space for extra data */&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nf"&gt;_PyCode_DEF_THREAD_LOCAL_BYTECODE&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="n"&gt;co_code_adaptive&lt;/span&gt;&lt;span class="p"&gt;[(&lt;/span&gt;&lt;span class="n"&gt;SIZE&lt;/span&gt;&lt;span class="p"&gt;)];&lt;/span&gt; &lt;span class="cm"&gt;/* adaptive bytecode */&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="n"&gt;PyCodeObject&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&#10; &lt;/div&gt;&#10;&lt;/div&gt;&#10;&lt;p&gt;The &amp;ldquo;locals plus&amp;rdquo; arrays unify what used to be three separate tuples (&lt;code&gt;co_varnames&lt;/code&gt;, &lt;code&gt;co_cellvars&lt;/code&gt;, &lt;code&gt;co_freevars&lt;/code&gt;).&lt;/p&gt;&#10;&lt;p&gt;&lt;code&gt;co_localsplusnames&lt;/code&gt; is a tuple of identifier strings and &lt;code&gt;co_localspluskinds&lt;/code&gt; is a parallel bytes object whose entries are bitmasks of &lt;code&gt;_PyLocals_Kind&lt;/code&gt;:&lt;/p&gt;&#10;&lt;div class="code-block"&gt;&#10; &lt;div class="code-block-head"&gt;&#10; &lt;span class="code-lang"&gt;c&lt;/span&gt;&#10; &lt;button class="code-copy" type="button" data-copy&gt;Copy&lt;/button&gt;&#10; &lt;/div&gt;&#10; &lt;div class="code-block-body"&gt;&#10; &lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-c" data-lang="c"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// Include/internal/pycore_code.h&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="cp"&gt;#define CO_FAST_LOCAL (0x20) &lt;/span&gt;&lt;span class="cm"&gt;/* local variable */&lt;/span&gt;&lt;span class="cp"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="cp"&gt;#define CO_FAST_CELL (0x40) &lt;/span&gt;&lt;span class="cm"&gt;/* escapes into a closure */&lt;/span&gt;&lt;span class="cp"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="cp"&gt;#define CO_FAST_FREE (0x80) &lt;/span&gt;&lt;span class="cm"&gt;/* captured from an outer scope */&lt;/span&gt;&lt;span class="cp"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="cp"&gt;#define CO_FAST_ARG (0x0E) &lt;/span&gt;&lt;span class="cm"&gt;/* argument (pos/kw/var) */&lt;/span&gt;&lt;span class="cp"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="cp"&gt;#define CO_FAST_HIDDEN (0x10) &lt;/span&gt;&lt;span class="cm"&gt;/* hidden (LOAD_FAST_AND_CLEAR) */&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&#10; &lt;/div&gt;&#10;&lt;/div&gt;&#10;&lt;p&gt;One array for all three kinds of variable, with the kind encoded as bits. That&amp;rsquo;s a nice bit of compression: the interpreter can ask &amp;ldquo;is slot 7 an argument or a local?&amp;rdquo; with a mask instead of a lookup.&lt;/p&gt;&#10;&lt;p&gt;The legacy names are still exposed lazily: &lt;code&gt;PyCode_GetVarnames&lt;/code&gt;, &lt;code&gt;PyCode_GetCellvars&lt;/code&gt;, and &lt;code&gt;PyCode_GetFreevars&lt;/code&gt; filter &lt;code&gt;co_localsplusnames&lt;/code&gt; by kind and cache the result in &lt;code&gt;_co_cached&lt;/code&gt;.&lt;/p&gt;&#10;&lt;h2 id="where-the-bytecode-lives"&gt;Where the bytecode lives&lt;/h2&gt;&#10;&lt;p&gt;The actual instructions live in &lt;code&gt;co_code_adaptive&lt;/code&gt;, accessed through &lt;code&gt;_PyCode_CODE(co)&lt;/code&gt; and sized by &lt;code&gt;Py_SIZE(co)&lt;/code&gt; code units.&lt;/p&gt;&#10;&lt;p&gt;&lt;code&gt;co_code&lt;/code&gt; (the Python-visible attribute) is a derived &lt;code&gt;bytes&lt;/code&gt; object rebuilt on demand by &lt;code&gt;_PyCode_GetCode&lt;/code&gt;, which de-specializes adaptive entries back into the original opcodes:&lt;/p&gt;&#10;&lt;div class="code-block"&gt;&#10; &lt;div class="code-block-head"&gt;&#10; &lt;span class="code-lang"&gt;c&lt;/span&gt;&#10; &lt;button class="code-copy" type="button" data-copy&gt;Copy&lt;/button&gt;&#10; &lt;/div&gt;&#10; &lt;div class="code-block-body"&gt;&#10; &lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-c" data-lang="c"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// Objects/codeobject.c (_PyCode_GetCode)&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;PyObject&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;code&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;FT_ATOMIC_LOAD_PTR&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cached&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;_co_code&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;code&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;Py_NewRef&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;code&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;...&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;code&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;PyBytes_FromStringAndSize&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nf"&gt;_PyCode_CODE&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;co&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nf"&gt;_PyCode_NBYTES&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;co&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nf"&gt;deopt_code&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;co&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_Py_CODEUNIT&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nf"&gt;PyBytes_AS_STRING&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;code&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nf"&gt;FT_ATOMIC_STORE_PTR&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cached&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;_co_code&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;code&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&#10; &lt;/div&gt;&#10;&lt;/div&gt;&#10;&lt;p&gt;&lt;code&gt;_PyCode_Quicken&lt;/code&gt; (called in &lt;code&gt;init_code&lt;/code&gt;) specializes the raw bytecode into adaptive forms and inserts cache slots, so the eval loop can specialize at runtime.&lt;/p&gt;&#10;&lt;p&gt;&lt;code&gt;co_executors&lt;/code&gt; holds Tier-2 (uop) executors produced by the optimizer, and &lt;code&gt;co_tlbc&lt;/code&gt; (free-threaded builds only) holds per-thread specialized copies.&lt;/p&gt;&#10;&lt;p&gt;&lt;strong&gt;This is the part people get wrong:&lt;/strong&gt; there is one copy of the bytecode, and it mutates. The &amp;ldquo;original&amp;rdquo; opcodes you see in &lt;code&gt;dis&lt;/code&gt; output are reconstructed on demand.&lt;/p&gt;&#10;&lt;h2 id="cached-derived-views-and-monitoring"&gt;Cached derived views and monitoring&lt;/h2&gt;&#10;&lt;p&gt;Several attributes are derived and cached lazily in &lt;code&gt;_co_cached&lt;/code&gt; (&lt;code&gt;_PyCoCached&lt;/code&gt;): &lt;code&gt;_co_code&lt;/code&gt; (the de-specialized bytes), &lt;code&gt;_co_varnames&lt;/code&gt;, &lt;code&gt;_co_cellvars&lt;/code&gt;, and &lt;code&gt;_co_freevars&lt;/code&gt;.&lt;/p&gt;&#10;&lt;p&gt;&lt;code&gt;init_co_cached&lt;/code&gt; allocates this structure on first use, and access is guarded by a critical section plus atomic loads so it&amp;rsquo;s safe under free-threading. Weak references are supported via &lt;code&gt;co_weakreflist&lt;/code&gt;.&lt;/p&gt;&#10;&lt;p&gt;Code objects also carry &lt;code&gt;_co_monitoring&lt;/code&gt; (per-tool/per-instruction monitoring data), &lt;code&gt;_co_instrumentation_version&lt;/code&gt;, and &lt;code&gt;co_executors&lt;/code&gt; for Tier 2.&lt;/p&gt;&#10;&lt;p&gt;Lifecycle watchers registered with &lt;code&gt;PyCode_AddWatcher&lt;/code&gt; receive &lt;code&gt;PY_CODE_EVENT_CREATE&lt;/code&gt; (fired at the end of &lt;code&gt;init_code&lt;/code&gt;) and &lt;code&gt;PY_CODE_EVENT_DESTROY&lt;/code&gt; (fired in &lt;code&gt;code_dealloc&lt;/code&gt; before teardown).&lt;/p&gt;&#10;&lt;p&gt;&lt;code&gt;co_extra&lt;/code&gt; provides indexed scratch slots whose free functions are registered per interpreter.&lt;/p&gt;&#10;&lt;h2 id="frame-size"&gt;Frame size&lt;/h2&gt;&#10;&lt;p&gt;&lt;code&gt;co_framesize&lt;/code&gt; is &lt;code&gt;co_nlocalsplus + co_stacksize + FRAME_SPECIALS_SIZE&lt;/code&gt; (computed in &lt;code&gt;init_code&lt;/code&gt;), giving the frame&amp;rsquo;s total word size.&lt;/p&gt;&#10;&lt;p&gt;The eval loop allocates a frame of this size, with localsplus slots first, then the evaluation stack, then special cells (return value, exception state, and so on). &lt;code&gt;co_stacksize&lt;/code&gt; is an upper bound on operand-stack depth produced by the compiler.&lt;/p&gt;&#10;&lt;h2 id="consts-names-and-flags"&gt;consts, names, and flags&lt;/h2&gt;&#10;&lt;p&gt;&lt;code&gt;co_consts&lt;/code&gt; is a tuple: literals, nested code objects, and, when &lt;code&gt;CO_HAS_DOCSTRING&lt;/code&gt; is set, the docstring as element 0.&lt;/p&gt;&#10;&lt;p&gt;&lt;code&gt;co_names&lt;/code&gt; is a tuple of strings used by &lt;code&gt;LOAD_GLOBAL&lt;/code&gt;, &lt;code&gt;LOAD_ATTR&lt;/code&gt;, and friends.&lt;/p&gt;&#10;&lt;p&gt;Constants and names are interned at construction time (&lt;code&gt;intern_code_constants&lt;/code&gt;) so identity comparisons work in the eval loop.&lt;/p&gt;&#10;&lt;p&gt;&lt;code&gt;co_flags&lt;/code&gt; combines function-kind flags (&lt;code&gt;CO_OPTIMIZED&lt;/code&gt;, &lt;code&gt;CO_NEWLOCALS&lt;/code&gt;, &lt;code&gt;CO_VARARGS&lt;/code&gt;, &lt;code&gt;CO_VARKEYWORDS&lt;/code&gt;, &lt;code&gt;CO_NESTED&lt;/code&gt;, &lt;code&gt;CO_GENERATOR&lt;/code&gt;, &lt;code&gt;CO_COROUTINE&lt;/code&gt;, &lt;code&gt;CO_ASYNC_GENERATOR&lt;/code&gt;) with compiler future flags and runtime hints such as &lt;code&gt;CO_HAS_DOCSTRING&lt;/code&gt; and &lt;code&gt;CO_METHOD&lt;/code&gt;.&lt;/p&gt;&#10;&lt;h2 id="cell-and-free-variables"&gt;Cell and free variables&lt;/h2&gt;&#10;&lt;p&gt;There&amp;rsquo;s no separate &lt;code&gt;co_cellvars&lt;/code&gt;/&lt;code&gt;co_freevars&lt;/code&gt; storage anymore; they&amp;rsquo;re derived views over &lt;code&gt;co_localsplus&lt;/code&gt;.&lt;/p&gt;&#10;&lt;p&gt;A local that escapes into an inner function gets &lt;code&gt;CO_FAST_CELL&lt;/code&gt; ORed into its kind (and may also be &lt;code&gt;CO_FAST_LOCAL&lt;/code&gt; when it&amp;rsquo;s both a local and a cell — a parameter captured by a closure, for example). A variable from an enclosing scope is &lt;code&gt;CO_FAST_FREE&lt;/code&gt;.&lt;/p&gt;&#10;&lt;p&gt;The counts &lt;code&gt;co_ncellvars&lt;/code&gt; and &lt;code&gt;co_nfreevars&lt;/code&gt; are computed by &lt;code&gt;get_localsplus_counts&lt;/code&gt; during validation.&lt;/p&gt;&#10;&lt;p&gt;At runtime, free variables are carried by &lt;code&gt;PyCellObject&lt;/code&gt; boxes (see &lt;code&gt;Include/cpython/cellobject.h&lt;/code&gt;); &lt;code&gt;co_nfreevars&lt;/code&gt; tells the frame how many cell slots to copy from the function&amp;rsquo;s closure tuple.&lt;/p&gt;&#10;&lt;h2 id="the-linetable"&gt;The linetable&lt;/h2&gt;&#10;&lt;p&gt;&lt;code&gt;co_linetable&lt;/code&gt; is a compact bytes object mapping bytecode offsets to source locations.&lt;/p&gt;&#10;&lt;p&gt;Rather than one entry per instruction, it uses a variable-length encoding of &amp;ldquo;entries&amp;rdquo; keyed by &lt;code&gt;_PyCodeLocationInfoKind&lt;/code&gt;:&lt;/p&gt;&#10;&lt;div class="code-block"&gt;&#10; &lt;div class="code-block-head"&gt;&#10; &lt;span class="code-lang"&gt;c&lt;/span&gt;&#10; &lt;button class="code-copy" type="button" data-copy&gt;Copy&lt;/button&gt;&#10; &lt;/div&gt;&#10; &lt;div class="code-block-body"&gt;&#10; &lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-c" data-lang="c"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// Include/cpython/code.h&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;typedef&lt;/span&gt; &lt;span class="k"&gt;enum&lt;/span&gt; &lt;span class="n"&gt;_PyCodeLocationInfoKind&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;PY_CODE_LOCATION_INFO_SHORT0&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="cm"&gt;/* short forms 0..9 */&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;PY_CODE_LOCATION_INFO_ONE_LINE0&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;PY_CODE_LOCATION_INFO_ONE_LINE1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;11&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;PY_CODE_LOCATION_INFO_ONE_LINE2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;12&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;PY_CODE_LOCATION_INFO_NO_COLUMNS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;13&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;PY_CODE_LOCATION_INFO_LONG&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;14&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;PY_CODE_LOCATION_INFO_NONE&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;15&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="n"&gt;_PyCodeLocationInfoKind&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&#10; &lt;/div&gt;&#10;&lt;/div&gt;&#10;&lt;p&gt;&lt;code&gt;PyCode_Addr2Line&lt;/code&gt; and &lt;code&gt;PyCode_Addr2Location&lt;/code&gt; walk this table.&lt;/p&gt;&#10;&lt;p&gt;When &lt;code&gt;sys.flags&lt;/code&gt;/config disables debug ranges, &lt;code&gt;remove_column_info&lt;/code&gt; rewrites entries to the &lt;code&gt;NO_COLUMNS&lt;/code&gt; form at construction time, shrinking the table.&lt;/p&gt;&#10;&lt;p&gt;The first traceable instruction index (&lt;code&gt;_co_firsttraceable&lt;/code&gt;) is computed by scanning for the first &lt;code&gt;RESUME&lt;/code&gt;, so tracers skip module-level setup.&lt;/p&gt;&#10;&lt;h2 id="the-exception-table"&gt;The exception table&lt;/h2&gt;&#10;&lt;p&gt;&lt;code&gt;co_exceptiontable&lt;/code&gt; is a bytes object encoding the exception handling ranges as a sequence of varints.&lt;/p&gt;&#10;&lt;p&gt;For each &lt;code&gt;try&lt;/code&gt; block: a start offset, a length (end = start + length), a handler target offset, and a packed &amp;ldquo;depth/lasti&amp;rdquo; word whose high bits give the stack depth to restore and whose low bit records whether to push the current instruction index.&lt;/p&gt;&#10;&lt;p&gt;All offsets are in code units (times two for byte offsets). &lt;code&gt;_parse_exception_table&lt;/code&gt; in &lt;code&gt;Lib/dis.py&lt;/code&gt; decodes it:&lt;/p&gt;&#10;&lt;div class="code-block"&gt;&#10; &lt;div class="code-block-head"&gt;&#10; &lt;span class="code-lang"&gt;python&lt;/span&gt;&#10; &lt;button class="code-copy" type="button" data-copy&gt;Copy&lt;/button&gt;&#10; &lt;/div&gt;&#10; &lt;div class="code-block-body"&gt;&#10; &lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Lib/dis.py&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;start&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;_parse_varint&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;iterator&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;length&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;_parse_varint&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;iterator&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;end&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;start&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;length&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;target&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;_parse_varint&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;iterator&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;dl&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;_parse_varint&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;iterator&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;depth&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;dl&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;lasti&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;bool&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dl&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&#10; &lt;/div&gt;&#10;&lt;/div&gt;&#10;&lt;p&gt;The eval loop consults this table when an exception propagates, replacing the old block-stack mechanism.&lt;/p&gt;&#10;&lt;p&gt;An empty module-level code object uses the immortal empty bytes singleton.&lt;/p&gt;&#10;&lt;h2 id="creating-a-code-object"&gt;Creating a code object&lt;/h2&gt;&#10;&lt;p&gt;All construction goes through &lt;code&gt;_PyCode_New&lt;/code&gt;, which takes a &lt;code&gt;_PyCodeConstructor&lt;/code&gt;:&lt;/p&gt;&#10;&lt;div class="code-block"&gt;&#10; &lt;div class="code-block-head"&gt;&#10; &lt;span class="code-lang"&gt;c&lt;/span&gt;&#10; &lt;button class="code-copy" type="button" data-copy&gt;Copy&lt;/button&gt;&#10; &lt;/div&gt;&#10; &lt;div class="code-block-body"&gt;&#10; &lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-c" data-lang="c"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// Objects/codeobject.c&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;PyCodeObject&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nf"&gt;_PyCode_New&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;_PyCodeConstructor&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;con&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;{&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;intern_code_constants&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;con&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;// Compact linetable if debug ranges are disabled.&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nf"&gt;_Py_GetConfig&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;code_debug_ranges&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;replacement_locations&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;remove_column_info&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;con&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;linetable&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;con&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;linetable&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;replacement_locations&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;Py_ssize_t&lt;/span&gt; &lt;span class="n"&gt;size&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;PyBytes_GET_SIZE&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;con&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;code&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="k"&gt;sizeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_Py_CODEUNIT&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;PyCodeObject&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;co&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;PyObject_NewVar&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;PyCodeObject&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;PyCode_Type&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;co&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;init_code&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;co&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;con&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nf"&gt;Py_DECREF&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;co&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;co&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&#10; &lt;/div&gt;&#10;&lt;/div&gt;&#10;&lt;p&gt;&lt;code&gt;init_code&lt;/code&gt; fills every field, derives &lt;code&gt;co_nlocals&lt;/code&gt;/&lt;code&gt;co_ncellvars&lt;/code&gt;/&lt;code&gt;co_nfreevars&lt;/code&gt;/&lt;code&gt;co_framesize&lt;/code&gt;, assigns a fresh &lt;code&gt;co_version&lt;/code&gt; from the interpreter&amp;rsquo;s &lt;code&gt;func_state.next_version&lt;/code&gt;, copies the bytecode into &lt;code&gt;co_code_adaptive&lt;/code&gt;, and calls &lt;code&gt;_PyCode_Quicken&lt;/code&gt; to specialize it. It also fires code watchers (&lt;code&gt;PY_CODE_EVENT_CREATE&lt;/code&gt;).&lt;/p&gt;&#10;&lt;p&gt;Before allocation, &lt;code&gt;_PyCode_Validate&lt;/code&gt; checks argument types and ranges: code must be bytes aligned to &lt;code&gt;_Py_CODEUNIT&lt;/code&gt;, consts/names/localsplusnames must be tuples, localspluskinds bytes of matching length, filename/name/qualname unicode, linetable/exceptiontable bytes, and enough locals to cover arg counts.&lt;/p&gt;&#10;&lt;p&gt;&lt;code&gt;co_version&lt;/code&gt; is taken from &lt;code&gt;interp-&amp;gt;func_state.next_version&lt;/code&gt; under the func_state mutex, so each code object gets a unique version used by function specialization guards.&lt;/p&gt;&#10;&lt;p&gt;The public entry point &lt;code&gt;PyUnstable_Code_NewWithPosOnlyArgs&lt;/code&gt; still accepts the legacy separate &lt;code&gt;varnames&lt;/code&gt;/&lt;code&gt;cellvars&lt;/code&gt;/&lt;code&gt;freevars&lt;/code&gt; tuples and assembles them into the unified localsplus arrays, merging a cell that is also a local:&lt;/p&gt;&#10;&lt;div class="code-block"&gt;&#10; &lt;div class="code-block-head"&gt;&#10; &lt;span class="code-lang"&gt;c&lt;/span&gt;&#10; &lt;button class="code-copy" type="button" data-copy&gt;Copy&lt;/button&gt;&#10; &lt;/div&gt;&#10; &lt;div class="code-block-body"&gt;&#10; &lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-c" data-lang="c"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// Objects/codeobject.c (PyUnstable_Code_NewWithPosOnlyArgs)&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="n"&gt;in&lt;/span&gt; &lt;span class="n"&gt;cellvars&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;// if the cell name is already a local, OR CO_FAST_CELL into&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;// that local&amp;#39;s kind instead of adding a new slot&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;argoffset&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nf"&gt;_PyLocals_SetKind&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;localspluskinds&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;argoffset&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;kind&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;CO_FAST_CELL&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;continue&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nf"&gt;_Py_set_localsplus_info&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;offset&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;CO_FAST_CELL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;...);&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&#10; &lt;/div&gt;&#10;&lt;/div&gt;&#10;&lt;p&gt;&lt;code&gt;PyCode_NewEmpty&lt;/code&gt; builds a minimal code object whose bytecode is a single &lt;code&gt;RESUME&lt;/code&gt; followed by &lt;code&gt;LOAD_COMMON_CONSTANT&lt;/code&gt;/&lt;code&gt;RAISE_VARARGS&lt;/code&gt; (so calling it raises &lt;code&gt;AssertionError&lt;/code&gt;), useful for stubs and tracebacks. &lt;code&gt;code.__new__&lt;/code&gt; (&lt;code&gt;code_new_impl&lt;/code&gt;) validates inputs and delegates to &lt;code&gt;PyCode_NewWithPosOnlyArgs&lt;/code&gt;.&lt;/p&gt;&#10;&lt;p&gt;Dealloc (&lt;code&gt;code_dealloc&lt;/code&gt;) clears executors, decrements all owned objects (consts, names, localsplus arrays, filename, name, qualname, linetable, exceptiontable, cached views), frees monitoring data and (free-threaded) thread-local bytecode copies, and fires &lt;code&gt;PY_CODE_EVENT_DESTROY&lt;/code&gt;.&lt;/p&gt;&#10;&lt;h2 id="hashing-and-equality"&gt;Hashing and equality&lt;/h2&gt;&#10;&lt;p&gt;&lt;code&gt;code_richcompare&lt;/code&gt; compares &lt;code&gt;co_name&lt;/code&gt;, the arg counts, &lt;code&gt;co_flags&lt;/code&gt;, &lt;code&gt;co_firstlineno&lt;/code&gt;, the bytecode (size and code units, cache slots included), consts (via &lt;code&gt;_PyCode_ConstantKey&lt;/code&gt;), &lt;code&gt;co_names&lt;/code&gt;, &lt;code&gt;co_localsplusnames&lt;/code&gt;, &lt;code&gt;co_linetable&lt;/code&gt;, and &lt;code&gt;co_exceptiontable&lt;/code&gt;.&lt;/p&gt;&#10;&lt;p&gt;It deliberately skips &lt;code&gt;co_filename&lt;/code&gt;, &lt;code&gt;co_qualname&lt;/code&gt;, &lt;code&gt;co_stacksize&lt;/code&gt;, and &lt;code&gt;co_version&lt;/code&gt;, so code objects from different files or with different stack sizes can still be equal when their executable content matches.&lt;/p&gt;&#10;&lt;p&gt;&lt;code&gt;code_hash&lt;/code&gt; mirrors these fields (plus &lt;code&gt;Py_SIZE&lt;/code&gt;) using a fixed seed of &lt;code&gt;20221211&lt;/code&gt;.&lt;/p&gt;&#10;&lt;h2 id="key-takeaways"&gt;Key takeaways&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;A code object is &lt;code&gt;PyCodeObject&lt;/code&gt;: a &lt;code&gt;PyObject_VAR_HEAD&lt;/code&gt; plus fields for consts, names, exception table, flags, arg counts, stack size, first line number, localsplus counts, version, localsplus names/kinds, filename/name/qualname, linetable, executors, cached views, monitoring data, and adaptive bytecode in the trailing array.&lt;/li&gt;&#10;&lt;li&gt;Bytecode is specialized in place (&lt;code&gt;co_code_adaptive&lt;/code&gt;); &lt;code&gt;co_code&lt;/code&gt; is a lazy, de-specialized bytes view.&lt;/li&gt;&#10;&lt;li&gt;Variable layout is unified into &lt;code&gt;co_localsplusnames&lt;/code&gt;/&lt;code&gt;co_localspluskinds&lt;/code&gt;; varnames/cellvars/freevars are filtered views.&lt;/li&gt;&#10;&lt;li&gt;Constants and names are interned; &lt;code&gt;co_version&lt;/code&gt; drives function specialization.&lt;/li&gt;&#10;&lt;li&gt;Linetable and exception table are compact bytes encodings consulted by the eval loop and debuggers.&lt;/li&gt;&#10;&lt;li&gt;Creation funnels through &lt;code&gt;_PyCode_New&lt;/code&gt; -&amp;gt; &lt;code&gt;init_code&lt;/code&gt;, which validates, interns, derives counts, assigns a version, copies bytecode, and quickens it.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;p&gt;&lt;strong&gt;The one thing to remember:&lt;/strong&gt; a code object is the &lt;em&gt;executable content&lt;/em&gt; of a function, stripped of everything contextual. That&amp;rsquo;s why two functions with the same body can share one code object — and why &lt;code&gt;co_filename&lt;/code&gt; is deliberately excluded from equality.&lt;/p&gt;&#10;&lt;h2 id="further-reading"&gt;Further reading&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;code&gt;Objects/codeobject.c&lt;/code&gt; &amp;ndash; all of the above.&lt;/li&gt;&#10;&lt;li&gt;&lt;code&gt;Include/cpython/code.h&lt;/code&gt; &amp;ndash; &lt;code&gt;PyCodeObject&lt;/code&gt; and public API.&lt;/li&gt;&#10;&lt;li&gt;&lt;code&gt;Include/internal/pycore_code.h&lt;/code&gt; &amp;ndash; &lt;code&gt;_PyLocals_Kind&lt;/code&gt; and constructor.&lt;/li&gt;&#10;&lt;li&gt;&lt;code&gt;Python/ceval.c&lt;/code&gt; &amp;ndash; eval loop consumption of bytecode/exception table.&lt;/li&gt;&#10;&lt;li&gt;&lt;code&gt;Python/compile.c&lt;/code&gt; &amp;ndash; producer of &lt;code&gt;_PyCodeConstructor&lt;/code&gt;.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;</content:encoded></item></channel></rss>