Skip to content

Behaviour change in defaultdict.__missing__ between 3.13.11 and 3.13.12 #148242

Open

Description

@cbourjau

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
A

3.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

Activity

  1. added
    stdlibStandard Library Python modules in the Lib/ directory
    on Apr 8, 2026
  2. sunmy2019 commented on Apr 8, 2026

    @sunmy2019
    Member

    bisected to a043407

    Confirmed related by #142668

  3. sunmy2019 commented on Apr 8, 2026

    @sunmy2019
    Member

    I commented there to notify the author. I believe this is not intentional.

    #142668 (comment)

  4. serhiy-storchaka commented on Apr 9, 2026

    @serhiy-storchaka
    Member

    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?

  5. cbourjau commented on Apr 9, 2026

    @cbourjau
    Author

    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:

    However, if the dictionary is a dict subclass that defines missing (i.e. provides a method for default values), then this default is used rather than NaN.

    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 the defaultdict instance.

  6. serhiy-storchaka commented on Apr 10, 2026

    @serhiy-storchaka
    Member
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    stdlibStandard Library Python modules in the Lib/ directorytype-bugAn unexpected behavior, bug, or error

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions