| A. Direct | Bare, imported, qualified, aliased, star, nested, re-export | foo(), m.foo() | Trivial-Easy |
| B. Method dispatch | Static, class, self, inherited, virtual, MRO, abstract, interface, trait, super, constructor, __new__, bound method | x.method() | Medium — CHA / type inference |
| C. First-class functions | Var, callback, returned, in container, attr, closure, partial, map/filter/reduce, lambda, method-ref | f=foo; f(), handlers[k]() | Hard — points-to analysis |
| D. Dynamic dispatch / reflection | getattr(obj,'n')(), eval, Method.invoke, send, __call__, Proxy, fn.call/apply/bind, subscript with dynamic key | getattr(o,n)() | Impossible statically; runtime only |
| E. Metaprogramming | Decorators (passthrough/wrap), monkey patch, metaclass, __init_subclass__, descriptors, property, staticmethod, singledispatch, functools.wraps, ABC.register, __slots__, dataclass/NamedTuple synthesis, mixins, Protocol | @retry def f | Varies; some resolvable with decorator modeling |
| F. Implicit dunders | Cls(x) → __init__, obj.x → __getattribute__, obj[k] → __getitem__, with x: → __enter__, a==b → __eq__, hash(obj) → __hash__, for x in y → __iter__, a+b → __add__, etc. (33 total) | with f: ... | Blanket rule: keep all dunders on reachable classes |
| G. Async/concurrency | await, create_task, .then, generators, goroutines, channel dispatch, thread pool, event emitter, pub/sub | await coro() | Medium; event/topic matching needed |
| H. Framework dispatch | Route decorators, signals, DI containers, plugins, CLI commands, fixtures, ORM hooks, GraphQL resolvers | @app.route('/x') def h() | Medium; per-framework model |
| I. Cross-boundary | FFI, subprocess, HTTP/gRPC, SQL, MQ, serverless, WASM, JNI | requests.get() | Runtime or schema-contract only |