Repository: tox-dev/tox

Issue:
tox 3.8 crashes on Appveyor
In the h5py project, all the builds on Appveyor recently started failing. This seems to coincide with the release of tox 3.8.0, and it still occurs with 3.8.1. I'm still investigating this,  but here's the error we're getting:

```
ci\appveyor\build.cmd py -3.5 -m tox
Using default MSVC build environment
C:\Python35-x64\lib\site-packages\tox\config\__init__.py:576: UserWarning: conflicting basepython version (set 36, should be 27) for env 'py27-test-deps';resolve conflict or set ignore_basepython_conflict
  proposed_version, implied_version, testenv_config.envname
C:\Python35-x64\lib\site-packages\tox\config\__init__.py:576: UserWarning: conflicting basepython version (set 36, should be 27) for env 'py27-test-mindeps';resolve conflict or set ignore_basepython_conflict
  proposed_version, implied_version, testenv_config.envname
C:\Python35-x64\lib\site-packages\tox\config\__init__.py:576: UserWarning: conflicting basepython version (set 36, should be 34) for env 'py34-test-deps';resolve conflict or set ignore_basepython_conflict
  proposed_version, implied_version, testenv_config.envname
C:\Python35-x64\lib\site-packages\tox\config\__init__.py:576: UserWarning: conflicting basepython version (set 36, should be 34) for env 'py34-test-mindeps';resolve conflict or set ignore_basepython_conflict
  proposed_version, implied_version, testenv_config.envname
C:\Python35-x64\lib\site-packages\tox\config\__init__.py:576: UserWarning: conflicting basepython version (set 36, should be 35) for env 'py35-test-deps';resolve conflict or set ignore_basepython_conflict
  proposed_version, implied_version, testenv_config.envname
C:\Python35-x64\lib\site-packages\tox\config\__init__.py:576: UserWarning: conflicting basepython version (set 36, should be 35) for env 'py35-test-mindeps';resolve conflict or set ignore_basepython_conflict
  proposed_version, implied_version, testenv_config.envname
C:\Python35-x64\lib\site-packages\tox\config\__init__.py:576: UserWarning: conflicting basepython version (set 36, should be 37) for env 'py37-test-deps';resolve conflict or set ignore_basepython_conflict
  proposed_version, implied_version, testenv_config.envname
C:\Python35-x64\lib\site-packages\tox\config\__init__.py:576: UserWarning: conflicting basepython version (set 36, should be 37) for env 'py37-test-mindeps';resolve conflict or set ignore_basepython_conflict
  proposed_version, implied_version, testenv_config.envname
Traceback (most recent call last):
  File "C:\Python35-x64\lib\runpy.py", line 193, in _run_module_as_main
    "__main__", mod_spec)
  File "C:\Python35-x64\lib\runpy.py", line 85, in _run_code
    exec(code, run_globals)
  File "C:\Python35-x64\lib\site-packages\tox\__main__.py", line 4, in <module>
    tox.cmdline()
  File "C:\Python35-x64\lib\site-packages\tox\session\__init__.py", line 42, in cmdline
    main(args)
  File "C:\Python35-x64\lib\site-packages\tox\session\__init__.py", line 58, in main
    config = load_config(args)
  File "C:\Python35-x64\lib\site-packages\tox\session\__init__.py", line 75, in load_config
    config = parseconfig(args)
  File "C:\Python35-x64\lib\site-packages\tox\config\__init__.py", line 249, in parseconfig
    ParseIni(config, config_file, content)
  File "C:\Python35-x64\lib\site-packages\tox\config\__init__.py", line 1077, in __init__
    config.envconfigs[name] = self.make_envconfig(name, section, reader._subs, config)
  File "C:\Python35-x64\lib\site-packages\tox\config\__init__.py", line 1181, in make_envconfig
    res = env_attr.postprocess(testenv_config=tc, value=res)
  File "C:\Python35-x64\lib\site-packages\tox\config\__init__.py", line 571, in basepython_default
    if not proposed_version.startswith(implied_version):
TypeError: startswith first arg must be str or a tuple of str, not NoneType
```

