def render(incfg):
    axes = collections.OrderedDict()

    if incfg.has_section('axes'):
        for axis in incfg.options('axes'):
            axes[axis] = Axis(axis, incfg)

    out = ConfigParser()
    for section in incfg.sections():
        if section == 'axes' or section.startswith('axis:'):
            continue
        out.add_section(section)
        for name, value in incfg.items(section):
            out.set(section, name, value)

    for combination in itertools.product(
            *[axis.items.keys() for axis in axes.values()]):
        options = collections.OrderedDict()

        section_name = (
            'testenv:' + '-'.join([item for item in combination if item])
        )
        section_alt_name = (
            'testenv:' + '-'.join([
                itemname
                for axis, itemname in zip(axes.values(), combination)
                if itemname and not axis.items[itemname].isdefault
            ])
        )
        if section_alt_name == section_name:
            section_alt_name = None

        axes_items = [
            '%s:%s' % (axis, itemname)
            for axis, itemname in zip(axes, combination)
        ]

        for axis, itemname in zip(axes.values(), combination):
            axis_options = axis.items[itemname].options
            if 'constraints' in axis_options:
                constraints = axis_options['constraints'].split('\n')
                for c in constraints:
                    if c.startswith('!') and c[1:] in axes_items:
                        continue
            for name, value in axis_options.items():
                if name in options:
                    options[name] += value
                else:
                    options[name] = value

        constraints = options.pop('constraints', '').split('\n')
        neg_constraints = [c[1:] for c in constraints if c and c[0] == '!']
        if not set(neg_constraints).isdisjoint(axes_items):
            continue

        if not out.has_section(section_name):
            out.add_section(section_name)

        if (section_alt_name and not out.has_section(section_alt_name)):
            out.add_section(section_alt_name)

        for name, value in reversed(options.items()):
            if not out.has_option(section_name, name):
                out.set(section_name, name, value)
            if section_alt_name and not out.has_option(section_alt_name, name):
                out.set(section_alt_name, name, value)

    return out
dataset/ETHPy150Open openstack/wsme/toxgen.py/render/original