Skip to content

[3.15] gh-129724: Intern string constants in the compiler, not per code object (GH-159193) - #159291

Draft
miss-islington wants to merge 1 commit into
python:3.15from
miss-islington:backport-627eabf-3.15
Draft

miss-islington wants to merge 1 commit into
python:3.15from
miss-islington:backport-627eabf-3.15

Conversation

@miss-islington

@miss-islington miss-islington commented Oct 13, 2026 •

Copy link
Copy Markdown
Contributor

The compiler merges equal constants of a module through its constant
cache. intern_constants() then ran on each code object and rebuilt a
frozenset (or, in the free-threaded build, a slice) when one of its
strings was replaced by an already interned one, so a constant shared by
several functions was copied for some of them depending on which strings
happened to be interned in the process. The class body's qualname
constant and co_qualname had the same problem. marshal then wrote
different bytes for the same source.

Intern the eligible strings of the final constants of each code unit
after optimization and before the code object is created. Tuples are
updated in place; a frozenset or slice is rebuilt once and stored in the
constant cache so that later units get the same object. The same code
is used in both builds.

Which strings are interned does not change, except that identifier-like
strings in slice constants are now interned in the default build too.

TestConstantsIdentity compares the identity graph and the marshal
output of code compiled in differently prepared processes, including
names tuples shared with constants.
(cherry picked from commit 627eabf)

Co-authored-by: Gregory P. Smith 68491+gpshead@users.noreply.github.com

…e object (pythonGH-159193)

The compiler merges equal constants of a module through its constant
cache.  intern_constants() then ran on each code object and rebuilt a
frozenset (or, in the free-threaded build, a slice) when one of its
strings was replaced by an already interned one, so a constant shared by
several functions was copied for some of them depending on which strings
happened to be interned in the process.  The class body's __qualname__
constant and co_qualname had the same problem.  marshal then wrote
different bytes for the same source.

Intern the eligible strings of the final constants of each code unit
after optimization and before the code object is created.  Tuples are
updated in place; a frozenset or slice is rebuilt once and stored in the
constant cache so that later units get the same object.  The same code
is used in both builds.

Which strings are interned does not change, except that identifier-like
strings in slice constants are now interned in the default build too.

TestConstantsIdentity compares the identity graph and the marshal
output of code compiled in differently prepared processes, including
names tuples shared with constants.
(cherry picked from commit 627eabf)

Co-authored-by: Gregory P. Smith <68491+gpshead@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

type-bug An unexpected behavior, bug, or error

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants