# 24. Constants, Names, and Locals

# 24. Constants, Names, and Locals

A code object does not store Python source code as text. It stores compact tables and bytecode instructions that refer to those tables by index.

Three of the most important tables are:

```text id="mx2a9w"
co_consts
co_names
co_varnames
```

They separate repeated data from the instruction stream.

For this function:

```python id="wg80pj"
def f(a):
    b = len(a)
    return b + 1
```

CPython stores:

```text id="jxh1ou"
constants:
    None
    1

names:
    len

local variables:
    a
    b
```

The bytecode instructions then refer to those entries by index.

## 24.1 Position in the Compilation Pipeline

Constants, names, and locals are assembled during compilation.

```text id="la84x8"
AST
    ↓
symbol table
    ↓
compiler
    ↓
instruction stream
    ↓
constant table
    ↓
name table
    ↓
local variable table
    ↓
code object
```

These tables are part of the code object.

The interpreter uses them when executing bytecode.

```text id="gvqxes"
LOAD_CONST 1
LOAD_GLOBAL 0
LOAD_FAST 0
STORE_FAST 1
```

Each numeric operand indexes into one of the code object’s tables.

## 24.2 Why Code Objects Use Tables

Bytecode needs to be compact.

Instead of embedding full Python objects or strings directly inside each instruction, CPython stores them once in a table.

Example:

```python id="y6ymck"
def f():
    print("hello")
    print("hello")
```

The string `"hello"` can appear once in `co_consts`.

The name `"print"` can appear once in `co_names`.

The bytecode references them by index.

Conceptually:

```text id="y1yh5e"
co_consts:
    0: None
    1: "hello"

co_names:
    0: "print"

bytecode:
    LOAD_GLOBAL 0       print
    LOAD_CONST 1        "hello"
    CALL
    POP_TOP

    LOAD_GLOBAL 0       print
    LOAD_CONST 1        "hello"
    CALL
    POP_TOP
```

This reduces duplication and gives the interpreter stable lookup positions.

## 24.3 Constants

Constants are literal values and compiled artifacts stored in `co_consts`.

Common constants include:

```text id="0sqmi6"
None
True
False
integers
floats
complex numbers
strings
bytes
tuples of constants
frozensets of constants
nested code objects
```

Example:

```python id="0bigls"
def f():
    return 123, "abc", None
```

Inspect:

```python id="unotfl"
print(f.__code__.co_consts)
```

Typical shape:

```text id="zsqktw"
(None, 123, 'abc')
```

The tuple returned by the function may itself be constructed from constants, or it may be stored as a constant tuple if the compiler can safely fold it.

## 24.4 The `None` Constant

Most code objects include `None` in `co_consts`.

Example:

```python id="mxsc3g"
def f():
    x = 1
```

Even though the source has no explicit `return None`, the function returns `None` implicitly.

The compiler must be able to emit:

```text id="b7i1tf"
LOAD_CONST None
RETURN_VALUE
```

At module level, CPython also often emits a final `RETURN_VALUE` with `None` to finish execution.

## 24.5 Numeric Constants

Numeric literals usually appear in `co_consts`.

Example:

```python id="y88hr2"
def f():
    return 10 + 20
```

The AST may contain `10 + 20`, but the compiler may fold this into `30`.

Inspect:

```python id="y7a6vi"
import dis

def f():
    return 10 + 20

print(f.__code__.co_consts)
dis.dis(f)
```

You may see only `30` as a loaded constant.

Constant folding is conservative. CPython can fold expressions that are safe and deterministic at compile time. It cannot fold expressions with runtime effects.

Example:

```python id="3nempa"
def f():
    return 10 + x
```

`x` is not known at compile time, so this cannot become a constant.

## 24.6 String and Bytes Constants

String and bytes literals appear in `co_consts`.

Example:

```python id="086py8"
def f():
    return "hello", b"world"
```

Inspect:

```python id="mwit9a"
print(f.__code__.co_consts)
```

Adjacent string literals may be concatenated during compilation:

```python id="yn2nfn"
def f():
    return "hello" "world"
```

This is a compile-time operation. It does not call string addition at runtime.

The result is one constant:

```text id="g8bxm7"
"helloworld"
```

## 24.7 Tuple Constants

