Perfect.
Today we open the Python engine and look inside.
This is one of the most important days in the entire course.
If you truly understand DAY 2, Python will never feel “magical” again.
🧠 DAY 2 — Python Execution Model (Inside CPython)
🔑 BIG IDEA OF THE DAY
Python does NOT execute source code directly.
Python executes BYTECODE using a virtual machine.
Everything today revolves around this pipeline.
1️⃣ The Full Python Execution Pipeline (Bird’s-Eye View)




Source Code (.py)
↓
Lexical Analysis (Tokenizer)
↓
Parsing
↓
Abstract Syntax Tree (AST)
↓
Bytecode Compilation (.pyc)
↓
Python Virtual Machine (PVM)
↓
OS / CPU
⚠️ Every single Python program follows this path.
2️⃣ Step 1: Tokenization (Lexical Analysis)
Python first converts raw text into tokens.
Example
x = 10 + 20
Tokens:
NAME(x), OP(=), NUMBER(10), OP(+), NUMBER(20)
💡 Python uses whitespace + indentation as syntax
→ This is why indentation errors exist.
3️⃣ Step 2: Parsing → AST (Abstract Syntax Tree)
Tokens are converted into a tree structure.
x = 10 + 20
AST (conceptually):
Assign
├── Name(x)
└── BinOp
├── Constant(10)
└── Constant(20)
Why AST matters
- Syntax checking happens here
- Some optimizations happen here
- Tools like linters, formatters work on AST
4️⃣ Step 3: Compilation → Bytecode
Python compiles AST into bytecode, not machine code.
Bytecode characteristics
- Platform-independent
- Low-level instructions
- Stack-based
Let’s SEE it.
import dis
def f():
x = 10 + 20
return x
dis.dis(f)
Typical output:
LOAD_CONST 1 (10)
LOAD_CONST 2 (20)
BINARY_ADD
STORE_FAST 0 (x)
LOAD_FAST 0 (x)
RETURN_VALUE
👉 This is what Python actually executes.
5️⃣ What Is .pyc and __pycache__?
When Python creates .pyc
- When importing a module
- When source code hasn’t changed
Why .pyc exists
- Skip recompilation
- Faster startup
⚠️ .pyc ≠ executable
It’s bytecode, not machine code.
6️⃣ Step 4: Python Virtual Machine (PVM)
The Python Virtual Machine:
- Reads bytecode
- Executes instruction by instruction
- Maintains:
- Call stack
- Frame objects
- Evaluation stack
VERY IMPORTANT
Python is a stack-based VM, not register-based.
7️⃣ Stack-Based Execution (CRUCIAL)
Example:
a = 3
b = 4
c = a + b
Execution:
LOAD_FAST a
LOAD_FAST b
BINARY_ADD
STORE_FAST c
Stack state:
[3]
[3, 4]
[7]
[]
👉 Every operation pushes/pops from stack.
8️⃣ Python Frames (Execution Context)
Every function call creates a frame object.
Frame contains:
- Local variables
- Global variables
- Instruction pointer
- Operand stack
def f():
return 1
def g():
return f()
g()
Call stack:
Frame g
└── Frame f
9️⃣ Why Python Errors Happen Where They Do
SyntaxError
- Happens at parse time
if True print("hi")
NameError
- Happens at runtime
print(x)
TypeError
- Happens during bytecode execution
1 + "1"
🔥 INTERVIEW GOLD (DAY 2)
Q1: Why Python startup is slow?
✔ Parsing
✔ Bytecode compilation
✔ Module imports
Q2
def f():
return 1
print(f.__code__)
This object contains:
- Bytecode
- Constants
- Variable names
- Line numbers
Q3
Is Python interpreted line by line?
❌ NO
✅ Python executes compiled bytecode
🧠 COMMON MISCONCEPTIONS (CLEAR THEM NOW)
❌ Python runs line-by-line
❌ Python doesn’t compile
❌ .pyc is optional magic
❌ Python VM = OS process
✅ Python has its own VM
✅ Compilation happens every time code changes
✅ Execution is stack-based
📝 DAY 2 ASSIGNMENT (VERY IMPORTANT)
1️⃣ Disassemble everything
import dis
def test(a, b):
return a * b + 10
dis.dis(test)
Write:
- Which instructions push to stack?
- Which pop from stack?
2️⃣ Explain in your own words:
Why Python cannot do true compile-time optimization like C?
3️⃣ Think (interview-style):
If Python bytecode is portable, why is Python still slower than Java?
🔜 DAY 3 PREVIEW (FOUNDATION DAY)
DAY 3 — Variables, Names, References & Object Identity
This is where 90% Python confusion disappears:
- Why
isvs== - Why mutation surprises people
- Why Python variables aren’t boxes
When ready, say 👉 “START DAY 3”