@@ -416,6 +416,8 @@ def items(self):
416
416
class ConfigurationView (AttributeDictMixin ):
417
417
"""A view over an applications configuration dicts.
418
418
419
+ Custom (but older) version of :class:`collections.ChainMap`.
420
+
419
421
If the key does not exist in ``changes``, the ``defaults`` dicts
420
422
are consulted.
421
423
@@ -457,6 +459,10 @@ def get(self, key, default=None):
457
459
except KeyError :
458
460
return default
459
461
462
+ def clear (self ):
463
+ """Removes all changes, but keeps defaults."""
464
+ self .changes .clear ()
465
+
460
466
def setdefault (self , key , default ):
461
467
try :
462
468
return self [key ]
@@ -468,10 +474,10 @@ def update(self, *args, **kwargs):
468
474
return self .changes .update (* args , ** kwargs )
469
475
470
476
def __contains__ (self , key ):
471
- for d in self ._order :
472
- if key in d :
473
- return True
474
- return False
477
+ return any ( key in m for m in self ._order )
478
+
479
+ def __bool__ ( self ):
480
+ return any ( self . _order )
475
481
476
482
def __repr__ (self ):
477
483
return repr (dict (items (self )))
@@ -482,7 +488,7 @@ def __iter__(self):
482
488
def __len__ (self ):
483
489
# The logic for iterating keys includes uniq(),
484
490
# so to be safe we count by explicitly iterating
485
- return len (self . keys ( ))
491
+ return len (set (). union ( * self . _order ))
486
492
487
493
def _iter (self , op ):
488
494
# defaults must be first in the stream, so values in
0 commit comments