def get_desired_factors(ini):
    """Get the list of desired envs per declared factor.

    Look at all the accepted configuration locations, and give a list
    of envlists, one for each Travis factor found.

    Look in the ``[travis]`` section for the known Travis factors,
    which are backed by environment variable checking behind the
    scenes, but provide a cleaner interface.

    Also look for the ``[tox:travis]`` section, which is deprecated,
    and treat it as an additional ``python`` key from the ``[travis]``
    section.

    Finally, look for factors based directly on environment variables,
    listed in the ``[travis:env]`` section. Configuration found in the
    ``[travis]`` and ``[tox:travis]`` sections are converted to this
    form under the hood, and are considered in the same way.

    Special consideration is given to the ``python`` factor. If this
    factor is set in the environment, then an appropriate configuration
    will be provided automatically if no manual configuration is
    provided.

    To allow for the most flexible processing, the envlists provided
    by each factor are not combined after they are selected, but
    instead returned as a list of envlists, and expected to be
    combined as and when appropriate by the caller. This allows for
    special handling based on the number of factors that were found
    to apply to this environment.
    """
    # Find configuration based on known travis factors
    travis_section = ini.sections.get('travis', {})
    found_factors = [
        (factor, parse_dict(travis_section[factor]))
        for factor in TRAVIS_FACTORS
        if factor in travis_section
    ]

    # Backward compatibility with the old tox:travis section
    if 'tox:travis' in ini.sections:
        print('The [tox:travis] section is deprecated in favor of'
              ' the "python" key of the [travis] section.', file=sys.stderr)
        found_factors.append(('python', ini.sections['tox:travis']))

    # Inject any needed autoenv
    version = os.environ.get('TRAVIS_PYTHON_VERSION')
    if version:
        default_envlist = get_default_envlist(version)
        if not any(factor == 'python' for factor, _ in found_factors):
            found_factors.insert(0, ('python', {version: default_envlist}))
        python_factors = [(factor, mapping)
                          for factor, mapping in found_factors
                          if version and factor == 'python']
        for _, mapping in python_factors:
            mapping.setdefault(version, default_envlist)

    # Convert known travis factors to env factors,
    # and combine with declared env factors.
    env_factors = [
        (TRAVIS_FACTORS[factor], mapping)
        for factor, mapping in found_factors
    ] + [
        (name, parse_dict(value))
        for name, value in ini.sections.get('travis:env', {}).items()
    ]

    # Choose the correct envlists based on the factor values
    return [
        split_env(mapping[os.environ[name]])
        for name, mapping in env_factors
        if name in os.environ and os.environ[name] in mapping
    ]
Get the list of desired envs per declared factor.

    Look at all the accepted configuration locations, and give a list
    of envlists, one for each Travis factor found.

    Look in the ``[travis]`` section for the known Travis factors,
    which are backed by environment variable checking behind the
    scenes, but provide a cleaner interface.

    Also look for the ``[tox:travis]`` section, which is deprecated,
    and treat it as an additional ``python`` key from the ``[travis]``
    section.

    Finally, look for factors based directly on environment variables,
    listed in the ``[travis:env]`` section. Configuration found in the
    ``[travis]`` and ``[tox:travis]`` sections are converted to this
    form under the hood, and are considered in the same way.

    Special consideration is given to the ``python`` factor. If this
    factor is set in the environment, then an appropriate configuration
    will be provided automatically if no manual configuration is
    provided.

    To allow for the most flexible processing, the envlists provided
    by each factor are not combined after they are selected, but
    instead returned as a list of envlists, and expected to be
    combined as and when appropriate by the caller. This allows for
    special handling based on the number of factors that were found
    to apply to this environment.