Fix _endpoint_context_cache using id() which risks stale entries afte… by Charisn · Pull Request #14928 · fastapi/fastapi

@Charisn

…memory leaks

The _endpoint_context_cache in routing.py used id(func) as dict keys to
cache endpoint context (source file, line number, function name) for
error messages. This has two problems:

1. ID reuse after garbage collection. Python id() returns the memory
   address of an object. Once an object is garbage collected, its ID can
   be reassigned to a newly created object. If an endpoint function were
   deallocated and a new function reused the same ID, the cache would
   return stale context (wrong file, line, function name) for error
   messages.

2. No eviction. The module-level dict grows unboundedly for every unique
   endpoint function. In scenarios where FastAPI instances are
   dynamically created and destroyed in a single process (e.g., test
   suites running hundreds of apps), endpoint functions and their
   closures are kept alive indefinitely by the cache, leaking memory.

Fix: replace the plain dict with a weakref.WeakKeyDictionary keyed on
the function object itself. This solves both problems: keys are looked
up by object identity (no ID collision), and entries are automatically
evicted when the endpoint function is garbage collected, allowing the
function and its closure to be reclaimed.

Endpoint functions always support weak references (regular def / async
def), so WeakKeyDictionary is safe for this use case.