Tuples containing only constants can be stored as constants.

Example:

```python id="u33byh"
def f():
    return (1, 2, 3)
```

The compiler may store the entire tuple:

```text id="kw4dlg"
(1, 2, 3)
```

in `co_consts`.

But if an element is dynamic:

```python id="f0psq9"
def f(x):
    return (1, x, 3)
```

the tuple must be built at runtime.

Compilation pattern:

```text id="0f7svq"
LOAD_CONST 1
LOAD_FAST x
LOAD_CONST 3
BUILD_TUPLE 3
```

The compiler distinguishes immutable constant containers from runtime-built containers.

## 24.8 Frozen Set Constants

Set literals are mutable, so a set itself cannot be a constant in bytecode.

But CPython may use `frozenset` constants for optimized membership tests.

Example:

```python id="a4bjga"
def is_small(x):
    return x in {1, 2, 3}
```

The source uses a set literal. The compiler may compile membership against a `frozenset` constant because the set is used only for membership testing.

Conceptually:

```text id="y0dtbp"
LOAD_FAST x
LOAD_CONST frozenset({1, 2, 3})
CONTAINS_OP
```

This avoids rebuilding the set each time the function runs.

The compiler must preserve semantics. This optimization is valid for constants because membership in `{1, 2, 3}` and `frozenset({1, 2, 3})` gives the same result for the relevant operation.

## 24.9 Nested Code Objects as Constants

Nested functions store their code objects in `co_consts`.

Example:

```python id="n17lr5"
def outer():
    def inner():
        return 1
    return inner
```

Inspect:

```python id="56jqwc"
for const in outer.__code__.co_consts:
    print(repr(const))
```

You will find a code object for `inner`.

At runtime, the outer function executes bytecode that loads the nested code object and creates a function object:

```text id="xrarxf"
LOAD_CONST <code object inner>
MAKE_FUNCTION
STORE_FAST inner
```

The nested code object is constant compiled data. The function object is created at runtime.

## 24.10 Name Tables

`co_names` stores symbolic names used by bytecode operations that are not fast locals or closure variables.

These include:

```text id="b9fx1t"
global names
builtin lookup names
attribute names
imported module names
method names
some class body names
```

Example:

```python id="sl10xc"
def f(xs):
    return len(xs)
```

Inspect:

```python id="il1b6j"
print(f.__code__.co_names)
```

Typical shape:

```text id="6whwgp"
('len',)
```

The bytecode loads `len` through a name index.

## 24.11 Globals and Builtins

A name in `co_names` may refer to a global or builtin at runtime.

Example:

```python id="pxxc09"
def f(xs):
    return len(xs)
```

`len` is not local. It is loaded using global lookup rules.

Runtime lookup checks:

```text id="d2z1ce"
function globals
then builtins
```

The code object does not store the actual builtin function `len`. It stores the name string `"len"`.

That means changing globals can affect execution:

```python id="oghwkx"
def f(xs):
    return len(xs)

len = lambda x: 999

print(f([1, 2, 3]))
```

Inside that module, `len` now resolves to the global lambda, not the builtin.

## 24.12 Attribute Names

Attribute names also live in `co_names`.

Example:

```python id="trjd66"
def f(obj):
    return obj.value
```

Inspect:

```python id="vrg5um"
print(f.__code__.co_names)
```

Typical shape:

```text id="133tbx"
('value',)
```

The bytecode uses:

```text id="f1yae8"
LOAD_FAST obj
LOAD_ATTR value
```

The string `"value"` is stored once in `co_names`.

This is separate from global lookup. The same table stores name strings used by multiple instruction families.

## 24.13 Method Names

Method call syntax also uses names.

Example:

```python id="pwnbfj"
def f(obj):
    return obj.run()
```

`run` appears in `co_names`.

The compiler may emit specialized call-oriented instructions depending on Python version, but the method name still comes from the name table.

Conceptual bytecode:

```text id="vjlnib"
LOAD_FAST obj
LOAD_METHOD run
CALL 0
```

The name table stores the method name string.

## 24.14 Import Names

Imports use name tables too.

Example:

```python id="sf2lb3"
def f():
    import os
    return os.getcwd()
```

The name table may contain:

```text id="pi43tc"
os
getcwd
```

The local table contains `os` if the import is inside a function because import binds a local variable.

