@@ -34,6 +34,9 @@ cdef class _Base:
34
34
def __cinit__ (self ):
35
35
self ._upstr = upstr
36
36
37
+ cdef _upper(self , key):
38
+ return key
39
+
37
40
def getall (self , key , default = _marker):
38
41
"""
39
42
Return a list of all values matching the key (may be an empty list)
@@ -42,6 +45,7 @@ cdef class _Base:
42
45
43
46
cdef _getall(self , key, default):
44
47
cdef list res
48
+ key = self ._upper(key)
45
49
res = [v for k, v in self ._items if k == key]
46
50
if res:
47
51
return res
@@ -57,6 +61,7 @@ cdef class _Base:
57
61
58
62
cdef _getone(self , key, default):
59
63
cdef tuple item
64
+ key = self ._upper(key)
60
65
for item in self ._items:
61
66
if item[0 ] == key:
62
67
return item[1 ]
@@ -77,6 +82,7 @@ cdef class _Base:
77
82
78
83
cdef _contains(self , key):
79
84
cdef tuple item
85
+ key = self ._upper(key)
80
86
for item in self ._items:
81
87
if item[0 ] == key:
82
88
return True
@@ -88,23 +94,14 @@ cdef class _Base:
88
94
def __len__ (self ):
89
95
return len (self ._items)
90
96
91
- def keys (self , *, getall = True ):
92
- return self ._keys_view(getall)
93
-
94
- cdef _KeysView _keys_view(self , getall):
95
- return _KeysView.__new__ (_KeysView, self ._items, getall)
96
-
97
- def items (self , *, getall = True ):
98
- return self ._items_view(getall)
97
+ def keys (self ):
98
+ return _KeysView.__new__ (_KeysView, self ._items)
99
99
100
- cdef _ItemsView _items_view (self , getall ):
101
- return _ItemsView.__new__ (_ItemsView, self ._items, getall )
100
+ def items (self ):
101
+ return _ItemsView.__new__ (_ItemsView, self ._items)
102
102
103
- def values (self , *, getall = True ):
104
- return self ._values_view(getall)
105
-
106
- cdef _ValuesView _values_view(self , getall):
107
- return _ValuesView.__new__ (_ValuesView, self ._items, getall)
103
+ def values (self ):
104
+ return _ValuesView.__new__ (_ValuesView, self ._items)
108
105
109
106
def __repr__ (self ):
110
107
body = ' , ' .join(" '{}': {!r}" .format(k, v) for k, v in self .items())
@@ -188,21 +185,6 @@ cdef class CIMultiDictProxy(MultiDictProxy):
188
185
def copy (self ):
189
186
return CIMultiDict(self ._items)
190
187
191
- def getall (self , key , default = _marker):
192
- return self ._getall(self ._upper(key), default)
193
-
194
- def getone (self , key , default = _marker):
195
- return self ._getone(self ._upper(key), default)
196
-
197
- def get (self , key , default = None ):
198
- return self ._getone(self ._upper(key), default)
199
-
200
- def __getitem__ (self , key ):
201
- return self ._getone(self ._upper(key), _marker)
202
-
203
- def __contains__ (self , key ):
204
- return self ._contains(self ._upper(key))
205
-
206
188
207
189
abc.Mapping.register(CIMultiDictProxy)
208
190
@@ -213,9 +195,9 @@ cdef class MultiDict(_Base):
213
195
def __init__ (self , *args , **kwargs ):
214
196
self ._items = []
215
197
216
- self ._extend(args, kwargs, self .__class__.__name__ )
198
+ self ._extend(args, kwargs, self .__class__.__name__ , 1 )
217
199
218
- cdef _extend(self , tuple args, dict kwargs, name):
200
+ cdef _extend(self , tuple args, dict kwargs, name, int do_add ):
219
201
cdef tuple item
220
202
221
203
if len (args) > 1 :
@@ -225,30 +207,45 @@ cdef class MultiDict(_Base):
225
207
if args:
226
208
if hasattr (args[0 ], ' items' ):
227
209
for item in args[0 ].items():
228
- 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)
229
216
else :
230
217
for arg in args[0 ]:
231
218
if not len (arg) == 2 :
232
219
raise TypeError (
233
220
" {} takes either dict or list of (key, value) "
234
221
" tuples" .format(name))
235
- if not isinstance (arg, tuple ):
236
- item = tuple (arg)
222
+ key, value = arg
223
+ key = self ._upper(key)
224
+ if do_add:
225
+ self ._add(key, value)
237
226
else :
238
- item = arg
239
- 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)
240
236
241
- for item in kwargs.items( ):
242
- self ._add(item )
237
+ cdef _add( self , key, value ):
238
+ self ._items.append((key, value) )
243
239
244
- cdef _add(self , tuple item):
245
- self ._items.append(item)
240
+ cdef _replace(self , key, value):
241
+ self ._remove(key, 0 )
242
+ self ._items.append((key, value))
246
243
247
244
def add (self , key , value ):
248
245
"""
249
246
Add the key and value, not overwriting any previous value.
250
247
"""
251
- self ._add((key, value) )
248
+ self ._add(self ._upper (key) , value)
252
249
253
250
def copy (self ):
254
251
""" Returns a copy itself."""
@@ -260,7 +257,7 @@ cdef class MultiDict(_Base):
260
257
261
258
This method must be used instead of update.
262
259
"""
263
- self ._extend(args, kwargs, " extend" )
260
+ self ._extend(args, kwargs, " extend" , 1 )
264
261
265
262
def clear (self ):
266
263
""" Remove all items from MultiDict"""
@@ -269,13 +266,15 @@ cdef class MultiDict(_Base):
269
266
# MutableMapping interface #
270
267
271
268
def __setitem__ (self , key , value ):
272
- self ._delitem(key, False )
273
- self ._add((key, value))
269
+ key = self ._upper(key)
270
+ self ._remove(key, False )
271
+ self ._add(key, value)
274
272
275
273
def __delitem__ (self , key ):
276
- self ._delitem(key, True )
274
+ key = self ._upper(key)
275
+ self ._remove(key, True )
277
276
278
- cdef _delitem (self , key, int raise_key_error):
277
+ cdef _remove (self , key, int raise_key_error):
279
278
cdef int found
280
279
found = False
281
280
for i in range (len (self ._items) - 1 , - 1 , - 1 ):
@@ -286,15 +285,17 @@ cdef class MultiDict(_Base):
286
285
raise KeyError (key)
287
286
288
287
def setdefault (self , key , default = None ):
288
+ key = self ._upper(key)
289
289
for k, v in self ._items:
290
290
if k == key:
291
291
return v
292
- self ._add(( key, default) )
292
+ self ._add(key, default)
293
293
return default
294
294
295
295
def pop (self , key , default = _marker):
296
296
cdef int found
297
297
cdef object value
298
+ key = self ._upper(key)
298
299
value = None
299
300
found = False
300
301
for i in range (len (self ._items) - 1 , - 1 , - 1 ):
@@ -310,18 +311,14 @@ cdef class MultiDict(_Base):
310
311
else :
311
312
return value
312
313
313
- """ Method not allowed."""
314
- raise NotImplementedError
315
-
316
314
def popitem (self ):
317
315
if self ._items:
318
316
return self ._items.pop(0 )
319
317
else :
320
318
raise KeyError (" empty multidict" )
321
319
322
- def update (self , *args , **kw ):
323
- """ Method not allowed."""
324
- raise NotImplementedError (" Use extend method instead" )
320
+ def update (self , *args , **kwargs ):
321
+ self ._extend(args, kwargs, " update" , 0 )
325
322
326
323
def __richcmp__ (self , other , op ):
327
324
cdef MultiDict typed_self = self
@@ -360,75 +357,11 @@ abc.MutableMapping.register(MultiDict)
360
357
cdef class CIMultiDict(MultiDict):
361
358
""" An ordered dictionary that can have multiple values for each key."""
362
359
363
- cdef _add(self , tuple item):
364
- self ._items.append((self ._upper(item[0 ]), item[1 ]))
365
-
366
360
cdef _upper(self , s):
367
361
if type (s) is self ._upstr:
368
362
return s
369
363
return s.upper()
370
364
371
- def getall (self , key , default = _marker):
372
- return self ._getall(self ._upper(key), default)
373
-
374
- def getone (self , key , default = _marker):
375
- return self ._getone(self ._upper(key), default)
376
-
377
- def get (self , key , default = None ):
378
- return self ._getone(self ._upper(key), default)
379
-
380
- def __getitem__ (self , key ):
381
- return self ._getone(self ._upper(key), _marker)
382
-
383
- def __contains__ (self , key ):
384
- return self ._contains(self ._upper(key))
385
-
386
- def add (self , key , value ):
387
- """
388
- Add the key and value, not overwriting any previous value.
389
- """
390
- self ._add((key, value))
391
-
392
- def extend (self , *args , **kwargs ):
393
- """ Extends current MultiDict with more values.
394
-
395
- This method must be used instead of update.
396
- """
397
- self ._extend(args, kwargs, " extend" )
398
-
399
- def clear (self ):
400
- """ Remove all items from MultiDict"""
401
- self ._items = []
402
-
403
- # MutableMapping interface #
404
-
405
- def __setitem__ (self , key , value ):
406
- key = self ._upper(key)
407
- self ._delitem(key, False )
408
- self ._add((key, value))
409
-
410
- def __delitem__ (self , key ):
411
- self ._delitem(self ._upper(key), True )
412
-
413
- def setdefault (self , key , default = None ):
414
- key = self ._upper(key)
415
- for k, v in self ._items:
416
- if k == key:
417
- return v
418
- self ._add((key, default))
419
- return default
420
-
421
- def pop (self , key , default = None ):
422
- """ Method not allowed."""
423
- raise NotImplementedError
424
-
425
- def popitem (self ):
426
- """ Method not allowed."""
427
- raise NotImplementedError
428
-
429
- def update (self , *args , **kw ):
430
- """ Method not allowed."""
431
- raise NotImplementedError (" Use extend method instead" )
432
365
433
366
434
367
abc.MutableMapping.register(CIMultiDict)
@@ -439,24 +372,8 @@ cdef class _ViewBase:
439
372
cdef list _keys
440
373
cdef list _items
441
374
442
- def __cinit__ (self , list items , int getall ):
443
- cdef list items_to_use
444
- cdef set keys
445
-
446
- if getall:
447
- self ._items = items
448
- self ._keys = [item[0 ] for item in items]
449
- else :
450
- self ._items = []
451
- keys = set ()
452
- self ._keys = []
453
- for i in items:
454
- key = i[0 ]
455
- if key in keys:
456
- continue
457
- keys.add(key)
458
- self ._keys.append(key)
459
- self ._items.append(i)
375
+ def __cinit__ (self , list items ):
376
+ self ._items = items
460
377
461
378
def __len__ (self ):
462
379
return len (self ._items)
@@ -549,12 +466,14 @@ abc.ItemsView.register(_ItemsView)
549
466
cdef class _ValuesView(_ViewBase):
550
467
551
468
def __contains__ (self , value ):
469
+ cdef tuple item
552
470
for item in self ._items:
553
471
if item[1 ] == value:
554
472
return True
555
473
return False
556
474
557
475
def __iter__ (self ):
476
+ cdef tuple item
558
477
for item in self ._items:
559
478
yield item[1 ]
560
479
@@ -566,16 +485,23 @@ cdef class _KeysView(_ViewBaseSet):
566
485
567
486
def isdisjoint (self , other ):
568
487
' Return True if two sets have a null intersection.'
569
- for key in self ._keys:
570
- if key in other:
488
+ cdef tuple item
489
+ for item in self ._items:
490
+ if item[0 ] in other:
571
491
return False
572
492
return True
573
493
574
- def __contains__ (self , key ):
575
- return key in self ._keys
494
+ def __contains__ (self , value ):
495
+ cdef tuple item
496
+ for item in self ._items:
497
+ if item[0 ] == value:
498
+ return True
499
+ return False
576
500
577
501
def __iter__ (self ):
578
- return iter (self ._keys)
502
+ cdef tuple item
503
+ for item in self ._items:
504
+ yield item[0 ]
579
505
580
506
581
507
abc.KeysView.register(_KeysView)
0 commit comments