Behind Python's dynamic ergonomics lies a foundation of rigorous mathematical equations, recurrence relations, and formal structural invariants.
This revision matrix consolidates every mathematical equation governing CPython runtime execution, memory footprints, and algorithmic complexities into a single, authoritative reference.
Formal Mathematical Models ReferenceComplete mathematical formulations governing CPython memory, algorithms, and execution.
Fixed Object Header : PyObject = ( ob_refcnt , ob_type ) ⟹ 16 bytes \text{Fixed Object Header}: \text{PyObject} = (\text{ob\_refcnt}, \text{ob\_type}) \implies 16 \text{ bytes} Fixed Object Header : PyObject = ( ob_refcnt , ob_type ) ⟹ 16 bytes Variable Object Header : PyVarObject = ( ob_refcnt , ob_type , ob_size ) ⟹ 24 bytes \text{Variable Object Header}: \text{PyVarObject} = (\text{ob\_refcnt}, \text{ob\_type}, \text{ob\_size}) \implies 24 \text{ bytes} Variable Object Header : PyVarObject = ( ob_refcnt , ob_type , ob_size ) ⟹ 24 bytes GC Tracked Header : PyGC_Head = ( gc_next , gc_prev , gc_refs ) ⟹ 16 bytes (prepended) \text{GC Tracked Header}: \text{PyGC\_Head} = (\text{gc\_next}, \text{gc\_prev}, \text{gc\_refs}) \implies 16 \text{ bytes (prepended)} GC Tracked Header : PyGC_Head = ( gc_next , gc_prev , gc_refs ) ⟹ 16 bytes (prepended)
Arbitrary-Precision Integers ( PyLongObject) # Large integers N ∈ Z N \in \mathbb{Z} N ∈ Z are expressed using a sign-magnitude base- 2 30 2^{30} 2 30 positional numeral system:
N = sgn ( ob_size ) ⋅ ∑ i = 0 ∣ s ∣ − 1 d i ⋅ 2 30 ⋅ i N = \text{sgn}(\text{ob\_size}) \cdot \sum_{i=0}^{|s|-1} d_i \cdot 2^{30 \cdot i} N = sgn ( ob_size ) ⋅ i = 0 ∑ ∣ s ∣ − 1 d i ⋅ 2 30 ⋅ i Where:
d i ∈ { 0 , 1 , … , 2 30 − 1 } d_i \in \{0, 1, \dots, 2^{30} - 1\} d i ∈ { 0 , 1 , … , 2 30 − 1 } is an unsigned 32-bit digit word ( uint32_t). ∣ s ∣ = ∣ ob_size ∣ |s| = |\text{ob\_size}| ∣ s ∣ = ∣ ob_size ∣ indicates the count of active digits. sgn ( ob_size ) ∈ { − 1 , 0 , 1 } \text{sgn}(\text{ob\_size}) \in \{-1, 0, 1\} sgn ( ob_size ) ∈ { − 1 , 0 , 1 } stores integer sign. Flexible Unicode Strings (PEP 393) # 1 \text{ byte} & \text{if } V_{\max} < 2^8 \quad (\text{ASCII / Latin-1}) \\
2 \text{ bytes} & \text{if } 2^8 \le V_{\max} < 2^{16} \quad (\text{UCS-2}) \\
4 \text{ bytes} & \text{if } 2^{16} \le V_{\max} < 2^{32} \quad (\text{UCS-4})
M str ( L , k ) = sizeof ( PyASCIIObject ) + ( L ⋅ k ) + 1 M_{\text{str}}(L, k) = \text{sizeof}(\text{PyASCIIObject}) + (L \cdot k) + 1 M str ( L , k ) = sizeof ( PyASCIIObject ) + ( L ⋅ k ) + 1
3. Container Capacity & Hash Recurrence Relations # Dynamic Array Capacity Growth ( PyListObject) # When an append operation exceeds capacity, CPython reallocates the pointer buffer according to the non-linear growth formula:
C new = N new + ⌊ N new 8 ⌋ + { 3 if N new < 9 6 if N new ≥ 9 C_{\text{new}} = N_{\text{new}} + \left\lfloor \frac{N_{\text{new}}}{8} \right\rfloor + \begin{cases} 3 & \text{if } N_{\text{new}} < 9 \\ 6 & \text{if } N_{\text{new}} \ge 9 \end{cases} C new = N new + ⌊ 8 N new ⌋ + { 3 6 if N new < 9 if N new ≥ 9 This guarantees amortized insertion complexity O ( 1 ) O(1) O ( 1 ) while bounding memory waste to roughly 12.5 % 12.5\% 12.5% .
Open Addressing Hash Collision Probing ( PyDictObject) # Given key hash h = hash ( K ) h = \text{hash}(K) h = hash ( K ) , probing index i i i inside a table of size 2 k 2^k 2 k follows the pseudo-random recurrence relation:
i 0 = h ( m o d 2 k ) i_0 = h \pmod{2^k} i 0 = h ( mod 2 k ) i j + 1 = ( 5 ⋅ i j + 1 + perturb j ) ( m o d 2 k ) , perturb j + 1 = perturb j ≫ 5 i_{j+1} = (5 \cdot i_j + 1 + \text{perturb}_j) \pmod{2^k}, \quad \text{perturb}_{j+1} = \text{perturb}_j \gg 5 i j + 1 = ( 5 ⋅ i j + 1 + perturb j ) ( mod 2 k ) , perturb j + 1 = perturb j ≫ 5 Where perturb 0 = h \text{perturb}_0 = h perturb 0 = h .
4. Hierarchy & Resolution Invariants # C3 Linearization MRO Recursion Identity # The Method Resolution Order L ( C ) L(C) L ( C ) for class C C C with parents B 1 , B 2 , … , B n B_1, B_2, \dots, B_n B 1 , B 2 , … , B n is:
L ( C ) = C + merge ( L ( B 1 ) , L ( B 2 ) , … , L ( B n ) , ( B 1 , B 2 , … , B n ) ) L(C) = C + \text{merge}\left( L(B_1), L(B_2), \dots, L(B_n), (B_1, B_2, \dots, B_n) \right) L ( C ) = C + merge ( L ( B 1 ) , L ( B 2 ) , … , L ( B n ) , ( B 1 , B 2 , … , B n ) ) L ( object ) = ( object ) L(\text{object}) = (\text{object}) L ( object ) = ( object ) Subject to the head-not-in-tail selection rule:
head ( L i ) ∉ tail ( L j ) , ∀ j ≠ i \text{head}(L_i) \notin \text{tail}(L_j), \quad \forall j \neq i head ( L i ) ∈ / tail ( L j ) , ∀ j = i Attribute Resolution Precedence Sequence # R ( o b j , a t t r ) = DataDescriptor ≻ InstanceDict ≻ NonDataDescriptor ≻ ClassDict ≻ GetAttr \mathcal{R}(obj, attr) = \text{DataDescriptor} \succ \text{InstanceDict} \succ \text{NonDataDescriptor} \succ \text{ClassDict} \succ \text{GetAttr} R ( o bj , a tt r ) = DataDescriptor ≻ InstanceDict ≻ NonDataDescriptor ≻ ClassDict ≻ GetAttr Amdahl's Law Speedup Boundary # Speedup ( P ) = 1 S + 1 − S P − O ( P ) \text{Speedup}(P) = \frac{1}{S + \frac{1 - S}{P}} - O(P) Speedup ( P ) = S + P 1 − S 1 − O ( P )
5. Concept Verification # Test your understanding of formal CPython mathematical models:
Concept check
In the PyListObject capacity formula, why does CPython add (N >> 3) plus 3 or 6 instead of simply doubling the capacity (2 * N) like standard textbooks?
A Doubling capacity wastes up to 50% extra memory on large lists; CPython's formula bounds average wasted memory to ~12.5% while still guaranteeing amortized O(1) appends
B Doubling would cause integer overflow on 64-bit CPUs
C CPython list memory is allocated on magnetic tape drives
D The operating system forbids doubling dynamic arrays
Concept check
What guarantees that large integers in Python never suffer from silent integer overflow during arithmetic operations?
A PyLongObject represents integers as sign-magnitude arrays of 30-bit digits
B dynamically allocating additional digit words as numbers grow
C Integers in Python are limited to 64 bits like C
D Python rounds overflowing integers to infinity
E Integers are converted into floating-point numbers automatically