FazBrowse GitHub Viewer | Trending |
URL:
| Home
Tools: [Download Repo ZIP]   [Original HTTPS Page]

gh-141510, PEP 814: Add built-in frozendict type by vstinner · Pull Request #144757 · python/cpython · GitHub

/ cpython Public

gh-141510, PEP 814: Add built-in frozendict type - #144757

Merged
vstinner merged 16 commits into
python:mainfrom
vstinner:frozendict_base
Feb 17, 2026
Merged

gh-141510, PEP 814: Add built-in frozendict type#144757
vstinner merged 16 commits into
python:mainfrom
vstinner:frozendict_base

Conversation

vstinner commented Feb 12, 2026
edited by hugovk
Loading

Copy link
Copy Markdown
Member

Add TYPE_FROZENDICT to the marshal module.

Add C API functions:

  • PyAnyDict_Check()
  • PyAnyDict_CheckExact()
  • PyFrozenDict_Check()
  • PyFrozenDict_CheckExact()
  • PyFrozenDict_New()

Add PyFrozenDict_Type C type.


📚 Documentation preview 📚: https://cpython-previews--144757.org.readthedocs.build/en/144757/c-api/dict.html#frozen-dictionary-objects

Add TYPE_FROZENDICT to the marshal module.

Add C API functions:

* PyAnyDict_Check()
* PyAnyDict_CheckExact()
* PyFrozenDict_Check()
* PyFrozenDict_CheckExact()
* PyFrozenDict_New()

Add PyFrozenDict_Type C type.

Copy link
Copy Markdown
Member Author

cc @corona10

Fix also indentation.
corona10 self-requested a review February 13, 2026 10:07
Comment thread Doc/library/stdtypes.rst Outdated
Comment thread Doc/library/stdtypes.rst Outdated
Comment thread Doc/library/stdtypes.rst Outdated
Comment thread Doc/library/stdtypes.rst Outdated
Comment thread Doc/library/stdtypes.rst Outdated
Comment thread Doc/library/stdtypes.rst Outdated
Comment thread Doc/whatsnew/3.15.rst Outdated
Comment thread Lib/test/mapping_tests.py Outdated
Comment thread Lib/test/mapping_tests.py Outdated
Co-authored-by: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com>
Comment thread Objects/dictobject.c
Comment thread Objects/dictobject.c
}

