nodes: 0, module; 1, function_definition; 2, function_name:_resolve_datacenter; 3, parameters; 4, block; 5, identifier:dc; 6, identifier:pillarenv; 7, expression_statement; 8, expression_statement; 9, try_statement; 10, expression_statement; 11, expression_statement; 12, comment:# sort in reverse based on pattern length; 13, comment:# but use alphabetic order within groups of patterns of same length; 14, expression_statement; 15, for_statement; 16, expression_statement; 17, string; 18, call; 19, block; 20, except_clause; 21, call; 22, call; 23, assignment; 24, pattern_list; 25, identifier:sorted_mappings; 26, block; 27, call; 28, string_content:If ``dc`` is a string - return it as is.
  
      If it's a dict then sort it in descending order by key length and try
      to use keys as RegEx patterns to match against ``pillarenv``.
      The value for matched pattern should be a string (that can use
      ``str.format`` syntax togetehr with captured variables from pattern)
      pointing to targe data center to use.
  
      If none patterns matched return ``None`` which meanse us datacenter of
      conencted Consul agent.; 29, attribute; 30, argument_list; 31, expression_statement; 32, comment:# is it a dict?; 33, identifier:AttributeError; 34, block; 35, attribute; 36, argument_list; 37, attribute; 38, argument_list; 39, identifier:sorted_mappings; 40, call; 41, identifier:pattern; 42, identifier:target; 43, expression_statement; 44, if_statement; 45, attribute; 46, argument_list; 47, identifier:log; 48, identifier:debug; 49, string; 50, identifier:dc; 51, assignment; 52, expression_statement; 53, return_statement; 54, identifier:log; 55, identifier:debug; 56, string; 57, call; 58, identifier:log; 59, identifier:debug; 60, string; 61, identifier:pillarenv; 62, identifier:sorted; 63, argument_list; 64, assignment; 65, identifier:match; 66, block; 67, identifier:log; 68, identifier:debug; 69, string; 70, identifier:pillarenv; 71, call; 72, string_content:Resolving Consul datacenter based on: %s; 73, identifier:mappings; 74, call; 75, call; 76, identifier:dc; 77, string_content:Selecting DC based on pillarenv using %d pattern(s); 78, identifier:len; 79, argument_list; 80, string_content; 81, identifier:mappings; 82, keyword_argument; 83, identifier:match; 84, call; 85, expression_statement; 86, expression_statement; 87, expression_statement; 88, return_statement; 89, string_content:None of following patterns matched pillarenv=%s: %s; 90, attribute; 91, generator_expression; 92, attribute; 93, argument_list; 94, attribute; 95, argument_list; 96, identifier:mappings; 97, escape_sequence:\'; 98, escape_sequence:\'; 99, identifier:key; 100, lambda; 101, attribute; 102, argument_list; 103, call; 104, assignment; 105, call; 106, identifier:result; 107, string; 108, identifier:join; 109, call; 110, for_in_clause; 111, identifier:dc; 112, identifier:items; 113, identifier:log; 114, identifier:debug; 115, string; 116, identifier:dc; 117, lambda_parameters; 118, tuple; 119, identifier:re; 120, identifier:match; 121, identifier:pattern; 122, identifier:pillarenv; 123, attribute; 124, argument_list; 125, identifier:result; 126, call; 127, attribute; 128, argument_list; 129, string_content:,; 130, identifier:repr; 131, argument_list; 132, identifier:x; 133, identifier:mappings; 134, string_content; 135, identifier:m; 136, unary_operator; 137, subscript; 138, identifier:log; 139, identifier:debug; 140, string; 141, identifier:pattern; 142, attribute; 143, argument_list; 144, identifier:log; 145, identifier:debug; 146, string; 147, identifier:result; 148, identifier:x; 149, escape_sequence:\'; 150, escape_sequence:\'; 151, call; 152, identifier:m; 153, integer:0; 154, string_content; 155, identifier:target; 156, identifier:format; 157, dictionary_splat; 158, string_content; 159, identifier:len; 160, argument_list; 161, escape_sequence:\'; 162, escape_sequence:\'; 163, call; 164, escape_sequence:\'; 165, escape_sequence:\'; 166, subscript; 167, attribute; 168, argument_list; 169, identifier:m; 170, integer:0; 171, identifier:match; 172, identifier:groupdict
code: def _resolve_datacenter(dc, pillarenv):
      '''
      If ``dc`` is a string - return it as is.
  
      If it's a dict then sort it in descending order by key length and try
      to use keys as RegEx patterns to match against ``pillarenv``.
      The value for matched pattern should be a string (that can use
      ``str.format`` syntax togetehr with captured variables from pattern)
      pointing to targe data center to use.
  
      If none patterns matched return ``None`` which meanse us datacenter of
      conencted Consul agent.
      '''
      log.debug('Resolving Consul datacenter based on: %s', dc)
  
      try:
          mappings = dc.items()  # is it a dict?
      except AttributeError:
          log.debug('Using pre-defined DC: \'%s\'', dc)
          return dc
  
      log.debug('Selecting DC based on pillarenv using %d pattern(s)', len(mappings))
      log.debug('Pillarenv set to \'%s\'', pillarenv)
  
      # sort in reverse based on pattern length
      # but use alphabetic order within groups of patterns of same length
      sorted_mappings = sorted(mappings, key=lambda m: (-len(m[0]), m[0]))
  
      for pattern, target in sorted_mappings:
          match = re.match(pattern, pillarenv)
          if match:
              log.debug('Matched pattern: \'%s\'', pattern)
              result = target.format(**match.groupdict())
              log.debug('Resolved datacenter: \'%s\'', result)
              return result
  
      log.debug(
          'None of following patterns matched pillarenv=%s: %s',
          pillarenv, ', '.join(repr(x) for x in mappings)
      )