copy.copy(d) on a defaultdict resolves type(d).copy and calls it.
Under Dynamo this became UserDefinedClassVariable(defaultdict).call_method(
"copy"), which fell through to the bare dict type via
SourcelessBuilder(dict). Since dict has no copy, tracing failed with
"Dynamo does not know how to trace method copy".
The fix handles copy in two places. DefaultDictVariable.call_method now
treats "copy" alongside "copy", returning a fresh defaultdict that
preserves default_factory and performs a shallow copy of the base dict.
UserDefinedClassVariable.call_method gains a narrow branch that dispatches
defaultdict.copy(inst) (one positional arg, no kwargs) to the instance,
mirroring the existing OrderedDict.move_to_end pattern.
Test Plan:
CUDA_VISIBLE_DEVICES= PYTORCH_TESTING_DEVICE_ONLY_FOR=cpu PYTORCH_TEST_WITH_DYNAMO=1 \
pixi run -w pytorch -e pytorch313 python -m pytest test/cpython/v3_13/test_defaultdict.py -q
CUDA_VISIBLE_DEVICES= PYTORCH_TESTING_DEVICE_ONLY_FOR=cpu \
pixi run -w pytorch -e pytorch313 python -m pytest test/dynamo/test_dicts.py -q
Authored with the help of an AI assistant.
Pull Request resolved: #186758
Approved by: https://github.com/rtimpe
ghstack dependencies: #185998, #185999, #186042, #186499
SOCIAL SHARE CARD GENERATOR