Behaviour change in defaultdict.__missing__ between 3.13.11 and 3.13.12 #148242
Copy link
Copy link
Open
Labels
stdlibStandard Library Python modules in the Lib/ directoryStandard Library Python modules in the Lib/ directorytype-bugAn unexpected behavior, bug, or errorAn unexpected behavior, bug, or error
Description
Bug report
Bug description:
I have observed a subtle change in behavior of defaultdict.__missing__ between Python 3.13.11 and 3.13.12. Consider the following output:
3.13.11:
$ uv run --python 3.13.11 python -c 'from collections import defaultdict; print(defaultdict(lambda: "A", {None: "B"}).__missing__(None))'
Using CPython 3.13.11
Creating virtual environment at: .venv
Built pdonnx @ file:///Users/christian.bourjau/repos/pdonnx
Installed 1 package in 1ms
A3.13.12:
$ uv run --python 3.13.12 python -c 'from collections import defaultdict; print(defaultdict(lambda: "A", {None: "B"}).__missing__(None))'
Using CPython 3.13.12
Removed virtual environment at: .venv
Creating virtual environment at: .venv
Installed 1 package in 1ms
B
The same change in behavior can be observed between 3.14.2 and 3.14.3.
This might be related to #142495 and #142668
Was this an intentional fix?
CPython versions tested on:
3.13
Operating systems tested on:
macOS
Linked PRs
Metadata
Metadata
Assignees
Labels
stdlibStandard Library Python modules in the Lib/ directoryStandard Library Python modules in the Lib/ directorytype-bugAn unexpected behavior, bug, or errorAn unexpected behavior, bug, or error
Activity
sunmy2019 commentedon Apr 8, 2026
bisected to a043407
Confirmed related by #142668
sunmy2019 commentedon Apr 8, 2026
I commented there to notify the author. I believe this is not intentional.
#142668 (comment)
serhiy-storchaka commentedon Apr 9, 2026
Thank you for your report @cbourjau (and thanks @sunmy2019 for bringing this to my attention). This is an interesting observation.
It seems that no one thought that
__missing__()could be used directly. It is called indirectly for subscription when the specified key was not found in the dict. That change was the only solution of the concurrent access problem. The question is whether consider this a bug fix or a new feature (and revert the backports).How did you find such example? Is there a code that directly calls
__missing__()? How that change affected it?cbourjau commentedon Apr 9, 2026
Thanks a lot for looking into this so quickly! The
__missing__member is documented publicly with what I understand to be the prior behavior here. While not calling__missing__directly, pandas does mention that member in its docs here:I stumbled upon this while working on a proprietary library that mirrors the Pandas API. We were able to work around the issue by simply calling
__missing__with a value that is guaranteed not to be in thedefaultdictinstance.serhiy-storchaka commentedon Apr 10, 2026
Opened a discussion https://discuss.python.org/t/about-defaultdict-missing/106922.
Changaco commentedon Apr 23, 2026
The pull requests are ready to be reviewed:
defaultdict, without losing thread safety #148880defaultdict, without losing thread safety #148881 (the failing check doesn't seem related to the proposed changes)