Skip to content

Use frozendict on Python 3.15#294

Closed
vstinner wants to merge 1 commit into
hukkin:masterfrom
vstinner:frozendict
Closed

Use frozendict on Python 3.15#294
vstinner wants to merge 1 commit into
hukkin:masterfrom
vstinner:frozendict

Conversation

@vstinner

@vstinner vstinner commented Apr 7, 2026

Copy link
Copy Markdown
Contributor

On Python 3.15, use the new built-in type frozendict, instead of types.MappingProxyType, for BASIC_STR_ESCAPE_REPLACEMENTS constant.

On Python 3.15, use the new built-in type frozendict, instead of
types.MappingProxyType, for BASIC_STR_ESCAPE_REPLACEMENTS constant.
@vstinner

vstinner commented Apr 7, 2026

Copy link
Copy Markdown
Contributor Author

Change extracted from the larger #292 change.

@codecov

codecov Bot commented Apr 7, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 100.00%. Comparing base (bbca44b) to head (b099527).

Additional details and impacted files
@@            Coverage Diff            @@
##            master      #294   +/-   ##
=========================================
  Coverage   100.00%   100.00%           
=========================================
  Files            4         4           
  Lines          535       534    -1     
  Branches       100       100           
=========================================
- Hits           535       534    -1     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@encukou

encukou commented Apr 8, 2026

Copy link
Copy Markdown
Collaborator

What's the benefit?
The MappingProxyType downsides given in PEP 814 doesn't really apply to this internal mapping:

This type is not hashable and it’s not possible to inherit from it. It’s also easy to retrieve the original dictionary which can be mutated, for example using gc.get_referents().

@vstinner

vstinner commented Apr 8, 2026

Copy link
Copy Markdown
Contributor Author

It avoids import types which can improve the tomli startup time a little bit.

Accessing frozendict items is also a little bit faster than MappingProxyType: Mean +- std dev: [proxy] 20.0 ns +- 0.4 ns -> [frozendict] 18.1 ns +- 0.4 ns: 1.10x faster. (I'm surprised that the difference is not higher.)

python3.15 -m pyperf timeit -s 'import types; d={"key": 1}; d=types.MappingProxyType(d)' 'd["key"]' -o proxy.json
python3.15 -m pyperf timeit -s 'd={"key": 1}; d=frozendict(d)' 'd["key"]' -o frozendict.json

@hukkin

hukkin commented Apr 8, 2026

Copy link
Copy Markdown
Owner

I don't think this does much anything currently because tomli._re imports re and functools which both bring types in regardless. If we lazy import tomli._re though then this makes sense, I think.

@vstinner

vstinner commented Apr 9, 2026

Copy link
Copy Markdown
Contributor Author

Ok, I close my PR.

@vstinner vstinner closed this Apr 9, 2026
@vstinner vstinner deleted the frozendict branch April 9, 2026 10:46
@danielhollas

Copy link
Copy Markdown

If we lazy import tomli._re though then this makes sense, I think.

Since the tomli._re lazy import has been merged, is it worth re-opening this PR to avoid import types as well?

@hukkin

hukkin commented Apr 14, 2026

Copy link
Copy Markdown
Owner

I'd imagine that the attempt to avoid types import still remains futile, seeing that the new lazy import mechanism uses types.LazyImportType lazy objects.

If CPython wants this change, however, I don't object to it. A frozendict better reflects the kind of type that was needed here, i.e. an immutable mapping rather than a read-only proxy to a mutable mapping.

@vstinner

Copy link
Copy Markdown
Contributor Author

Ok, I recreated my PR to use frozendict: #297.

@encukou

encukou commented Apr 14, 2026

Copy link
Copy Markdown
Collaborator

the new lazy import mechanism uses types.LazyImportType lazy objects.

CPython doesn't import types for lazy imports (AFAIK); that's just where the type is exposed to Python code.

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.

4 participants