This distinction matters:

```text id="hc8fxf"
co_names:
    names needed by import and attribute operations

co_varnames:
    local binding created by import os
```

Imports are assignments from the perspective of local variable layout.

## 24.15 Local Variables

`co_varnames` stores fast local variable names.

Example:

```python id="nyh7qv"
def f(a, b):
    c = a + b
    return c
```

Inspect:

```python id="g0h75x"
print(f.__code__.co_varnames)
```

Typical shape:

```text id="ja0vd0"
('a', 'b', 'c')
```

The frame stores local values in an array-like layout. Bytecode indexes into this layout.

```text id="x503qw"
LOAD_FAST 0    a
LOAD_FAST 1    b
STORE_FAST 2   c
```

This is why local access is faster than global dictionary lookup.

## 24.16 Parameter Locals

Function parameters appear first in `co_varnames`.

Example:

```python id="9b48mv"
def f(a, b, c=0):
    d = a + b + c
    return d
```

`co_varnames` usually begins:

```text id="83pbbd"
('a', 'b', 'c', 'd')
```

The call machinery binds arguments into those fast local slots before the function body begins executing.

Defaults are stored on the function object, not directly in the code object.

```python id="9q7w3m"
print(f.__defaults__)
print(f.__code__.co_varnames)
```

## 24.17 Positional-Only and Keyword-Only Locals

Code objects store argument counts separately from `co_varnames`.

Example:

```python id="87asnp"
def f(a, b, /, c, *, d):
    return a, b, c, d
```

Inspect:

```python id="kbjcbq"
code = f.__code__

print(code.co_posonlyargcount)
print(code.co_argcount)
print(code.co_kwonlyargcount)
print(code.co_varnames)
```

The local names are stored in `co_varnames`, while the counts define how to interpret the leading entries.

Conceptually:

```text id="h79uky"
co_varnames:
    a, b, c, d

co_posonlyargcount:
    2

co_argcount:
    3

co_kwonlyargcount:
    1
```

The call machinery uses this metadata for argument binding.

## 24.18 `*args` and `**kwargs`

Variable argument names also appear in `co_varnames`.

Example:

```python id="a78joh"
def f(a, *args, **kwargs):
    return args, kwargs
```

Inspect:

```python id="57zit6"
code = f.__code__

print(code.co_varnames)
print(code.co_flags)
```

The `co_flags` field records that the function accepts variable positional or keyword arguments.

The names `args` and `kwargs` are local slots.

## 24.19 Temporary Values Are Not Named Locals

The evaluation stack holds temporary values.

Example:

```python id="yqtwg0"
def f(a, b, c):
    return a + b * c
```

`co_varnames` contains:

```text id="gvos5r"
a
b
c
```

It does not contain temporary intermediate values such as `b * c`.

That intermediate result lives on the frame’s evaluation stack.

Conceptual stack:

```text id="3snx1b"
LOAD_FAST a       stack: a
LOAD_FAST b       stack: a, b
LOAD_FAST c       stack: a, b, c
BINARY_OP *       stack: a, temp
BINARY_OP +       stack: result
RETURN_VALUE      stack empty
```

Local variables and stack temporaries are separate storage mechanisms.

## 24.20 Cell Variables

`co_cellvars` stores locals captured by nested functions.

Example:

```python id="qbiuv6"
def outer():
    x = 1

    def inner():
        return x

    return inner
```

Inspect:

```python id="91ti0b"
print(outer.__code__.co_cellvars)
```

Typical result:

```text id="n2byuv"
('x',)
```

Inside `outer`, `x` must live in a cell because `inner` may access it after `outer` returns.

The local variable becomes heap-backed closure storage.

## 24.21 Free Variables

`co_freevars` stores names captured from enclosing scopes.

Using the same example:

```python id="b3corm"
inner = outer()
print(inner.__code__.co_freevars)
```

Typical result:

```text id="i1hd7z"
('x',)
```

Inside `inner`, `x` is not a normal local. It is loaded from a closure cell.

Conceptual bytecode:

```text id="o8g8eg"
LOAD_DEREF x
RETURN_VALUE
```

The code object records the name. The function object carries the actual cell.

## 24.22 The Locals Dictionary

Inside a normal optimized function, locals

