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))