🧠
Senior Deep-Dives L5 PRO · 161 lessons asyncio internals, GIL, typing tricks, Rust extensions
161 lessons across 6 modules: concurrency & async internals, CPython internals & performance, metaclasses + descriptors + dunder magic, memory + profiling + optimization (memray/tracemalloc), and architecture + code review + senior judgment.
✅ Before you start
· 2+ years of Python in production. You've shipped something that failed at 2am · Comfortable with type hints, dataclasses, async/await. We go into asyncio internals — not basics · You've read profiler output once and felt confused. Good — that's what we fix ℹ️ Heads-up on the format: Senior Deep-Dives are mostly concept lessons + code reviews + predict-the-output exercises. Some samples touch CPython internals or C-extension boundaries that Skulpt/Pyodide can't execute — those run as walkthroughs, not live-runnable code.
🗺 Map 📚 Curriculum
🔒 asyncio: event loop deep-dive
🔒 Typing: TypeVar, Generic, Protocol
🔒 Memory and reference counting
🔒 Profiling: cProfile, py-spy, memory_profiler
🔒 concurrent.futures vs asyncio vs threading
🔒 Packaging modern Python apps
🔒 Testing strategies at scale
🔒 Observability: metrics, traces, logs
🔒 API design — pagination, errors, versioning
🔒 Capstone: redesign a hot path
🔒 The dis module — reading Python bytecode
🔒 Slots optimization in depth
🔒 Weak references (weakref module)
🔒 functools.singledispatch — type-dispatch
🔒 contextlib.contextmanager
🔒 🎯 Review: Senior Python module 1 recap
🔒 ExitStack for dynamic context management
🔒 asyncio.TaskGroup (Python 3.11+) vs gather
🔒 Cancellation patterns in asyncio
🔒 asyncio.Semaphore for backpressure
🔒 trio vs asyncio — when to pick which
🔒 Cython basics — typing hot paths
🔒 mypy strict mode + custom plugins
🔒 ParamSpec and Concatenate (typing 3.10+)
🔒 Generic protocols (typing.Protocol with TypeVar)
🔒 Memory views and buffer protocol
🔒 struct module for binary parsing
🔒 logging filters and adapters
🔒 Building custom pytest plugins
🔒 Debugging deadlocks (py-spy + gdb)
🔒 Capstone: profile + optimize a real bottleneck (CPU + memory)
🔒 CPython internals: bytecode and frame objects
🔒 PEP 703: no-GIL Python — what changes
🔒 Faster CPython: 3.11 / 3.12 / 3.13 improvements
🔒 Sub-interpreters (PEP 684, PEP 734)
🔒 asyncio internals: event loop step-by-step
🔒 🎯 Review: Senior Python module 2 recap
🔒 uvloop vs default asyncio loop
🔒 Trio's structured concurrency principles
🔒 Multiprocessing pitfalls: pickle, fork vs spawn
🔒 NumPy vectorization patterns
🔒 Numba JIT for hot Python loops
🔒 PEP 695: Type Parameters syntax (Python 3.12)
🔒 Variadic generics: TypeVarTuple and Unpack
🔒 typing.Self and @override (3.11+)
🔒 dataclass slots and kw_only
🔒 attrs vs dataclass vs Pydantic — when each wins
🔒 msgspec for ultra-fast (de)serialization
🔒 pydantic_settings for typed env config
🔒 Logging at scale: structlog + sampling + sinks
🔒 Open Source contribution flow
🔒 Capstone: redesign a slow Python service end-to-end
🔒 Cython basics — when pure Python isn't enough
🔒 C extensions via ctypes / cffi
🔒 PyO3 — Rust extensions for modern Python
🔒 AST manipulation with the `ast` module
🔒 Predict: bytecode introspection with `dis`
🔒 🎯 Review: Senior Python module 3 recap
🔒 Coroutine internals — `__await__` from scratch
🔒 asyncio TaskGroups + ExceptionGroup (3.11+)
🔒 Subinterpreters + free-threading (PEP 684, 703)
🔒 Memory views and the buffer protocol
🔒 Weak references and finalizers
🔒 GC tuning — generations and freeze
🔒 Profilers: cProfile vs pyinstrument vs py-spy
🔒 Memory profiling: tracemalloc + memray
🔒 Bytecode caching — __pycache__ internals
🔒 Import system internals — finders and loaders
🔒 Pattern matching internals — __match_args__
🔒 Type system: ParamSpec, TypeVarTuple, Self
🔒 Protocols vs ABCs vs duck typing
🔒 🏆 Capstone — diagnose a memory leak in production
🔒 When to introduce an abstraction
🔒 Code review: nitpicks vs blockers
🔒 Refactoring: characterization tests first
🔒 API design: stability vs ergonomics
🔒 Naming: domain language wins
🔒 🎯 Review: Senior Python module 4 recap
🔒 Error handling: exceptions vs Result types
🔒 Logging vs metrics vs tracing
🔒 Migrations: expand → migrate → contract
🔒 Concurrency: actor model vs shared memory
🔒 Mocking: when it lies to you
🔒 Documentation: ADRs for irreversible decisions
🔒 Testing pyramid: unit > integration > e2e
🔒 Logging PII: regulatory implications
🔒 Caching: cache-aside vs read-through
🔒 Threading: futures vs raw threads
🔒 Generators: yield from + send
🔒 Pickling: security warning
🔒 Memory leaks: cycles and weakref
🔒 Architecture: monolith vs microservices
🔒 Senior interview signal: 'show me the postmortem'
🔒 On-call: runbook is the contract
🔒 Senior glue work: invisible but irreplaceable
🔒 Tech debt: pay down with feature work
🔒 Mentoring: review with questions, not answers
🔒 🏆 Final senior capstone: judgment under uncertainty
🔒 Descriptor lookup order — data vs non-data
🔒 C3 linearisation — predict the MRO
🔒 contextvars in async — Task context isolation
🔒 typing.Protocol — runtime_checkable's hidden hole
🔒 asyncio reentrance — you can't nest `asyncio.run()`
🔒 functools.cache — hashability is the gate
🔒 Walrus in comprehensions — scope leak gotcha
🔒 functools.partial vs lambda — closure timing
🔒 dataclass field(default_factory) — the mutable-default block
🔒 Sentinel object — distinguishing 'not passed' from 'passed None'
🔒 __init_subclass__ — auto-registration without metaclasses
🔒 enum.IntFlag — bitwise composition and the `in` operator
🔒 WeakValueDictionary — caches that let GC do its job
🔒 `__slots__` — when you're paying for `__dict__` you don't use
🔒 contextlib.ExitStack — dynamic context-manager composition
🔒 functools.singledispatch — type-dispatched generic functions
🔒 @dataclass(frozen=True) + dataclasses.replace — immutable updates
🔒 @runtime_checkable Protocol — structural typing + its blind spots
🔒 __match_args__ — making your classes destructurable
🔒 🏆 Module 7 capstone: composing the seven patterns into a real design
🔒 asyncio.Semaphore — bounded concurrency without blocking the loop
🔒 asyncio.shield — let the inner work finish even when the outer awaiter walks away
🔒 asyncio.as_completed — stream results as tasks finish
🔒 asyncio.Queue — bounded backpressure between producer and consumer
🔒 asyncio.Lock — FIFO-fair, NOT reentrant, cancellation-safe
🔒 asyncio.Event — one-shot broadcast that stays set
🔒 asyncio.TaskGroup — structured concurrency (3.11+) replaces gather
🔒 🏆 Module 8 capstone: async correctness in a real ingest pipeline
🔒 Custom exception hierarchies — most-specific except first
🔒 Mis-ordered except clauses — when subclass handlers become dead code
🔒 Exception chaining: `raise X from Y` vs implicit context vs bare re-raise
🔒 contextlib.suppress — quietly skip specific exceptions
🔒 traceback.TracebackException — exceptions as data
🔒 ExceptionGroup + except* — multiple failures, one raise
🔒 Retry decorator — bounded attempts + exponential backoff + targeted catch
🔒 🏆 Module 9 capstone: batch CSV importer with structured error handling
🔒 pathlib.Path — the modern alternative to os.path string-pushing
🔒 @dataclass(kw_only=True, slots=True) — the modern senior default
🔒 typing.Annotated — metadata that hides BEHIND the type
🔒 enum.StrEnum — type-safe strings that serialise like strings
🔒 typing.Self (3.11+) — fluent builders that subclass correctly
🔒 typing.Never + assert_never — exhaustiveness checks the compiler enforces
🔒 TypedDict + NotRequired — JSON shapes as types
🔒 🏆 Module 10 capstone: typed config-driven API client
🔒 Parametrised decorators — three nested functions, not two
🔒 Decorator stacking — TOP wraps last, runs first
🔒 Class-based decorators — when the wrapper needs state
🔒 functools.singledispatchmethod — type dispatch when there's a self in the way
🔒 @contextlib.contextmanager — context managers from generators
🔒 Descriptor protocol — the mechanic under @property and ORM columns
🔒 typing.ParamSpec — decorators that preserve the wrapped signature
🔒 🏆 Module 11 capstone: designing a published decorator library
🔒 Write: implement freeze() — a recursive hashable-converter for cache keys
🔒 Write: merge_dicts() with conflict-resolution strategies
🔒 Write: chunked() — yield successive batches from a sequence
🔒 Write: unique_by() — order-preserving deduplication with a key function
Tip: click any lesson to revisit it. After your first attempt, the “Show example” button reveals the full solution.