Developer Tools

PyTorch Dynamo fixes descriptor order bug in UDOV setattr tracking

New PR ensures residual replay matches CPython descriptor precedence in Dynamo.

Deep Dive

PyTorch's Dynamo JIT compiler has received a targeted fix for how it handles attribute mutations on user-defined objects (UDOVs). When Dynamo traces a Python program, it records operations like setattr, getattr, and delattr to create a computation graph. However, it previously did not respect Python's descriptor protocol ordering when replaying these mutations. In CPython, writes to an object's attribute that go through a descriptor (like a property) follow a specific precedence rule: data descriptors (e.g., properties with both getter and setter) take priority over instance __dict__ entries, while non-data descriptors (e.g., functions) are shadowed by instance attributes. Dynamo's residual replay (the fallback execution path when tracing cannot fully capture behavior) incorrectly treated all mutations as direct __dict__ writes, bypassing descriptor semantics and leading to subtle bugs.

The PR (authored by Codex) introduces side-effect tracking that distinguishes between descriptor-aware mutations and direct instance dict writes. Direct __dict__ writes now replay through descriptor-bypassing helpers (simulating obj.__dict__['attr'] = val), while descriptor-backed and generic mutations keep the normal STORE_ATTR/DELETE_ATTR paths. This ensures that residual replay behaves identically to CPython in all cases. The update also adds focused test coverage for readonly properties, property deleters, non-data descriptor lookup after a `delattr`, __dict__ replacement, and descriptor versus instance-dict precedence. For PyTorch developers relying on Dynamo to compile models using custom Python classes with descriptors, this fix removes a class of hard-to-debug inconsistencies, improving both compilation accuracy and model performance predictability.

Key Points
  • Fix ensures residual replay follows CPython descriptor order for UDOV setattr/getattr/delattr
  • Direct __dict__ writes now bypass descriptors via helpers; descriptor-backed mutations keep normal STORE_ATTR/DELETE_ATTR
  • Adds coverage for readonly properties, property deleters, non-data descriptor lookup after delattr, and __dict__ replacement

Why It Matters

Improves accuracy of PyTorch's JIT compiler for user-defined objects, enabling more robust model optimization.