def _attribute_matcher(kwargs):
 def match(node):
  if ('terminal' in kwargs):
   kwa_copy = kwargs.copy()
   pattern = kwa_copy.pop('terminal')
   if ((pattern is not None) and ((not hasattr(node, 'is_terminal')) or (node.is_terminal() != pattern))):
    return False
  else:
   kwa_copy = kwargs
  for (key, pattern) in kwa_copy.items():
   if (not hasattr(node, key)):
    return False
   target = getattr(node, key)
   if isinstance(pattern, basestring):
    return (isinstance(target, basestring) and re.match((pattern + '$'), target))
   if isinstance(pattern, bool):
    return (pattern == bool(target))
   if isinstance(pattern, int):
    return (pattern == target)
   if (pattern is None):
    return (target is None)
   raise TypeError(('invalid query type: %s' % type(pattern)))
  return True
 return match

def _attribute_matcher ( kwargs ) : def match ( node ) : if ( 'terminal' in kwargs ) : kwa_copy = kwargs . copy ( ) pattern = kwa_copy . pop ( 'terminal' ) if ( ( pattern is not None ) and ( ( not hasattr ( node , 'is_terminal' ) ) or ( node . is_terminal ( ) != pattern ) ) ) : return False else : kwa_copy = kwargs for ( key , pattern ) in kwa_copy . items ( ) : if ( not hasattr ( node , key ) ) : return False target = getattr ( node , key ) if isinstance ( pattern , basestring ) : return ( isinstance ( target , basestring ) and re . match ( ( pattern + '$' ) , target ) ) if isinstance ( pattern , bool ) : return ( pattern == bool ( target ) ) if isinstance ( pattern , int ) : return ( pattern == target ) if ( pattern is None ) : return ( target is None ) raise TypeError ( ( 'invalid query type: %s' % type ( pattern ) ) ) return True return match
match a node by specified attribute values .