Skip to content

Commit 650ae22

Browse files
committed
Implement MultiDict.update method
1 parent cd7fe2b commit 650ae22

File tree

2 files changed

+48
-21
lines changed

2 files changed

+48
-21
lines changed

aiohttp/_multidict.pyx

Lines changed: 35 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -195,9 +195,9 @@ cdef class MultiDict(_Base):
195195
def __init__(self, *args, **kwargs):
196196
self._items = []
197197

198-
self._extend(args, kwargs, self.__class__.__name__)
198+
self._extend(args, kwargs, self.__class__.__name__, 1)
199199

200-
cdef _extend(self, tuple args, dict kwargs, name):
200+
cdef _extend(self, tuple args, dict kwargs, name, int do_add):
201201
cdef tuple item
202202

203203
if len(args) > 1:
@@ -207,30 +207,45 @@ cdef class MultiDict(_Base):
207207
if args:
208208
if hasattr(args[0], 'items'):
209209
for item in args[0].items():
210-
self._add(item)
210+
key, value = item
211+
key = self._upper(key)
212+
if do_add:
213+
self._add(key, value)
214+
else:
215+
self._replace(key, value)
211216
else:
212217
for arg in args[0]:
213218
if not len(arg) == 2:
214219
raise TypeError(
215220
"{} takes either dict or list of (key, value) "
216221
"tuples".format(name))
217-
if not isinstance(arg, tuple):
218-
item = tuple(arg)
222+
key, value = arg
223+
key = self._upper(key)
224+
if do_add:
225+
self._add(key, value)
219226
else:
220-
item = arg
221-
self._add(item)
227+
self._replace(key, value)
228+
229+
230+
for key, value in kwargs.items():
231+
key = self._upper(key)
232+
if do_add:
233+
self._add(key, value)
234+
else:
235+
self._replace(key, value)
222236

223-
for item in kwargs.items():
224-
self._add(item)
237+
cdef _add(self, key, value):
238+
self._items.append((key, value))
225239

226-
cdef _add(self, tuple item):
227-
self._items.append((self._upper(item[0]), item[1]))
240+
cdef _replace(self, key, value):
241+
self._remove(key, 0)
242+
self._items.append((key, value))
228243

229244
def add(self, key, value):
230245
"""
231246
Add the key and value, not overwriting any previous value.
232247
"""
233-
self._add((key, value))
248+
self._add(self._upper(key), value)
234249

235250
def copy(self):
236251
"""Returns a copy itself."""
@@ -242,7 +257,7 @@ cdef class MultiDict(_Base):
242257
243258
This method must be used instead of update.
244259
"""
245-
self._extend(args, kwargs, "extend")
260+
self._extend(args, kwargs, "extend", 1)
246261

247262
def clear(self):
248263
"""Remove all items from MultiDict"""
@@ -252,14 +267,14 @@ cdef class MultiDict(_Base):
252267

253268
def __setitem__(self, key, value):
254269
key = self._upper(key)
255-
self._delitem(key, False)
256-
self._add((key, value))
270+
self._remove(key, False)
271+
self._add(key, value)
257272

258273
def __delitem__(self, key):
259274
key = self._upper(key)
260-
self._delitem(key, True)
275+
self._remove(key, True)
261276

262-
cdef _delitem(self, key, int raise_key_error):
277+
cdef _remove(self, key, int raise_key_error):
263278
cdef int found
264279
found = False
265280
for i in range(len(self._items) - 1, -1, -1):
@@ -274,7 +289,7 @@ cdef class MultiDict(_Base):
274289
for k, v in self._items:
275290
if k == key:
276291
return v
277-
self._add((key, default))
292+
self._add(key, default)
278293
return default
279294

280295
def pop(self, key, default=_marker):
@@ -302,9 +317,8 @@ cdef class MultiDict(_Base):
302317
else:
303318
raise KeyError("empty multidict")
304319

305-
def update(self, *args, **kw):
306-
"""Method not allowed."""
307-
raise NotImplementedError("Use extend method instead")
320+
def update(self, *args, **kwargs):
321+
self._extend(args, kwargs, "update", 0)
308322

309323
def __richcmp__(self, other, op):
310324
cdef MultiDict typed_self = self

docs/multidict.rst

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,19 @@ MutableMultiDict
187187
If not, insert *key* with a value of *default* and return *default*.
188188
*default* defaults to ``None``.
189189

190+
.. method:: update([other])
191+
192+
Update the dictionary with the key/value pairs from *other*,
193+
overwriting existing keys.
194+
195+
Return ``None``.
196+
197+
:meth:`update` accepts either another dictionary object or an
198+
iterable of key/value pairs (as tuples or other iterables
199+
of length two). If keyword arguments are specified, the
200+
dictionary is then updated with those key/value pairs:
201+
``d.update(red=1, blue=2)``.
202+
190203

191204
CIMultiDict
192205
-----------

0 commit comments

Comments
 (0)