GeezerVison is showing github.com — gh-145478: Implement `frozendict` into `functools.partial` by brijkapadia · Pull Request #145960 · python/cpython
Conversation
brijkapadia
commented
Mar 15, 2026
•
edited by github-actions
Bot
Loading
Uh oh!
There was an error while loading. Please reload this page.
Changes:
partial.__setstate__ takes any dict for keywords and checks keywords to make sure that they are strings
- changed some tests to make sure they still make sense when working with a
frozendict (rather than a dict)
- change pickle tests to use protocols 2+, but am not sure if this is the best solution or if there is a problem not using protocols 0 or 1. I made this change since
frozendict does not work for these lower numbed protocols
📚 Documentation preview 📚: https://cpython-previews--145960.org.readthedocs.build/
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
|
cc @encukou since you originally suggested this change.
|
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
|
Most of the test errors are due to problems with pickling the partial object, due to the fact that frozendict does not work for all protocols. I'm not sure what the best approach is, but one solution might be to define __reduce_ex__ for partial and have it create a temporary dict for certain protocols instead of using a frozendict.
|
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
|
Update: I realized that the simplest solution would be for partial_reduce to return a dict instead of a frozendict as there were issues pickling a frozendict. However, that meant I had to introduce a partial_copy function for shallow copies. I left the pure python implementation as is, which means it uses __reduce_ex__, however I am open to changing this to be consistent with the C code.
|
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
|
Sorry for the delay.
Seeing the PR, I realized it's a backwards incompatible change, since keywords is publicly accessible:
>>> import functools
>>> p = functools.partial(print)
>>> p.keywords['sep'] = '::'
>>> p('a', 'b')
a::b
It would be good to deprecate this first, but that looks like a lot of extra work :/
@vstinner, do you know of more cases where it would be good to replace dict with frozendict with a deprecation period? Would it be worth it to create a helper for this?
|
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
@vstinner, do you know of more cases where it would be good to replace dict with frozendict with a deprecation period? Would it be worth it to create a helper for this?
How would you implement such deprecation period? In the documentation only?
There are many dictionaries in the stdlib which should not be modified but are declared as mutable dict (dict type). Changing these dictionaries to frozendict would be nice to make the API stricter. But I didn't propose such changes since it can affect projects expecting a mutable dictionary.
So far, if I recall correctly, only two changes (gh-144909 and gh-144910) were merged to replace dict with frozendict in private stdlib APIs. I was told that the _opcode_metadata change (private module) impacts Meta CinderX which does modify _opcode_metadata dictonaries on purpose (they wrote a simple change to become compatible with Python 3.15 frozendict).
There is also gh-144904 which replaced types.MappingProxyType with frozendict. It changed the dataclasses and email.headerregistry APIs in subtle way (return MappingProxyType instead of frozendict, it's documented).
Another example is gh-144906 which proposed converting errno.errorcode dict to a frozendict. The PR was rejected by the module maintainer, since it's useful to be able to modify errno.errorcode dictionary.
By the way, the SC decision includes:
Stdlib adoption should happen with each module maintainer’s approval, not as a mechanical sweep.
|
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
How would you implement such deprecation period? In the documentation only?
I was thinking of a new mapping class that warns when mutated.
Stdlib adoption should happen with each module maintainer’s approval, not as a mechanical sweep.
Yes, but when approval is given, we need to honor the backwards compatibility policy.
|
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
Seeing the PR, I realized it's a backwards incompatible change, since keywords is publicly accessible
Okay, I will defer to your judgment on whatever makes the most sense.
Additionally, this PR also enforces that the keywords for the keywords dictionary are always strings. This is also a backward-incompatible change, but it might be easier to implement than converting the keywords dict to a frozendict.
|
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
Additionally, this PR also enforces that the keywords for the keywords dictionary are always strings.
Yeah, but since you can't call functions with non-string keywords, I see this as erroring out earlier.
|
brijkapadia reacted with thumbs up emoji
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
|
This PR is stale because it has been open for 30 days with no activity.
|
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
|
@encukou do you think it is still worth deprecating this feature?
|
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
encukou
commented
Jun 1, 2026
•
edited
Loading
Uh oh!
There was an error while loading. Please reload this page.
|
That depends -- mainly on how many other cases would use the deprecation. It's probably not worth the trouble for this case only.
|
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
|
Okay, I'll close this then
|
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
This was referenced Aug 14, 2026
Reviewers
rhettinger
Awaiting requested review from rhettinger
rhettinger is a code owner
Uh oh!
There was an error while loading. Please reload this page.
Assignees
No one assigned
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.
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.
|