def _consolidate_faux_containers(parser): container_spec = re.compile("^.+?\[.+?\]$") for section in parser.sections(): containers = {} for name, value in parser.items(section): if container_spec.match(name) is not None: container_name, item_key_or_index = name[:-1].split('[') if invoke.try_except( lambda: parser.get(section, container_name)): # An option exists for container_name, so container can not be added to section containers[container_name] = None continue container_options_pair = containers.setdefault( container_name, (dict(), list())) if container_options_pair is not None: container = container_options_pair[0] if item_key_or_index in container: # duplicate key/index found, not a valid container so stop processing it containers[container_name] = None continue container[item_key_or_index] = value container_options_pair[1].append(name) options_to_remove = [] # TODO add support for keyed containers as well as indexed containers. for container_name, container_options_pair in containers.iteritems(): if container_options_pair is None: continue container = container_options_pair[0] index_min = sys.maxint index_max = -1 index_count = 0 for key_or_index in container.iterkeys(): try: index = int(key_or_index) except: # Keys not indexes container = None break if index >= sys.maxint: # Index to large, treat as keys container = None break if index < index_min: index_min = index if index > index_max: index_max = index index_count += 1 else: # indexes need to be contiguous, starting at 0 if index_max >= 0 and index_max - index_min + 1 == index_count: items_to_sort = container.items() items_to_sort.sort() container = [value for index, value in items_to_sort] if container is None: continue parser.set(section, container_name, container) options_to_remove.extend(container_options_pair[1]) for toremove in options_to_remove: parser.remove_option(section, toremove)
def _consolidate_faux_containers(parser): container_spec=re.compile("^.+?\[.+?\]$") for section in parser.sections(): containers = {} for name, value in parser.items(section): if container_spec.match(name) is not None: container_name, item_key_or_index = name[:-1].split('[') if invoke.try_except(lambda: parser.get(section, container_name)): # An option exists for container_name, so container can not be added to section containers[container_name] = None continue container_options_pair = containers.setdefault(container_name, (dict(), list())) if container_options_pair is not None: container = container_options_pair[0] if item_key_or_index in container: # duplicate key/index found, not a valid container so stop processing it containers[container_name] = None continue container[item_key_or_index] = value container_options_pair[1].append(name) options_to_remove = [] # TODO add support for keyed containers as well as indexed containers. for container_name, container_options_pair in containers.iteritems(): if container_options_pair is None: continue container = container_options_pair[0] index_min = sys.maxint index_max = -1 index_count = 0 for key_or_index in container.iterkeys(): try: index = int(key_or_index) except: # Keys not indexes container = None break if index >= sys.maxint: # Index to large, treat as keys container = None break if index < index_min: index_min = index if index > index_max: index_max = index index_count += 1 else: # indexes need to be contiguous, starting at 0 if index_max >= 0 and index_max-index_min+1 == index_count: items_to_sort = container.items() items_to_sort.sort() container = [value for index, value in items_to_sort] if container is None: continue parser.set(section, container_name, container) options_to_remove.extend(container_options_pair[1]) for toremove in options_to_remove: parser.remove_option(section, toremove)
def _has_subkey(get_subkey, subkey): return invoke.try_except(lambda: get_subkey(subkey))