GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — gh-141510: Add frozendict_check_mutable() by vstinner · Pull Request #144944 · python/cpython

Conversation

@vstinner

@vstinner vstinner commented Feb 18, 2026 •
edited by bedevere-app Bot
Loading

Uh oh!

There was an error while loading. Please reload this page.

Copy link
Copy Markdown
Member

frozendict.fromkeys() now checks if it can mutate the newly created frozendict.

  • Issue: PEP 814: Add built-in frozendict type #141510

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
@vstinner
pythongh-141510: Add frozendict_check_mutable()
bb2c546
frozendict.fromkeys() now checks if it can mutate the newly created
frozendict.
@vstinner
vstinner requested review from markshannon and methane as code owners February 18, 2026 10:35
@vstinner vstinner added the skip news label Feb 18, 2026
@bedevere-app bedevere-app Bot added the awaiting core review label Feb 18, 2026
@bedevere-app bedevere-app Bot mentioned this pull request Feb 18, 2026
PEP 814: Add built-in frozendict type #141510
Closed
@vstinner vstinner mentioned this pull request Feb 18, 2026
gh-141510: Optimize {frozen}dict.fromkeys for frozendict #144915
Merged
@vstinner

vstinner commented Feb 18, 2026

Copy link
Copy Markdown
Member Author

@methane @corona10: I wrote this change to raise an exception if a frozendict subclass constructor keeps a reference to the newly created dictionary.

I don't know which error message should be used, so I wrote: RuntimeError("cannot mutate frozendict already exposed in Python"). Do you have a better error message to propose?

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@vstinner
Fix typo
5ecf0f9
@markshannon

markshannon commented Feb 18, 2026

Copy link
Copy Markdown
Member

Frozen dicts are immutable, that's the whole point of them, so why are we allowing them to be mutated?

Mutation of tuples has been an endless source of bugs, please don't do the same with frozen dicts.

corona10 reacted with thumbs up emoji
All reactions
  • 👍 1 reaction

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@markshannon

markshannon commented Feb 18, 2026

Copy link
Copy Markdown
Member

I don't know which error message should be used, so I wrote: RuntimeError("cannot mutate frozendict already exposed in Python"). Do you have a better error message to propose?

This should be a SystemError.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@corona10

corona10 commented Feb 18, 2026

Copy link
Copy Markdown
Member

Frozen dicts are immutable, that's the whole point of them, so why are we allowing them to be mutated?

I concur with Mark's opinion here.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

corona10
corona10 reviewed Feb 18, 2026
View reviewed changes
Comment thread Objects/dictobject.c
static int
frozendict_check_mutable(PyObject *self)
{
if (Py_REFCNT(self) > 1) {

@corona10 corona10 Feb 18, 2026 •
edited
Loading

Uh oh!

There was an error while loading. Please reload this page.

Copy link
Copy Markdown
Member

There was a problem hiding this comment.

Choose a reason for hiding this comment

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

IIRC, Checking Py_REFCNT at runtime is not thread safe at free-threaded build.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
@vstinner

vstinner commented Feb 18, 2026

Copy link
Copy Markdown
Member Author

This change fix the following example:

fd = None

class SpecialDict(frozendict):
    def __new__(self):
        global fd
        fd = frozendict(x=1)
        return fd

print(SpecialDict.fromkeys("y"))

Currently, _PyDict_FromKeys() calls SpecialDict.__new__() which runs arbitrary Python code.

This change detects the special constructor and raises an error.

Mutation of tuples has been an endless source of bugs, please don't do the same with frozen dicts.

An alternative is to modify _PyDict_FromKeys() to not call the subclass constructor, but always call frozendict constructor: I wrote #144947 to implement this idea.

A more radical fix would be to disallow subclassing frozendict.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@vstinner
vstinner marked this pull request as draft February 18, 2026 11:27
@bedevere-app bedevere-app Bot removed the awaiting core review label Feb 18, 2026
@vstinner

vstinner commented Feb 18, 2026

Copy link
Copy Markdown
Member Author

frozendict_check_mutable() was a bad idea, I close the PR.

I wrote a 3rd PR to fix fromkeys(): #144952 copies the frozendict.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@vstinner vstinner closed this Feb 18, 2026
@vstinner
vstinner deleted the frozendict_mutable branch February 18, 2026 13:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Reviewers

@corona10 corona10 corona10 left review comments
@methane methane Awaiting requested review from methane methane is a code owner
@markshannon markshannon Awaiting requested review from markshannon markshannon is a code owner

Uh oh!

There was an error while loading. Please reload this page.

Assignees

No one assigned

Labels

skip news

Projects

None yet

Milestone

No milestone

Development

Successfully merging this pull request may close these issues.

Uh oh!

There was an error while loading. Please reload this page.

3 participants

@vstinner @markshannon @corona10
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
You are visitor 01402520 — GeezerVison does not store the pages you look up.
Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.