Example failure log: https://ci.appveyor.com/project/h5py/h5py/builds/23449770/job/itchqco453midako

I'll update this with anything I find.

Discussion:
todo[bot]: ## (stephenfin): Raise an exception here in tox 4.0

https://github.com/tox-dev/tox/blob/407121bcdb96663154f9c439b62c50fc44a72b56/src/tox/config/__init__.py#L574-L579

---

###### This comment was generated by [todo](https://todo.jasonet.co) based on a `TODO` comment in 407121bcdb96663154f9c439b62c50fc44a72b56 in #1229. cc @gaborbernat.

Patch:
diff --git a/docs/changelog/1227.bugfix.rst b/docs/changelog/1227.bugfix.rst
new file mode 100644
index 00000000..7d7a5009
--- /dev/null
+++ b/docs/changelog/1227.bugfix.rst
@@ -0,0 +1,1 @@
+don't crash when version information is not available for a proposed base python - by :user:`gaborbernat`
diff --git a/src/tox/config/__init__.py b/src/tox/config/__init__.py
index 5380814c..53e4003a 100644
--- a/src/tox/config/__init__.py
+++ b/src/tox/config/__init__.py
@@ -561,21 +561,23 @@ def tox_addoption(parser):
         proposed_python = (implied_python or sys.executable) if value is None else str(value)
         if implied_python is not None and implied_python != proposed_python:
             testenv_config.basepython = proposed_python
-            implied_version = tox.PYTHON.PY_FACTORS_RE.match(factor).group(2)
-            python_info_for_proposed = testenv_config.python_info
-            if not isinstance(python_info_for_proposed, NoInterpreterInfo):
-                proposed_version = "".join(
-                    str(i) for i in python_info_for_proposed.version_info[0:2]
-                )
-                # '27'.startswith('2') or '27'.startswith('27')
-                if not proposed_version.startswith(implied_version):
-                    # TODO(stephenfin): Raise an exception here in tox 4.0
-                    warnings.warn(
-                        "conflicting basepython version (set {}, should be {}) for env '{}';"
-                        "resolve conflict or set ignore_basepython_conflict".format(
-                            proposed_version, implied_version, testenv_config.envname
-                        )
+            match = tox.PYTHON.PY_FACTORS_RE.match(factor)
+            implied_version = match.group(2) if match else None
+            if implied_version is not None:
+                python_info_for_proposed = testenv_config.python_info
+                if not isinstance(python_info_for_proposed, NoInterpreterInfo):
+                    proposed_version = "".join(
+                        str(i) for i in python_info_for_proposed.version_info[0:2]
                     )
+                    # '27'.startswith('2') or '27'.startswith('27')
+                    if not proposed_version.startswith(implied_version):
+                        # TODO(stephenfin): Raise an exception here in tox 4.0
+                        warnings.warn(
+                            "conflicting basepython version (set {}, should be {}) for env '{}';"
+                            "resolve conflict or set ignore_basepython_conflict".format(
+                                proposed_version, implied_version, testenv_config.envname
+                            )
+                        )
         return proposed_python
 
     parser.add_testenv_attribute(


Test patch:
diff --git a/tests/unit/config/test_config.py b/tests/unit/config/test_config.py
index d717a7bb..55cbb547 100644
--- a/tests/unit/config/test_config.py
+++ b/tests/unit/config/test_config.py
@@ -3061,3 +3061,17 @@ def test_posargs_relative_changedir(newconfig, tmpdir):
             dir1.strpath,
             "dir3",
         ]
+
+
+def test_config_no_version_data_in__name(newconfig, capsys):
+    newconfig(
+        """
+        [tox]
+        envlist = py, pypy, jython
+        [testenv]
+        basepython = python
+        """
+    )
+    out, err = capsys.readouterr()
+    assert not out
+    assert not err