Skip to content

gh-158490: Don't freeze a shared set in the frozenset() fast path - #158492

Open
fedonman wants to merge 5 commits into
python:mainfrom
fedonman:fix-frozenset-shared-set
Open

fedonman wants to merge 5 commits into
python:mainfrom
fedonman:fix-frozenset-shared-set

Conversation

@fedonman

@fedonman fedonman commented Sep 30, 2026 •

Copy link
Copy Markdown
Contributor

frozenset() of a set comprehension froze the comprehension's set in place, but a comprehension that is not inlined, such as one in a class annotation, returns its set from a call, where a trace function or pdb can keep it. The compiler now uses the fast path only for comprehensions that are inlined.

make_frozenset() assumed that the set built for frozenset() of a set
display or comprehension is uniquely referenced and froze it in place.
A trace function or pdb can still hold the set returned by a
comprehension that is not inlined, such as one in a class annotation.
Copy the set in that case.
Comment thread Python/intrinsics.c Outdated
Comment on lines +215 to +217
if (!_PyObject_IsUniquelyReferenced(set)) {
return PyFrozenSet_New(set);
}

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.

The whole point of this intrinsic is that we assume the incoming set is uniquely referenced (though the naming is kind of bad). I think we should disable the optimization in the annotations path, not add extra cost to every instance of frozenset({...}).

…lined

Instead of copying a shared set in make_frozenset(), don't use the
frozenset() fast path for a set comprehension that is not inlined.
Only such a comprehension returns its set from a call, where a trace
function can keep it, so make_frozenset() keeps its assumption that
the set is uniquely referenced and other uses pay for no extra check.

@ZeroIntensity ZeroIntensity 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.

The crux of the fix looks good, but while we're here, can you rename that intrinsic to something like FREEZE_SET?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants