codecov-io: # [Codecov](https://codecov.io/gh/tox-dev/tox-travis/pull/59?src=pr&el=h1) Report
> Merging [#59](https://codecov.io/gh/tox-dev/tox-travis/pull/59?src=pr&el=desc) into [master](https://codecov.io/gh/tox-dev/tox-travis/commit/e83cadff47ca060bb437a4a12311a9a6b407ebcb?src=pr&el=desc) will **decrease** coverage by `1.96%`.
> The diff coverage is `65.85%`.

[![Impacted file tree graph](https://codecov.io/gh/tox-dev/tox-travis/pull/59/graphs/tree.svg?width=650&height=150&src=pr&token=CBMEkiKkWy)](https://codecov.io/gh/tox-dev/tox-travis/pull/59?src=pr&el=tree)

```diff
@@            Coverage Diff            @@
##           master     #59      +/-   ##
=========================================
- Coverage   75.26%   73.3%   -1.97%     
=========================================
  Files           5       4       -1     
  Lines         186     206      +20     
  Branches       45      51       +6     
=========================================
+ Hits          140     151      +11     
- Misses         39      43       +4     
- Partials        7      12       +5
```


| [Impacted Files](https://codecov.io/gh/tox-dev/tox-travis/pull/59?src=pr&el=tree) | Coverage Δ | |
|---|---|---|
| [src/tox\_travis/toxenv.py](https://codecov.io/gh/tox-dev/tox-travis/pull/59?src=pr&el=tree#diff-c3JjL3RveF90cmF2aXMvdG94ZW52LnB5) | `89.87% <100%> (-4.58%)` | :arrow_down: |
| [src/tox\_travis/after.py](https://codecov.io/gh/tox-dev/tox-travis/pull/59?src=pr&el=tree#diff-c3JjL3RveF90cmF2aXMvYWZ0ZXIucHk=) | `59.77% <50%> (+2.12%)` | :arrow_up: |
| [src/tox\_travis/utils.py](https://codecov.io/gh/tox-dev/tox-travis/pull/59?src=pr&el=tree#diff-c3JjL3RveF90cmF2aXMvdXRpbHMucHk=) | `65.38% <57.14%> (-34.62%)` | :arrow_down: |
| [src/tox\_travis/hooks.py](https://codecov.io/gh/tox-dev/tox-travis/pull/59?src=pr&el=tree#diff-c3JjL3RveF90cmF2aXMvaG9va3MucHk=) | `78.57% <75%> (-8.1%)` | :arrow_down: |
| [src/tox\_travis/hacks.py](https://codecov.io/gh/tox-dev/tox-travis/pull/59?src=pr&el=tree#diff-c3JjL3RveF90cmF2aXMvaGFja3MucHk=) | | |

------

[Continue to review full report at Codecov](https://codecov.io/gh/tox-dev/tox-travis/pull/59?src=pr&el=continue).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/tox-dev/tox-travis/pull/59?src=pr&el=footer). Last update [e83cadf...df2fed4](https://codecov.io/gh/tox-dev/tox-travis/pull/59?src=pr&el=lastupdated). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments).

ryanhiebert: This is ready for review. I've added a test, and rebased it to be based on us now using the tox_configure hook. So it's just using the config that Tox loaded, instead of loading our own.
ryanhiebert: >>> I'm going to clean this up and merge it.
>>
>> Tests?
>
> Yes, those too. I spoke like I wasn't going to, but I definitely do, and hopefully a green review too ;-)

Confession: I totally wanted to skip writing tests. My excuse was that it was a bug fix and I wanted to get it fixed quickly. In hindsight the original pull request was certainly too big to skip tests, and I'm really thankful to @rpkilby for calling me out on it with a single word. I apologize for obfuscating my true intentions at the time.

At this point the patch is much smaller, and has added a regression test. In an effort to maintain my own momentum, I may merge some PRs that I perceive to be less challenging, like this one now is, though I intend to give @rpkilby a couple days before I do that with this particular pull request. Or anyone else that's willing. I sometimes take @rpkilby for granted because of how absolutely awesome he's been as a maintainer.
diff --git a/src/tox_travis/after.py b/src/tox_travis/after.py
index 9f25f20..caf3750 100644
--- a/src/tox_travis/after.py
+++ b/src/tox_travis/after.py
@@ -4,7 +4,6 @@ import os
 import sys
 import json
 import time
-import py
 
 from tox.config import _split_env as split_env
 try:
@@ -32,18 +31,18 @@ def travis_after_monkeypatch():
         retcode = real_subcommand_test(self)
         if retcode == 0 and self.config.option.travis_after:
             # No need to run if the tests failed anyway
-            travis_after(self.config.envlist)
+            travis_after(self.config.envlist, self.config._cfg)
         return retcode
     tox.session.Session.subcommand_test = subcommand_test
 
 
-def travis_after(envlist):
+def travis_after(envlist, ini):
     """Wait for all jobs to finish, then exit successfully."""
     # after-all disabled for pull requests
     if os.environ.get('TRAVIS_PULL_REQUEST', 'false') != 'false':
         return
 
-    if not after_config_matches(envlist):
+    if not after_config_matches(envlist, ini):
         return  # This is not the one that needs to wait
 
     github_token = os.environ.get('GITHUB_TOKEN')
@@ -77,10 +76,9 @@ def travis_after(envlist):
     print('All required jobs were successful.')
 
 
-def after_config_matches(envlist):
+def after_config_matches(envlist, ini):
     """Determine if this job should wait for the others."""
-    config = py.iniconfig.IniConfig('tox.ini')
-    section = config.sections.get('travis:after', {})
+    section = ini.sections.get('travis:after', {})
 
     if not section:
         return False  # Never wait if it's not configured
diff --git a/src/tox_travis/toxenv.py b/src/tox_travis/toxenv.py
index 631f45b..8bed3c7 100644
--- a/src/tox_travis/toxenv.py
+++ b/src/tox_travis/toxenv.py
@@ -4,7 +4,6 @@ from itertools import product
 import os
 import sys
 import re
-import py
 import tox.config
 from tox.config import _split_env as split_env
 from .utils import TRAVIS_FACTORS, parse_dict
@@ -15,7 +14,7 @@ def default_toxenv(config):
     if 'TOXENV' in os.environ or config.option.env:
         return  # Skip any processing if already set
 
-    ini = py.iniconfig.IniConfig('tox.ini')
+    ini = config._cfg
 
     # Find the envs that tox knows about
     declared_envs = get_declared_envs(ini)
@@ -235,8 +234,7 @@ def env_matches(declared, desired):
 
 def override_ignore_outcome(config):
     """Override ignore_outcome if unignore_outcomes is set to True."""
-    tox_config = py.iniconfig.IniConfig('tox.ini')
-    travis_reader = tox.config.SectionReader("travis", tox_config)
+    travis_reader = tox.config.SectionReader("travis", config._cfg)
     if travis_reader.getbool('unignore_outcomes', False):
         for envconfig in config.envconfigs.values():
             envconfig.ignore_outcome = False

Respect specified tox configuration file
`tox -c CONFIGFILE` tells tox exactly where to find the Tox configuration file. This defaults to `tox.ini`. If this option is given, Tox-Travis should look for its configuration in that file as well.

References #56.
diff --git a/tests/test_after.py b/tests/test_after.py
index da63063..06fb01c 100644
--- a/tests/test_after.py
+++ b/tests/test_after.py
@@ -13,7 +13,7 @@ class TestAfter:
         monkeypatch.setenv('TRAVIS', 'true')
         monkeypatch.setenv('TRAVIS_PULL_REQUEST', '1')
 
-        travis_after(mocker.Mock())
+        travis_after(mocker.Mock(), mocker.Mock())
 
         out, err = capsys.readouterr()
         assert out == ''
@@ -25,7 +25,7 @@ class TestAfter:
                      return_value=True)
         monkeypatch.setenv('TRAVIS', 'true')
         with pytest.raises(SystemExit) as excinfo:
-            travis_after(mocker.Mock())
+            travis_after(mocker.Mock(), mocker.Mock())
 
         assert excinfo.value.code == 32
         out, err = capsys.readouterr()
@@ -38,7 +38,7 @@ class TestAfter:
         monkeypatch.setenv('TRAVIS', 'true')
         monkeypatch.setenv('GITHUB_TOKEN', 'spamandeggs')
         with pytest.raises(SystemExit) as excinfo:
-            travis_after(mocker.Mock())
+            travis_after(mocker.Mock(), mocker.Mock())
 
         assert excinfo.value.code == 34
         out, err = capsys.readouterr()
@@ -52,7 +52,7 @@ class TestAfter:
         monkeypatch.setenv('GITHUB_TOKEN', 'spamandeggs')
         monkeypatch.setenv('TRAVIS_BUILD_ID', '1234')
         with pytest.raises(SystemExit) as excinfo:
-            travis_after(mocker.Mock())
+            travis_after(mocker.Mock(), mocker.Mock())
 
         assert excinfo.value.code == 34
         out, err = capsys.readouterr()
@@ -69,7 +69,7 @@ class TestAfter:
         # TRAVIS_API_URL is set to a reasonable default
         monkeypatch.setenv('TRAVIS_API_URL', '')
         with pytest.raises(SystemExit) as excinfo:
-            travis_after(mocker.Mock())
+            travis_after(mocker.Mock(), mocker.Mock())
 
         assert excinfo.value.code == 34
         out, err = capsys.readouterr()
@@ -86,7 +86,7 @@ class TestAfter:
         # TRAVIS_POLLING_INTERVAL is set to a reasonable default
         monkeypatch.setenv('TRAVIS_POLLING_INTERVAL', 'xbe')
         with pytest.raises(SystemExit) as excinfo:
-            travis_after(mocker.Mock())
+            travis_after(mocker.Mock(), mocker.Mock())
 
         assert excinfo.value.code == 33
         out, err = capsys.readouterr()
@@ -186,7 +186,7 @@ class TestAfter:
         get_json.responses = iter(responses)
 
         mocker.patch('tox_travis.after.get_json', side_effect=get_json)
-        travis_after(mocker.Mock())
+        travis_after(mocker.Mock(), mocker.Mock())
         out, err = capsys.readouterr()
         assert 'All required jobs were successful.' in out
 
@@ -289,7 +289,7 @@ class TestAfter:
         mocker.patch('tox_travis.after.get_json', side_effect=get_json)
 
         with pytest.raises(SystemExit) as excinfo:
-            travis_after(mocker.Mock())
+            travis_after(mocker.Mock(), mocker.Mock())
 
         assert excinfo.value.code == 35
         out, err = capsys.readouterr()
diff --git a/tests/test_toxenv.py b/tests/test_toxenv.py
index bd62707..91daef9 100644
--- a/tests/test_toxenv.py
+++ b/tests/test_toxenv.py
@@ -119,27 +119,33 @@ unignore_outcomes = False
 class TestToxEnv:
     """Test the logic to automatically configure TOXENV with Travis."""
 
-    def tox_envs(self):
+    def tox_envs(self, **kwargs):
         """Find the envs that tox sees."""
-        returncode, stdout, stderr = self.tox_envs_raw()
+        returncode, stdout, stderr = self.tox_envs_raw(**kwargs)
         assert returncode == 0, stderr
         return [env for env in stdout.strip().split('\n')]
 
-    def tox_envs_raw(self):
+    def tox_envs_raw(self, ini_filename=None):
         """Return the raw output of finding what tox sees."""
-        return self.call_raw(['tox', '-l'])
+        command = ['tox', '-l']
+        if ini_filename is not None:
+            command += ['-c', ini_filename]
+        return self.call_raw(command)
 
-    def tox_config(self):
+    def tox_config(self, **kwargs):
         """Returns the configuration per configuration as computed by tox."""
-        returncode, stdout, stderr = self.tox_config_raw()
+        returncode, stdout, stderr = self.tox_config_raw(**kwargs)
         assert returncode == 0, stderr
         ini = "[global]\n" + re.sub(
             re.compile(r'^\s+', re.MULTILINE), '', stdout)
         return py.iniconfig.IniConfig('', data=ini)
 
-    def tox_config_raw(self):
+    def tox_config_raw(self, ini_filename=None):
         """Return the raw output of finding the complex tox env config."""
-        return self.call_raw(['tox', '--showconfig'])
+        command = ['tox', '--showconfig']
+        if ini_filename is not None:
+            command += ['-c', ini_filename]
+        return self.call_raw(command)
 
     def call_raw(self, command):
         """Return the raw output of the given command."""
@@ -152,10 +158,11 @@ class TestToxEnv:
     def configure(self, tmpdir, monkeypatch, tox_ini,
                   version=None, major=None, minor=None,
                   travis_version=None, travis_os=None,
-                  travis_language=None, env=None):
+                  travis_language=None, env=None,
+                  ini_filename='tox.ini'):
         """Configure the environment for running a test."""
         origdir = tmpdir.chdir()
-        tmpdir.join('tox.ini').write(tox_ini)
+        tmpdir.join(ini_filename).write(tox_ini)
         tmpdir.join('.coveragerc').write(coverage_config)
 
         if version or travis_version or travis_os or travis_language:
@@ -202,6 +209,12 @@ class TestToxEnv:
             ]
             assert self.tox_envs() == expected
 
+    def test_travis_config_filename(self, tmpdir, monkeypatch):
+        """Give the correct env for CPython 2.7."""
+        with self.configure(tmpdir, monkeypatch, tox_ini, 'CPython', 3, 6,
+                            ini_filename='spam.ini'):
+            assert self.tox_envs(ini_filename='spam.ini') == ['py36']
+
     def test_travis_default_26(self, tmpdir, monkeypatch):
         """Give the correct env for CPython 2.6."""
         with self.configure(tmpdir, monkeypatch, tox_ini, 'CPython', 2, 6):

pip install -e .[dev]
parse_log_pytest
pytest
pytest pytest-mock mock
3.6
pytest --no-header -rA --tb=line --color=no -p no:cacheprovider -W ignore::DeprecationWarning
attrs @ file:///opt/conda/conda-bld/attrs_1642510447205/work
certifi==2021.5.30
distlib==0.3.9
filelock==3.4.1
importlib-metadata==4.8.3
importlib-resources==5.4.0
iniconfig @ file:///home/linux1/recipes/ci/iniconfig_1610983019677/work
mock==5.2.0
more-itertools @ file:///tmp/build/80754af9/more-itertools_1637733554872/work
packaging @ file:///tmp/build/80754af9/packaging_1637314298585/work
platformdirs==2.4.0
pluggy @ file:///tmp/build/80754af9/pluggy_1615976315926/work
py @ file:///opt/conda/conda-bld/py_1644396412707/work
pyparsing @ file:///tmp/build/80754af9/pyparsing_1635766073266/work
pytest==6.2.4
pytest-mock==3.6.1
six==1.17.0
toml @ file:///tmp/build/80754af9/toml_1616166611790/work
tox==3.28.0
-e git+https://github.com/tox-dev/tox-travis.git@bc25fa2d2fc8e98a051a57160dfc43c8f35da2ee#egg=tox_travis
typing_extensions @ file:///opt/conda/conda-bld/typing_extensions_1647553014482/work
virtualenv==20.17.1
zipp @ file:///tmp/build/80754af9/zipp_1633618647012/work

name: tox-travis
channels:
  - defaults
  - https://repo.anaconda.com/pkgs/main
  - https://repo.anaconda.com/pkgs/r
  - conda-forge
dependencies:
  - _libgcc_mutex=0.1=main
  - _openmp_mutex=5.1=1_gnu
  - attrs=21.4.0=pyhd3eb1b0_0
  - ca-certificates=2025.2.25=h06a4308_0
  - certifi=2021.5.30=py36h06a4308_0
  - importlib_metadata=4.8.1=hd3eb1b0_0
  - iniconfig=1.1.1=pyhd3eb1b0_0
  - ld_impl_linux-64=2.40=h12ee557_0
  - libffi=3.3=he6710b0_2
  - libgcc-ng=11.2.0=h1234567_1
  - libgomp=11.2.0=h1234567_1
  - libstdcxx-ng=11.2.0=h1234567_1
  - more-itertools=8.12.0=pyhd3eb1b0_0
  - ncurses=6.4=h6a678d5_0
  - openssl=1.1.1w=h7f8727e_0
  - packaging=21.3=pyhd3eb1b0_0
  - pip=21.2.2=py36h06a4308_0
  - pluggy=0.13.1=py36h06a4308_0
  - py=1.11.0=pyhd3eb1b0_0
  - pyparsing=3.0.4=pyhd3eb1b0_0
  - pytest=6.2.4=py36h06a4308_2
  - python=3.6.13=h12debd9_1
  - readline=8.2=h5eee18b_0
  - setuptools=58.0.4=py36h06a4308_0
  - sqlite=3.45.3=h5eee18b_0
  - tk=8.6.14=h39e8969_0
  - toml=0.10.2=pyhd3eb1b0_0
  - typing_extensions=4.1.1=pyh06a4308_0
  - wheel=0.37.1=pyhd3eb1b0_0
  - xz=5.6.4=h5eee18b_1
  - zipp=3.6.0=pyhd3eb1b0_0
  - zlib=1.2.13=h5eee18b_1
  - pip:
      - distlib==0.3.9
      - filelock==3.4.1
      - importlib-metadata==4.8.3
      - importlib-resources==5.4.0
      - mock==5.2.0
      - platformdirs==2.4.0
      - pytest-mock==3.6.1
      - six==1.17.0
      - tox==3.28.0
      - virtualenv==20.17.1
prefix: /opt/conda/envs/tox-travis

tests/test_after.py::TestAfter::test_pull_request tests/test_after.py::TestAfter::test_no_github_token tests/test_after.py::TestAfter::test_travis_environment_build_id tests/test_after.py::TestAfter::test_travis_environment_job_number tests/test_after.py::TestAfter::test_travis_environment_api_url tests/test_after.py::TestAfter::test_travis_env_polling_interval tests/test_after.py::TestAfter::test_travis_env_passed tests/test_after.py::TestAfter::test_travis_env_failed
tests/test_toxenv.py::TestToxEnv::test_travis_config_filename tests/test_toxenv.py::TestToxEnv::test_travis_default_26 tests/test_toxenv.py::TestToxEnv::test_travis_default_27 tests/test_toxenv.py::TestToxEnv::test_travis_default_32 tests/test_toxenv.py::TestToxEnv::test_travis_default_33 tests/test_toxenv.py::TestToxEnv::test_travis_default_34 tests/test_toxenv.py::TestToxEnv::test_travis_default_pypy tests/test_toxenv.py::TestToxEnv::test_travis_default_pypy3 tests/test_toxenv.py::TestToxEnv::test_travis_python_version_py27 tests/test_toxenv.py::TestToxEnv::test_travis_python_version_py35 tests/test_toxenv.py::TestToxEnv::test_travis_python_version_pypy tests/test_toxenv.py::TestToxEnv::test_travis_python_version_pypy3 tests/test_toxenv.py::TestToxEnv::test_travis_not_matching tests/test_toxenv.py::TestToxEnv::test_travis_nightly tests/test_toxenv.py::TestToxEnv::test_travis_override tests/test_toxenv.py::TestToxEnv::test_respect_overridden_toxenv tests/test_toxenv.py::TestToxEnv::test_keep_if_no_match tests/test_toxenv.py::TestToxEnv::test_default_tox_ini_overrides tests/test_toxenv.py::TestToxEnv::test_factors tests/test_toxenv.py::TestToxEnv::test_match_and_keep tests/test_toxenv.py::TestToxEnv::test_django_factors tests/test_toxenv.py::TestToxEnv::test_non_python_factor tests/test_toxenv.py::TestToxEnv::test_travis_factors_py27 tests/test_toxenv.py::TestToxEnv::test_travis_factors_py35 tests/test_toxenv.py::TestToxEnv::test_travis_factors_osx tests/test_toxenv.py::TestToxEnv::test_travis_factors_py27_osx tests/test_toxenv.py::TestToxEnv::test_travis_factors_language tests/test_toxenv.py::TestToxEnv::test_travis_env_py27 tests/test_toxenv.py::TestToxEnv::test_travis_env_py27_dj19 tests/test_toxenv.py::TestToxEnv::test_travis_env_py35_dj110
tests/test_toxenv.py::TestToxEnv::test_not_travis tests/test_toxenv.py::TestToxEnv::test_legacy_warning tests/test_toxenv.py::TestToxEnv::test_travis_ignore_outcome tests/test_toxenv.py::TestToxEnv::test_travis_ignore_outcome_unignore_outcomes tests/test_toxenv.py::TestToxEnv::test_travis_ignore_outcome_not_unignore_outcomes tests/test_toxenv.py::TestToxEnv::test_local_ignore_outcome_unignore_outcomes
src/tox_travis/after.py src/tox_travis/toxenv.py
src/tox_travis/after.py src/tox_travis/toxenv.py