<s> import collections <EOL> from . . import Matcher , default_matcher <EOL> from ... texts import plain_enumerate <EOL> class _DictMatcher ( Matcher ) : <EOL> def _match ( self , subject ) : <EOL> if self . _not_a_dict ( subject ) : <EOL> return False , [ '<STR_LIT>' ] <EOL> return self . _matches ( subject ) <EOL> def _not_a_dict ( self , value ) : <EOL> return not isinstance ( value , collections . Mapping ) <EOL> def _matches ( self , subject ) : <EOL> args , kwargs = self . _expected <EOL> reasons = [ ] <EOL> for name in args : <EOL> has_key , reason = self . _has_key ( subject , name ) <EOL> if not has_key : <EOL> return False , [ reason ] <EOL> else : <EOL> reasons . append ( reason ) <EOL> for name , value in kwargs . items ( ) : <EOL> has_key , reason = self . _has_key ( subject , name , value ) <EOL> if not has_key : <EOL> return False , [ reason ] <EOL> else : <EOL> reasons . append ( reason ) <EOL> return True , reasons <EOL> def _has_key ( self , subject , name , * args ) : <EOL> if args : <EOL> expected_value = default_matcher ( args [ <NUM_LIT:0> ] ) <EOL> try : <EOL> value = subject [ name ] <EOL> except KeyError : <EOL> return False , '<STR_LIT>' . format ( name , expected_value ) <EOL> else : <EOL> result , _ = expected_value . _match ( value ) <EOL> reason_message = '<STR_LIT>' if not result else '<STR_LIT>' <EOL> return result , '<STR_LIT>' . format ( name , expected_value , reason_message ) <EOL> if name in subject : <EOL> return True , '<STR_LIT>' . format ( name ) <EOL> return False , '<STR_LIT>' . format ( name ) <EOL> def _match_negated ( self , subject ) : <EOL> if self . _not_a_dict ( subject ) : <EOL> return False , [ '<STR_LIT>' ] <EOL> result , description = self . _matches ( subject ) <EOL> return not result , description <EOL> def __repr__ ( self ) : <EOL> return '<STR_LIT>' . format ( type ( self ) . __name__ . replace ( '<STR_LIT:_>' , '<STR_LIT:U+0020>' ) , <EOL> plain_enumerate ( * self . _expected ) ) <EOL> class have_keys ( _DictMatcher ) : <EOL> def __init__ ( self , * args , ** kwargs ) : <EOL> try : <EOL> self . _expected = ( ) , dict ( * args , ** kwargs ) <EOL> except ( TypeError , ValueError ) : <EOL> self . _expected = args , kwargs <EOL> class have_key ( _DictMatcher ) : <EOL> def __init__ ( self , name , * args ) : <EOL> if args : <EOL> self . _expected = ( ) , { name : args [ <NUM_LIT:0> ] } <EOL> else : <EOL> self . _expected = ( name , ) , { } </s>
