0
# Mutable Multidict Operations
1
2
The `MultiDict` class provides the core mutable multidict functionality with case-sensitive key handling. It maintains insertion order and allows multiple values per key while providing both dict-like access patterns and specialized multidict methods.
3
4
## Capabilities
5
6
### Construction
7
8
Create multidict instances from various data sources with flexible initialization patterns.
9
10
```python { .api }
11
class MultiDict(MutableMultiMapping[_V]):
12
def __init__(self, arg: MDArg[_V] = None, /, **kwargs: _V):
13
"""
14
Create a mutable multidict.
15
16
Parameters:
17
- arg: Mapping, iterable of key-value pairs, or None
18
- **kwargs: Additional key-value pairs
19
20
Examples:
21
MultiDict() # Empty
22
MultiDict([('key', 'value1'), ('key', 'value2')]) # From pairs
23
MultiDict({'key': 'value'}) # From dict
24
MultiDict(key='value') # From kwargs
25
"""
26
```
27
28
Usage examples:
29
30
```python
31
# Empty multidict
32
md = MultiDict()
33
34
# From list of tuples (preserves duplicates)
35
headers = MultiDict([
36
('Accept', 'text/html'),
37
('Accept', 'application/json'),
38
('Cache-Control', 'no-cache')
39
])
40
41
# From dictionary (single values)
42
params = MultiDict({'page': '1', 'size': '10'})
43
44
# From keyword arguments
45
cookies = MultiDict(session='abc123', theme='dark')
46
47
# Mixed initialization
48
data = MultiDict([('tags', 'python')], tags='web', priority='high')
49
```
50
51
### Adding Values
52
53
Add new key-value pairs to the multidict without replacing existing values.
54
55
```python { .api }
56
def add(self, key: str, value: _V) -> None:
57
"""
58
Append a key-value pair to the multidict.
59
60
Parameters:
61
- key: The key to add
62
- value: The value to add
63
64
Does not replace existing values for the same key.
65
"""
66
```
67
68
Usage examples:
69
70
```python
71
headers = MultiDict()
72
headers.add('Accept', 'text/html')
73
headers.add('Accept', 'application/json') # Now has two Accept values
74
headers.add('User-Agent', 'MyApp/1.0')
75
76
print(headers.getall('Accept')) # ['text/html', 'application/json']
77
```
78
79
### Retrieving Values
80
81
Access values using various retrieval methods for different use cases.
82
83
```python { .api }
84
def __getitem__(self, key: str) -> _V:
85
"""Get the first value for key. Raises KeyError if not found."""
86
87
def get(self, key: str, default: Optional[_T] = None) -> Union[_V, _T, None]:
88
"""Get the first value for key, return default if not found."""
89
90
def getone(self, key: str, default: _T = ...) -> Union[_V, _T]:
91
"""
92
Get the first value for key.
93
94
Parameters:
95
- key: The key to retrieve
96
- default: Value to return if key not found
97
98
Returns:
99
First value for the key, or default if not found
100
101
Raises:
102
KeyError if key not found and no default provided
103
"""
104
105
def getall(self, key: str, default: _T = ...) -> Union[List[_V], _T]:
106
"""
107
Get all values for key as a list.
108
109
Parameters:
110
- key: The key to retrieve
111
- default: Value to return if key not found
112
113
Returns:
114
List of all values for the key, or default if not found
115
116
Raises:
117
KeyError if key not found and no default provided
118
"""
119
```
120
121
Usage examples:
122
123
```python
124
headers = MultiDict([
125
('Accept', 'text/html'),
126
('Accept', 'application/json'),
127
('User-Agent', 'MyApp/1.0')
128
])
129
130
# Get first value (dict-like)
131
print(headers['Accept']) # 'text/html'
132
print(headers.get('Accept')) # 'text/html'
133
print(headers.getone('Accept')) # 'text/html'
134
135
# Get all values
136
print(headers.getall('Accept')) # ['text/html', 'application/json']
137
138
# Safe access with defaults
139
print(headers.get('Authorization', 'None')) # 'None'
140
print(headers.getall('Authorization', [])) # []
141
```
142
143
### Modifying Values
144
145
Replace, update, or merge values in the multidict.
146
147
```python { .api }
148
def __setitem__(self, key: str, value: _V) -> None:
149
"""Set key to value, replacing all existing values for key."""
150
151
def setdefault(self, key: str, default: _V = None) -> _V:
152
"""
153
Get value for key, or set and return default if key not present.
154
155
Parameters:
156
- key: The key to check/set
157
- default: Value to set if key not present
158
159
Returns:
160
Existing first value or the default value that was set
161
"""
162
163
def update(self, arg: MDArg[_V] = None, /, **kwargs: _V) -> None:
164
"""
165
Update multidict with key-value pairs, replacing existing values.
166
167
Parameters:
168
- arg: Mapping, iterable of pairs, or None
169
- **kwargs: Additional key-value pairs
170
"""
171
172
def extend(self, arg: MDArg[_V] = None, /, **kwargs: _V) -> None:
173
"""
174
Add all key-value pairs from arg and kwargs, preserving existing values.
175
176
Parameters:
177
- arg: Mapping, iterable of pairs, or None
178
- **kwargs: Additional key-value pairs
179
"""
180
181
def merge(self, arg: MDArg[_V] = None, /, **kwargs: _V) -> None:
182
"""
183
Add key-value pairs from arg and kwargs for keys not already present.
184
185
Parameters:
186
- arg: Mapping, iterable of pairs, or None
187
- **kwargs: Additional key-value pairs
188
"""
189
```
190
191
Usage examples:
192
193
```python
194
headers = MultiDict([('Accept', 'text/html'), ('Accept', 'application/json')])
195
196
# Replace all values for a key
197
headers['Accept'] = 'text/plain' # Now only has 'text/plain'
198
199
# Set default value
200
headers.setdefault('User-Agent', 'DefaultAgent/1.0')
201
202
# Update with new values (replaces existing)
203
headers.update([('Accept', 'text/xml')])
204
205
# Extend with additional values
206
headers.extend([('Accept', 'application/json')]) # Now has both values
207
208
# Merge only adds new keys
209
headers.merge({'Authorization': 'Bearer token'}) # Adds if not present
210
```
211
212
### Removing Values
213
214
Remove keys and values using various deletion methods.
215
216
```python { .api }
217
def __delitem__(self, key: str) -> None:
218
"""Remove all values for key. Raises KeyError if not found."""
219
220
def pop(self, key: str) -> _V:
221
"""Remove and return the first value for key. Raises KeyError if not found."""
222
223
def pop(self, key: str, default: _T) -> Union[_V, _T]:
224
"""Remove and return the first value for key, or default if not found."""
225
226
def popone(self, key: str, default: _T = ...) -> Union[_V, _T]:
227
"""
228
Remove and return the first value for key.
229
230
Parameters:
231
- key: The key to remove
232
- default: Value to return if key not found
233
234
Returns:
235
First value that was removed, or default if not found
236
237
Raises:
238
KeyError if key not found and no default provided
239
"""
240
241
def popall(self, key: str, default: _T = ...) -> Union[List[_V], _T]:
242
"""
243
Remove and return all values for key as a list.
244
245
Parameters:
246
- key: The key to remove
247
- default: Value to return if key not found
248
249
Returns:
250
List of all values that were removed, or default if not found
251
252
Raises:
253
KeyError if key not found and no default provided
254
"""
255
256
def popitem(self) -> tuple[str, _V]:
257
"""
258
Remove and return an arbitrary key-value pair.
259
260
Returns:
261
Tuple of (key, value)
262
263
Raises:
264
KeyError if multidict is empty
265
"""
266
267
def clear(self) -> None:
268
"""Remove all key-value pairs from the multidict."""
269
```
270
271
Usage examples:
272
273
```python
274
headers = MultiDict([
275
('Accept', 'text/html'),
276
('Accept', 'application/json'),
277
('User-Agent', 'MyApp/1.0')
278
])
279
280
# Remove all values for a key
281
del headers['User-Agent']
282
283
# Remove and get first value
284
first_accept = headers.popone('Accept') # 'text/html'
285
286
# Remove and get all values
287
remaining_accepts = headers.popall('Accept') # ['application/json']
288
289
# Remove arbitrary item
290
key, value = headers.popitem()
291
292
# Clear all
293
headers.clear()
294
```
295
296
### Collection Operations
297
298
Standard collection methods for iteration, copying, and inspection.
299
300
```python { .api }
301
def __len__(self) -> int:
302
"""Return the number of key-value pairs (not unique keys)."""
303
304
def __iter__(self) -> Iterator[str]:
305
"""Iterate over keys in insertion order."""
306
307
def __contains__(self, key: object) -> bool:
308
"""Check if key is present in the multidict."""
309
310
def keys(self) -> KeysView[str]:
311
"""Return a view of keys."""
312
313
def values(self) -> ValuesView[_V]:
314
"""Return a view of values."""
315
316
def items(self) -> ItemsView[str, _V]:
317
"""Return a view of key-value pairs."""
318
319
def copy(self) -> 'MultiDict[_V]':
320
"""Return a shallow copy of the multidict."""
321
322
def __copy__(self) -> 'MultiDict[_V]':
323
"""Support for copy.copy() - returns a shallow copy."""
324
```
325
326
Usage examples:
327
328
```python
329
headers = MultiDict([
330
('Accept', 'text/html'),
331
('Accept', 'application/json'),
332
('User-Agent', 'MyApp/1.0')
333
])
334
335
# Length is total key-value pairs
336
print(len(headers)) # 3
337
338
# Check key existence
339
print('Accept' in headers) # True
340
print('Authorization' in headers) # False
341
342
# Iterate over keys
343
for key in headers:
344
print(f"{key}: {headers.getall(key)}")
345
346
# Work with views
347
print(list(headers.keys())) # ['Accept', 'Accept', 'User-Agent']
348
print(list(headers.values())) # ['text/html', 'application/json', 'MyApp/1.0']
349
print(list(headers.items())) # [('Accept', 'text/html'), ...]
350
351
# Create a copy
352
headers_copy = headers.copy()
353
354
# View set operations (keys, values, items support set operations)
355
other_headers = MultiDict([('Accept', 'text/html'), ('Content-Type', 'application/json')])
356
357
# Set operations on keys
358
common_keys = headers.keys() & other_headers.keys() # Intersection
359
all_keys = headers.keys() | other_headers.keys() # Union
360
unique_keys = headers.keys() - other_headers.keys() # Difference
361
362
# Set operations on items
363
common_items = headers.items() & other_headers.items()
364
print(list(common_items)) # [('Accept', 'text/html')]
365
```