Skip to content

Commit daa024d

Browse files
vstinnerhugovk
andauthored
PEP 814: Minor tweaks (#4703)
Co-authored-by: Hugo van Kemenade <[email protected]>
1 parent 6da8478 commit daa024d

File tree

1 file changed

+79
-10
lines changed

1 file changed

+79
-10
lines changed

peps/pep-0814.rst

Lines changed: 79 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ Status: Draft
66
Type: Standards Track
77
Created: 12-Nov-2025
88
Python-Version: 3.15
9+
Post-History: `13-Nov-2025 <https://discuss.python.org/t/104854>`__
10+
911

1012
Abstract
1113
========
@@ -75,6 +77,15 @@ Construction
7577
- another ``frozendict``,
7678
- or an iterable of key/value tuples.
7779

80+
* ``frozendict(collection, **kwargs)`` combines the two previous
81+
constructions.
82+
83+
Keys must be hashable and so immutable, but values can be mutable.
84+
Using immutable values creates a hashtable ``frozendict``.
85+
86+
Creating a ``frozendict`` from a ``dict``, ``frozendict(dict)``, has a
87+
complexity of *O*\ (*n*): items are copied (shallow copy).
88+
7889
The insertion order is preserved.
7990

8091

@@ -92,8 +103,8 @@ protocol, so all expected methods of iteration are supported::
92103
Iterating on ``frozendict``, as on ``dict``, uses the insertion order.
93104

94105

95-
Hashing
96-
-------
106+
Hashing and Comparison
107+
----------------------
97108

98109
``frozendict`` instances can be hashable just like tuple objects::
99110

@@ -114,6 +125,64 @@ Equality test does not depend on the items' order either. Example::
114125
>>> a == b
115126
True
116127

128+
It's possible to compare ``frozendict`` to ``dict``. Example::
129+
130+
>>> frozendict(x=1, y=2) == dict(x=1, y=2)
131+
True
132+
133+
134+
Union operators
135+
---------------
136+
137+
It's possible to join two ``frozendict``, or a ``frozendict`` with a
138+
``dict``, with the merge (``|``) operator. Example::
139+
140+
>>> frozendict(x=1) | frozendict(y=1)
141+
frozendict({'x': 1, 'y': 1})
142+
>>> frozendict(x=1) | dict(y=1)
143+
frozendict({'x': 1, 'y': 1})
144+
145+
If some keys are in common, the values of the right operand are taken::
146+
147+
>>> frozendict(x=1, y=2) | frozendict(y=5)
148+
frozendict({'x': 1, 'y': 5})
149+
150+
The update operator ``|=`` does not modify a ``frozendict`` in-place, but
151+
creates a new ``frozendict``::
152+
153+
>>> d = frozendict(x=1)
154+
>>> copy = d
155+
>>> d |= frozendict(y=2)
156+
>>> d
157+
frozendict({'x': 1, 'y': 2})
158+
>>> copy # left unchanged
159+
frozendict({'x': 1})
160+
161+
See also :pep:`584` "Add Union Operators To dict".
162+
163+
164+
Copy
165+
----
166+
167+
``frozencopy.copy()`` returns a shallow copy. In CPython, it simply
168+
returns the same ``frozendict`` (new reference).
169+
170+
Use ``copy.deepcopy()`` to get a deep copy.
171+
172+
Example::
173+
174+
>>> import copy
175+
>>> d = frozendict(mutable=[])
176+
>>> shallow_copy = d.copy()
177+
>>> deep_copy = copy.deepcopy(d)
178+
>>> d['mutable'].append('modified')
179+
>>> d
180+
frozendict({'mutable': ['modified']})
181+
>>> shallow_copy # modified!
182+
frozendict({'mutable': ['modified']})
183+
>>> deep_copy # unchanged
184+
frozendict({'mutable': []})
185+
117186

118187
Typing
119188
------
@@ -138,10 +207,12 @@ C API
138207

139208
Add the following APIs:
140209

141-
* ``PyFrozenDict_Type``
142-
* ``PyFrozenDict_New(collection)`` function
210+
* ``PyAnyDict_Check(op)`` macro
211+
* ``PyAnyDict_CheckExact(op)`` macro
143212
* ``PyFrozenDict_Check()`` macro
144213
* ``PyFrozenDict_CheckExact()`` macro
214+
* ``PyFrozenDict_New(collection)`` function
215+
* ``PyFrozenDict_Type``
145216

146217
Even if ``frozendict`` is not a ``dict`` subclass, it can be used with
147218
``PyDict_GetItemRef()`` and similar "PyDict_Get" functions.
@@ -269,12 +340,10 @@ Relationship to PEP 603 frozenmap
269340
* ``excluding(key)``
270341
* ``union(mapping=None, **kw)``
271342

272-
========== ============== ==============
273-
Complexity ``frozenmap`` ``frozendict``
274-
========== ============== ==============
275-
Lookup *O*\ (log *n*) *O*\ (1)
276-
Copy *O*\ (1) *O*\ (*n*)
277-
========== ============== ==============
343+
These methods to mutate a ``frozenmap`` have a complexity of *O*\ (1).
344+
345+
* A mapping lookup (``mapping[key]``) has a complexity of *O*\ (log *n*)
346+
with ``frozenmap`` and a complexity of *O*\ (1) with ``frozendict``.
278347

279348

280349
Reference Implementation

0 commit comments

Comments
 (0)