Skip to main content

Execution model

A Python program is a sequence of code blocks executed in textual order. Each block runs in a namespace; namespaces nest; references are resolved by walking the scope chain. This page describes the rules that govern naming, binding, scope, and exception flow.

Source-of-record: CPython execution model, Python/symtable.c, Python/compile.c, Python/ceval.c.

Program structure

A Python program is structured into code blocks. A code block is a piece of code executed as a unit. Each kind of code block has its own kind of namespace.

BlockNamespaceCreated by
ModuleModule globalsimport, top-level script run.
Function bodyLocal localsCalling the function.
Class bodyClass namespaceclass statement execution.
ComprehensionHidden localList/set/dict/gen comprehension.
LambdaLocal localsCalling the lambda.
exec / evalPer-call localsCalling exec or eval.
Interactive lineModule globalsOne REPL line.

Naming and binding

What creates a binding

Any of the following binds a name in the current block:

FormNotes
x = ... (assignment)Including augmented.
def x / class xFunction and class definitions.
import xBinds x.
import a.bBinds a.
from x import yBinds y.
from x import y as zBinds z.
for x in ...Loop variable.
as clause: with ... as x, except ... as xLocal binding.
Function parameterLocal in the function.
:= (walrus)Binds in the enclosing block.
Pattern capture in matchBinds the captured name.
Comprehension targetLocal in the hidden comp scope.

Scope classes

Every binding sits in one scope class:

ClassWhere
LocalA name bound in the current function/lambda/class/comp.
EnclosingA name bound in an enclosing function and read here.
GlobalA name in the module namespace.
BuiltinA name in the builtins module.
ClassA name in a class body. Visible to methods only via self. and the special __class__ cell.
FreeA reference that points outside the current scope.
CellA local that is closed over by a nested function.

Resolution order (LEGB)

For a name x referenced in a function:

  1. Local. The function's own locals.
  2. Enclosing. Closure cells, walking outward through enclosing functions.
  3. Global. Module globals.
  4. Builtin. The builtins module.

If no binding is found, raise NameError. If the binding exists but is not yet assigned, raise UnboundLocalError (locals) or NameError (globals/closures).

global and nonlocal

StatementEffect
global xBindings of x in this block write to module globals.
nonlocal xBindings of x in this block write to the nearest enclosing function scope where x is bound.

Either declaration must precede any use of the name. Combining global and nonlocal for the same name in the same block is a SyntaxError.

Class body quirks

A class body's namespace is not visible to methods defined inside it. A class body cannot see its own name during execution (class C: ref = C raises). The special name __class__ is bound in any method that references it; calling super() without arguments uses this cell.

Code execution

Execution of a code block happens in two phases:

  1. Compile. Source -> AST -> control-flow graph -> bytecode.
  2. Evaluate. The VM runs the bytecode in a fresh frame.

The compile phase produces a code object. The evaluate phase needs a code object plus a globals dict (and optionally locals and closure cells). See Bytecode -> Opcodes.

Built-in scope

The builtin scope is the builtins module. Each module has a reference to it as __builtins__. The module is normally a shortcut: __builtins__.__dict__ (or __builtins__ itself in the main module) is consulted for lookup.

If a module is given a different __builtins__ (e.g. a curated dict for sandboxing), name resolution uses that dict instead of the real builtins module. See Manual -> Sandboxing.

Exception flow

Raising

FormEffect
raiseRe-raise the active exception.
raise ExcTypeConstruct ExcType() and raise.
raise ExcType(args)Raise the constructed exception.
raise exc from causeSet exc.__cause__ = cause, __suppress_context__ = True.
raise exc from NoneSuppress implicit context.

Implicit chaining

If an exception is raised while another is being handled, the new exception's __context__ is set to the active exception automatically. __cause__ is set only by raise ... from ....

When an exception propagates, the VM walks the active exception table for the running frame. If a handler is found, control jumps to it. Otherwise the frame unwinds and the exception propagates to the caller.

Exception groups (PEP 654)

ExceptionGroup is a subclass of Exception that wraps multiple exceptions. Two new syntactic forms:

FormMeaning
except* T as e:Match any exception in the group whose type matches T.
BaseExceptionGroup(message, excs)Wrap a sequence of exceptions.

except* handlers may run multiple times for a single group. Exceptions not matched are re-raised in a residual group.

Finalisation

When a function returns, raises, or yields, its locals become unreachable unless they are captured by a closure or held by a returned object. Reference counting reclaims them immediately if their refcount hits zero; otherwise the cycle collector handles them.

__del__ runs at finalisation time. The runtime guarantees it runs at most once; subsequent resurrections do not retrigger it.

Module execution

Importing a module runs its top-level code in a fresh namespace, which becomes the module's __dict__. Re-importing returns the cached module from sys.modules (see Import system).

A module being imported is partially initialised: it exists in sys.modules but its top-level code is still running. Circular imports that reach a name not yet bound raise ImportError or AttributeError.

Concurrency model

Python's concurrency story has three layers:

LayerProvides
GILOne Python instruction at a time per interpreter.
Threads_thread.start_new_thread; releases GIL on blocking I/O.
CoroutinesCooperative scheduling via async def / await.

The GIL is per-interpreter. PEP 684 introduces per-interpreter GILs, allowing multiple interpreters in one process to run Python in parallel.

Tracing and monitoring

HookTriggers on
sys.settrace(fn)Function call, line, return, exception (legacy).
sys.setprofile(fn)Function call, return.
sys.monitoringPEP 669 events; see Manual -> Debugging.

Garbage collection interactions

BehaviourSource
Reference cycles between user types are collected.Modules/gcmodule.c
gc.disable() pauses cycle collection.gc module.
gc.collect() forces a full sweep.gc module.
Weak references are cleared before object finalisation.Objects/weakrefobject.c

Reference

  • CPython 3.14: Execution model.
  • Python/symtable.c. Scope assignment.
  • Python/ceval.c. The eval loop.
  • Symbol table. Internal view.
  • VM. Internal view.