if (PyDict_CheckExact(d)) {
if (PyAnyDict_CheckExact(d)) {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

Maybe same opinion with @kumaraditya303 we can avoid a lot of critical section if dict is frozen dict.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

I agree, but I would prefer to make such "optimization" change in a separated PR.

Comment thread Objects/dictobject.c
dict_length(PyObject *self)
{
return FT_ATOMIC_LOAD_SSIZE_RELAXED(((PyDictObject *)self)->ma_used);
return GET_USED(_PyAnyDict_CAST(self));

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

Do we have to use atomic operation for frozendict?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

No, we can skip the atomic operation for frozendict.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

It uses relaxed atomic so it compiles to simple loads so avoiding it has no real benefit.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

len(frozendict) has been optimized by #144913.

Comment thread Objects/dictobject.c
};

static PyMappingMethods frozendict_as_mapping = {
.mp_length = dict_length,

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

I think that we can make frozendict_lenth

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

I propose to make such optimization in a separated PR.

Comment thread Objects/dictobject.c

static PyMappingMethods frozendict_as_mapping = {
.mp_length = dict_length,
.mp_subscript = dict_subscript,

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

Still perfer to make frozendict_subscript, but let's do it at the separate PR.

corona10 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

We should notice that frozendict is not subclass of dict to follow SC feedback

vstinner and others added 3 commits February 13, 2026 15:46
Co-authored-by: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com>
Document frozendict after lazy import.
Comment thread Objects/dictobject.c
mp->ma_values == NULL &&
(mp->ma_used >= (mp->ma_keys->dk_nentries * 2) / 3))
(mp->ma_used >= (mp->ma_keys->dk_nentries * 2) / 3) &&
!frozendict)

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

We might take this fast-path for frozendict as well. It's just a missed optimization opportunity.

@corona10: Add it to the optimization TODO list :-)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

Yeah I will take a look at it

Comment thread Objects/dictobject.c
if (items == NULL) {
return -1;
}
PyObject *frozenset = PyFrozenSet_New(items);

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

The current implementation creates an actual frozenset object which emits surprising error messages:

>>> hash(frozendict(x=[]))
Traceback (most recent call last):
  File "<python-input-0>", line 1, in <module>
    hash(frozendict(x=[]))
    ~~~~^^^^^^^^^^^^^^^^^^
TypeError: cannot use 'tuple' as a set element (unhashable type: 'list')

We may change the implementation later to not create an actual frozenset, but reuse frozenset hash code instead, to avoid the surprising errors.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

I changed the implementation in #144919.

Copy link
Copy Markdown
Member Author

We should notice that frozendict is not subclass of dict to follow SC feedback

Ah right, done.

corona10 added the 🔨 test-with-refleak-buildbots Test PR w/ refleak buildbots; report in status section label Feb 14, 2026

Copy link
Copy Markdown

🤖 New build scheduled with the buildbot fleet by @corona10 for commit 9101b1a 🤖

Results will be shown at:

https://buildbot.python.org/all/#/grid?branch=refs%2Fpull%2F144757%2Fmerge

If you want to schedule another build, you need to add the 🔨 test-with-refleak-buildbots label again.

bedevere-bot removed the 🔨 test-with-refleak-buildbots Test PR w/ refleak buildbots; report in status section label Feb 14, 2026

Copy link
Copy Markdown
Member

Let's wait build bot to pass the refleak test :)

benediktjohannes left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

Nitpick: I know this does not primarily belong to the PR, but it's such a small change that a new PR wouldn't make sense for these small "typos".

Comment thread Doc/library/stdtypes.rst
Comment thread Doc/library/stdtypes.rst
Comment thread Doc/library/stdtypes.rst
Comment thread Doc/library/stdtypes.rst Outdated
Co-authored-by: Adam Johnson <me@adamj.eu>

Copy link
Copy Markdown
Member Author

Let's wait build bot to pass the refleak test :)

Tests passed successfully on Refleaks buildbots:

buildbot/AMD64 CentOS9 NoGIL Refleaks PR — Build done.
buildbot/AMD64 Fedora Stable Refleaks PR — Build done.
buildbot/AMD64 FreeBSD Refleaks PR — Build done.
buildbot/AMD64 RHEL8 Refleaks PR — Build done.
buildbot/AMD64 Windows11 Refleaks PR — Build done.
buildbot/ARM64 MacOS M1 Refleaks NoGIL PR — Build done.
buildbot/PPC64LE Fedora Stable Refleaks PR — Build done.
buildbot/PPC64LE RHEL8 Refleaks PR — Build done.
buildbot/s390x Fedora Stable Refleaks PR — Build done.
buildbot/s390x RHEL8 Refleaks PR — Build done.
buildbot/s390x RHEL9 Refleaks PR — Build done.

Comment thread Doc/c-api/dict.rst Outdated
Comment thread Doc/c-api/dict.rst Outdated
Comment thread Doc/c-api/dict.rst Outdated
Comment thread Doc/c-api/dict.rst Outdated
Comment thread Doc/c-api/dict.rst Outdated
Comment thread Doc/c-api/dict.rst Outdated
Comment thread Doc/c-api/dict.rst Outdated
vstinner and others added 2 commits February 16, 2026 13:01
Co-authored-by: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com>
Add also a title in Doc/library/stdtypes.rst.

Copy link
Copy Markdown
Member Author

@hugovk: I modified a few more titles in the C API doc and the Python doc to use sentence case for headers.

corona10 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

lgtm with current implementations , I will soon create PRs for removing unneeded overhead from my side.

sergey-miryanov left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

Couple of nitpicks.

Comment thread Objects/dictobject.c
Comment thread Objects/dictobject.c
Comment thread Objects/dictobject.c
Comment thread Objects/dictobject.c
Comment thread Objects/dictobject.c
Comment thread Doc/whatsnew/3.15.rst Outdated
Comment thread Doc/whatsnew/3.15.rst Outdated
vstinner and others added 2 commits February 16, 2026 21:33
Co-authored-by: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com>
Comment thread Doc/library/stdtypes.rst
Comment thread Doc/library/stdtypes.rst
Comment thread Doc/library/stdtypes.rst
Comment thread Lib/test/mapping_tests.py Outdated
Comment thread Lib/test/mapping_tests.py Outdated
Co-authored-by: Benedikt Johannes <benedikt.johannes.hofer@gmail.com>
vstinner merged commit 696cdfc into python:main Feb 17, 2026
47 checks passed
vstinner deleted the frozendict_base branch February 17, 2026 09:54

Copy link
Copy Markdown
Member Author

I merged my PR. Thank you very much for all your reviews!

brijkapadia pushed a commit to brijkapadia/cpython that referenced this pull request Feb 28, 2026
Add TYPE_FROZENDICT to the marshal module.

Add C API functions:

* PyAnyDict_Check()
* PyAnyDict_CheckExact()
* PyFrozenDict_Check()
* PyFrozenDict_CheckExact()
* PyFrozenDict_New()

Add PyFrozenDict_Type C type.

Co-authored-by: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com>
Co-authored-by: Adam Johnson <me@adamj.eu>
Co-authored-by: Benedikt Johannes <benedikt.johannes.hofer@gmail.com>
ljfp pushed a commit to ljfp/cpython that referenced this pull request Apr 25, 2026
Add TYPE_FROZENDICT to the marshal module.

Add C API functions:

* PyAnyDict_Check()
* PyAnyDict_CheckExact()
* PyFrozenDict_Check()
* PyFrozenDict_CheckExact()
* PyFrozenDict_New()

Add PyFrozenDict_Type C type.

Co-authored-by: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com>
Co-authored-by: Adam Johnson <me@adamj.eu>
Co-authored-by: Benedikt Johannes <benedikt.johannes.hofer@gmail.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

8 participants


Back | FazBrowse Home | New Git URL