How Python runs your code
From the text you type to instructions a virtual machine executes, step by step.
When you press Run, Python doesn't read your file line by line like a person would. It goes through a small pipeline, and knowing that pipeline explains a lot of "why does Python do that?" moments.
your text ──► tokens ──► syntax tree (AST) ──► bytecode ──► Python Virtual Machine
"x = 1" NAME OP Assign(x, 1) LOAD_SMALL_INT runs it, one
NUMBER STORE_NAME instruction at a time1. Tokenizing: cutting text into words
The tokenizer splits your source into tokens: names, operators, numbers, strings, and, uniquely for Python, INDENT and DEDENT tokens that come from whitespace.
import io, tokenize
src = "if x > 1:\n y = x * 2\n"
for tok in tokenize.generate_tokens(io.StringIO(src).readline):
print(f"{tokenize.tok_name[tok.type]:<10} {tok.string!r}")2. Parsing: building a syntax tree
The parser checks the grammar and builds an Abstract Syntax Tree, a tree of what your code means. SyntaxError is raised here, before a single line runs, which is why a typo on line 50 stops line 1 from ever executing.
import ast
tree = ast.parse("total = price * 2 + tax")
print(ast.dump(tree.body[0], indent=2))3. Compiling: turning the tree into bytecode
The compiler walks the tree and produces bytecode: compact instructions for an imaginary machine. You can see them with the dis module, or just press Run and open the Inspect tab, which shows the bytecode for your own code.
import dis
def area(w, h):
return w * h
dis.dis(area)def greet(name):
message = "Hello, " + name
return message
code = greet.__code__
print("constants:", code.co_consts)
print("locals: ", code.co_varnames)
print("args: ", code.co_argcount)4. Running: the virtual machine
The Python Virtual Machine is a loop in C (ceval.c) that fetches the next instruction, executes it, and repeats. Most instructions push and pop values on a small value stack inside the current frame: one frame per running function call.
x = a + b compiles to: LOAD_NAME a stack: [a] LOAD_NAME b stack: [a, b] BINARY_OP + stack: [a+b] (calls a.__add__(b)) STORE_NAME x stack: [] (binds the name x)
Where does this Python run?
ThongLearn runs real CPython 3.14, compiled to WebAssembly (the Pyodide project), inside a background thread of your browser called a Web Worker. Nothing is sent to a server. That's also why an infinite loop can't freeze the page: the worker is simply thrown away and a fresh one started.
import sys, platform print(sys.version) print(sys.platform) # "emscripten": the WebAssembly toolchain print(platform.python_implementation())
🧭 Scenario: Your script has a typo in a function you never call, yet it still crashes before printing anything. Now you know why: SyntaxErrors happen at parse time (step 2), before execution starts. A NameError in an uncalled function, on the other hand, never happens, because names are only looked up when the instruction runs (step 4).
💡 Tip: Try any example above, then open Inspect → Bytecode and hover the instruction names to read what each one does.