Repository: pypa/virtualenv

Issue:
AttributeError: 'NoneType' object has no attribute 'group' with virtualenv 20.0.32 on CygWin
**Issue**
We are also testing on CygWin (using appveyor), and since this morning, tox fails creating a virtualenv with an AttributeError. Unfortunately, tox does not display the entire traceback, but just the exception.
Since virtualenv 20.0.32 was released just 4h ago, I suspect that to be the culprit.

From https://ci.appveyor.com/project/andy-maier/pywbem/builds/35526352/job/l3k6a2vb39bweqsw#L936:
```
if "%UNIX_PATH%"=="C:\cygwin64\bin" ( bash -c "which tox && tox -vv -e %TOX_ENV% && echo appveyor.yml: tox rc=$?" )
/usr/bin/tox
using tox.ini: /cygdrive/c/projects/pywbem/tox.ini (pid 1822)
using tox-3.20.0 from /usr/lib/python3.8/site-packages/tox/__init__.py (pid 1822)
skipping sdist step
cygwin64_py38 uses /usr/bin/python3.8.exe
cygwin64_py38 start: getenv /cygdrive/c/projects/pywbem/.tox/cygwin64_py38
cygwin64_py38 cannot reuse: no previous config /cygdrive/c/projects/pywbem/.tox/cygwin64_py38/.tox-config1
cygwin64_py38 create: /cygdrive/c/projects/pywbem/.tox/cygwin64_py38
setting PATH=/cygdrive/c/projects/pywbem/.tox/cygwin64_py38/bin:/usr/bin:/cygdrive/c/Windows/system32:/cygdrive/c/Windows:/cygdrive/c/ProgramData/chocolatey/bin
[1825] /cygdrive/c/projects/pywbem/.tox$ /usr/bin/python3.8.exe -m virtualenv --no-download --python /usr/bin/python3.8.exe cygwin64_py38
AttributeError: 'NoneType' object has no attribute 'group'
ERROR: invocation failed (exit code 1)
ERROR: InvocationError for command /usr/bin/python3.8.exe -m virtualenv --no-download --python /usr/bin/python3.8.exe cygwin64_py38 (exited with code 1)
cygwin64_py38 finish: getenv /cygdrive/c/projects/pywbem/.tox/cygwin64_py38 after 4.23 seconds
```

I am setting up a direct invocation of virtualenv in that environment, in order to get the full traceback, and will post that here.

**Environment**

Provide at least:
- OS: CygWin64
- ``pip list`` of the host python where ``virtualenv`` is installed:
  ```console
  See next comment, below
  ```

**Output of the virtual environment creation**

Make sure to run the creation with `-vvv --with-traceback`:

```console
See next comment, below
```


Discussion:
Here is the full traceback of virtualenv, using `-vvv --with-traceback`:

```
if "%UNIX_PATH%"=="C:\cygwin64\bin" ( bash --noprofile --norc -c "%PYTHON_CMD% -m virtualenv -vvv --with-traceback --no-download --python %PYTHON_CMD% test_py38" )
133 setup logging to NOTSET [DEBUG report:43]
134 created app data folder /home/appveyor/.local/share/virtualenv [DEBUG __init__:30]
144 find interpreter for spec PythonSpec(implementation=CPython, major=3, minor=8) [INFO builtin:44]
144 proposed PythonInfo(spec=CPython3.8.3.final.0-64, exe=/usr/bin/python3.8.exe, platform=cygwin, version='3.8.3 (default, May 23 2020, 15:50:53) \n[GCC 9.3.0]', encoding_fs_io=utf-8-utf-8) [INFO builtin:50]
144 accepted PythonInfo(spec=CPython3.8.3.final.0-64, exe=/usr/bin/python3.8.exe, platform=cygwin, version='3.8.3 (default, May 23 2020, 15:50:53) \n[GCC 9.3.0]', encoding_fs_io=utf-8-utf-8) [DEBUG builtin:52]
147 filesystem is not case-sensitive [DEBUG info:28]
211 create virtual environment via CPython3Posix(dest=/cygdrive/c/projects/pywbem/test_py38, clear=False, global=False) [INFO session:52]
211 create folder /cygdrive/c/projects/pywbem/test_py38/bin [DEBUG _sync:25]
216 create folder /cygdrive/c/projects/pywbem/test_py38/lib/python3.8/site-packages [DEBUG _sync:25]
216 write /cygdrive/c/projects/pywbem/test_py38/pyvenv.cfg [DEBUG pyenv_cfg:34]
216 	home = /usr [DEBUG pyenv_cfg:38]
216 	implementation = CPython [DEBUG pyenv_cfg:38]
216 	version_info = 3.8.3.final.0 [DEBUG pyenv_cfg:38]
216 	virtualenv = 20.0.32 [DEBUG pyenv_cfg:38]
217 	include-system-site-packages = false [DEBUG pyenv_cfg:38]
217 	base-prefix = /usr [DEBUG pyenv_cfg:38]
217 	base-exec-prefix = /usr [DEBUG pyenv_cfg:38]
217 	base-executable = /usr/bin/python3.8.exe [DEBUG pyenv_cfg:38]
220 symlink /usr/bin/python3.8.exe to /cygdrive/c/projects/pywbem/test_py38/bin/python [DEBUG _sync:44]
221 create virtualenv import hook file /cygdrive/c/projects/pywbem/test_py38/lib/python3.8/site-packages/_virtualenv.pth [DEBUG api:95]
222 create /cygdrive/c/projects/pywbem/test_py38/lib/python3.8/site-packages/_virtualenv.py [DEBUG api:98]
223 ============================== target debug ============================== [DEBUG session:54]
223 debug via /cygdrive/c/projects/pywbem/test_py38/bin/python /usr/lib/python3.8/site-packages/virtualenv/create/debug.py [DEBUG creator:213]
223 {
  "sys": {
    "executable": "/cygdrive/c/projects/pywbem/test_py38/bin/python",
    "_base_executable": "/cygdrive/c/projects/pywbem/test_py38/bin/python",
    "prefix": "/cygdrive/c/projects/pywbem/test_py38",
    "base_prefix": "/usr",
    "real_prefix": null,
    "exec_prefix": "/cygdrive/c/projects/pywbem/test_py38",
    "base_exec_prefix": "/usr",
    "path": [
      "/usr/lib/python38.zip",
      "/usr/lib/python3.8",
      "/usr/lib/python3.8/lib-dynload",
      "/cygdrive/c/projects/pywbem/test_py38/lib/python3.8/site-packages"
    ],
    "meta_path": [
      "<class '_virtualenv._Finder'>",
      "<class '_frozen_importlib.BuiltinImporter'>",
      "<class '_frozen_importlib.FrozenImporter'>",
      "<class '_frozen_importlib_external.PathFinder'>"
    ],
    "fs_encoding": "utf-8",
    "io_encoding": "utf-8"
  },
  "version": "3.8.3 (default, May 23 2020, 15:50:53) \n[GCC 9.3.0]",
  "makefile_filename": "/usr/lib/python3.8/config-3.8-x86_64-cygwin/Makefile",
  "os": "<module 'os' from '/usr/lib/python3.8/os.py'>",
  "site": "<module 'site' from '/usr/lib/python3.8/site.py'>",
  "datetime": "<module 'datetime' from '/usr/lib/python3.8/datetime.py'>",
  "math": "<module 'math' from '/usr/lib/python3.8/lib-dynload/math.cpython-38-x86_64-cygwin.dll'>",
  "json": "<module 'json' from '/usr/lib/python3.8/json/__init__.py'>"
} [DEBUG session:55]
302 add seed packages via FromAppData(download=False, pip=bundle, setuptools=bundle, wheel=bundle, via=copy, app_data_dir=/home/appveyor/.local/share/virtualenv) [INFO session:59]
309 wrote embed update of distribution setuptools at /home/appveyor/.local/share/virtualenv/wheel/3.8/embed/1/setuptools.json [DEBUG via_disk_folder:162]
309 wrote embed update of distribution pip at /home/appveyor/.local/share/virtualenv/wheel/3.8/embed/1/pip.json [DEBUG via_disk_folder:162]
309 wrote embed update of distribution wheel at /home/appveyor/.local/share/virtualenv/wheel/3.8/embed/1/wheel.json [DEBUG via_disk_folder:162]
347 triggered periodic upgrade of setuptools==50.3.0 (for python 3.8) via background process having PID 311 [INFO periodic_update:194]
386 triggered periodic upgrade of wheel==0.35.1 (for python 3.8) via background process having PID 312 [INFO periodic_update:194]
389 got embed update of distribution setuptools from /home/appveyor/.local/share/virtualenv/wheel/3.8/embed/1/setuptools.json [DEBUG via_disk_folder:133]
389 got embed update of distribution wheel from /home/appveyor/.local/share/virtualenv/wheel/3.8/embed/1/wheel.json [DEBUG via_disk_folder:133]
515 triggered periodic upgrade of pip==20.2.3 (for python 3.8) via background process having PID 313 [INFO periodic_update:194]
517 got embed update of distribution pip from /home/appveyor/.local/share/virtualenv/wheel/3.8/embed/1/pip.json [DEBUG via_disk_folder:133]
543 install setuptools from wheel /usr/lib/python3.8/site-packages/virtualenv/seed/wheels/embed/setuptools-50.3.0-py3-none-any.whl via CopyPipInstall [DEBUG via_app_data:53]
544 Attempting to acquire lock 123145287546336 on /home/appveyor/.local/share/virtualenv/wheel/3.8/image/1/CopyPipInstall/setuptools-50.3.0-py3-none-any.lock [DEBUG filelock:270]
544 Lock 123145287546336 acquired on /home/appveyor/.local/share/virtualenv/wheel/3.8/image/1/CopyPipInstall/setuptools-50.3.0-py3-none-any.lock [INFO filelock:274]
544 build install image for setuptools-50.3.0-py3-none-any.whl to /home/appveyor/.local/share/virtualenv/wheel/3.8/image/1/CopyPipInstall/setuptools-50.3.0-py3-none-any [DEBUG base:52]
679 install wheel from wheel /usr/lib/python3.8/site-packages/virtualenv/seed/wheels/embed/wheel-0.35.1-py2.py3-none-any.whl via CopyPipInstall [DEBUG via_app_data:53]
679 Attempting to acquire lock 123145287461616 on /home/appveyor/.local/share/virtualenv/wheel/3.8/image/1/CopyPipInstall/wheel-0.35.1-py2.py3-none-any.lock [DEBUG filelock:270]
680 install pip from wheel /usr/lib/python3.8/site-packages/virtualenv/seed/wheels/embed/pip-20.2.3-py2.py3-none-any.whl via CopyPipInstall [DEBUG via_app_data:53]
681 Attempting to acquire lock 123145287461520 on /home/appveyor/.local/share/virtualenv/wheel/3.8/image/1/CopyPipInstall/pip-20.2.3-py2.py3-none-any.lock [DEBUG filelock:270]
681 Lock 123145287461616 acquired on /home/appveyor/.local/share/virtualenv/wheel/3.8/image/1/CopyPipInstall/wheel-0.35.1-py2.py3-none-any.lock [INFO filelock:274]
681 build install image for wheel-0.35.1-py2.py3-none-any.whl to /home/appveyor/.local/share/virtualenv/wheel/3.8/image/1/CopyPipInstall/wheel-0.35.1-py2.py3-none-any [DEBUG base:52]
682 Lock 123145287461520 acquired on /home/appveyor/.local/share/virtualenv/wheel/3.8/image/1/CopyPipInstall/pip-20.2.3-py2.py3-none-any.lock [INFO filelock:274]
682 build install image for pip-20.2.3-py2.py3-none-any.whl to /home/appveyor/.local/share/virtualenv/wheel/3.8/image/1/CopyPipInstall/pip-20.2.3-py2.py3-none-any [DEBUG base:52]
1440 Attempting to release lock 123145287461616 on /home/appveyor/.local/share/virtualenv/wheel/3.8/image/1/CopyPipInstall/wheel-0.35.1-py2.py3-none-any.lock [DEBUG filelock:315]
1441 Lock 123145287461616 released on /home/appveyor/.local/share/virtualenv/wheel/3.8/image/1/CopyPipInstall/wheel-0.35.1-py2.py3-none-any.lock [INFO filelock:318]
1442 copy directory /home/appveyor/.local/share/virtualenv/wheel/3.8/image/1/CopyPipInstall/wheel-0.35.1-py2.py3-none-any/wheel to /cygdrive/c/projects/pywbem/test_py38/lib/python3.8/site-packages/wheel [DEBUG _sync:52]
1485 copy directory /home/appveyor/.local/share/virtualenv/wheel/3.8/image/1/CopyPipInstall/wheel-0.35.1-py2.py3-none-any/wheel-0.35.1.dist-info to /cygdrive/c/projects/pywbem/test_py38/lib/python3.8/site-packages/wheel-0.35.1.dist-info [DEBUG _sync:52]
1509 copy /home/appveyor/.local/share/virtualenv/wheel/3.8/image/1/CopyPipInstall/wheel-0.35.1-py2.py3-none-any/wheel-0.35.1.virtualenv to /cygdrive/c/projects/pywbem/test_py38/lib/python3.8/site-packages/wheel-0.35.1.virtualenv [DEBUG _sync:52]
1523 generated console scripts wheel3 wheel3.8 wheel-3.8 wheel [DEBUG base:48]
1698 Attempting to release lock 123145287546336 on /home/appveyor/.local/share/virtualenv/wheel/3.8/image/1/CopyPipInstall/setuptools-50.3.0-py3-none-any.lock [DEBUG filelock:315]
1698 Lock 123145287546336 released on /home/appveyor/.local/share/virtualenv/wheel/3.8/image/1/CopyPipInstall/setuptools-50.3.0-py3-none-any.lock [INFO filelock:318]
1700 copy /home/appveyor/.local/share/virtualenv/wheel/3.8/image/1/CopyPipInstall/setuptools-50.3.0-py3-none-any/distutils-precedence.pth to /cygdrive/c/projects/pywbem/test_py38/lib/python3.8/site-packages/distutils-precedence.pth [DEBUG _sync:52]
1702 copy /home/appveyor/.local/share/virtualenv/wheel/3.8/image/1/CopyPipInstall/setuptools-50.3.0-py3-none-any/easy_install.py to /cygdrive/c/projects/pywbem/test_py38/lib/python3.8/site-packages/easy_install.py [DEBUG _sync:52]
1704 copy directory /home/appveyor/.local/share/virtualenv/wheel/3.8/image/1/CopyPipInstall/setuptools-50.3.0-py3-none-any/pkg_resources to /cygdrive/c/projects/pywbem/test_py38/lib/python3.8/site-packages/pkg_resources [DEBUG _sync:52]
1747 copy directory /home/appveyor/.local/share/virtualenv/wheel/3.8/image/1/CopyPipInstall/setuptools-50.3.0-py3-none-any/setuptools to /cygdrive/c/projects/pywbem/test_py38/lib/python3.8/site-packages/setuptools [DEBUG _sync:52]
2037 Attempting to release lock 123145287461520 on /home/appveyor/.local/share/virtualenv/wheel/3.8/image/1/CopyPipInstall/pip-20.2.3-py2.py3-none-any.lock [DEBUG filelock:315]
2038 Lock 123145287461520 released on /home/appveyor/.local/share/virtualenv/wheel/3.8/image/1/CopyPipInstall/pip-20.2.3-py2.py3-none-any.lock [INFO filelock:318]
2038 copy directory /home/appveyor/.local/share/virtualenv/wheel/3.8/image/1/CopyPipInstall/pip-20.2.3-py2.py3-none-any/pip to /cygdrive/c/projects/pywbem/test_py38/lib/python3.8/site-packages/pip [DEBUG _sync:52]
2152 copy directory /home/appveyor/.local/share/virtualenv/wheel/3.8/image/1/CopyPipInstall/setuptools-50.3.0-py3-none-any/setuptools-50.3.0.dist-info to /cygdrive/c/projects/pywbem/test_py38/lib/python3.8/site-packages/setuptools-50.3.0.dist-info [DEBUG _sync:52]
2168 copy /home/appveyor/.local/share/virtualenv/wheel/3.8/image/1/CopyPipInstall/setuptools-50.3.0-py3-none-any/setuptools-50.3.0.virtualenv to /cygdrive/c/projects/pywbem/test_py38/lib/python3.8/site-packages/setuptools-50.3.0.virtualenv [DEBUG _sync:52]
2170 copy directory /home/appveyor/.local/share/virtualenv/wheel/3.8/image/1/CopyPipInstall/setuptools-50.3.0-py3-none-any/_distutils_hack to /cygdrive/c/projects/pywbem/test_py38/lib/python3.8/site-packages/_distutils_hack [DEBUG _sync:52]
2179 generated console scripts easy_install3.8 easy_install3 easy_install easy_install-3.8 [DEBUG base:48]
3542 copy directory /home/appveyor/.local/share/virtualenv/wheel/3.8/image/1/CopyPipInstall/pip-20.2.3-py2.py3-none-any/pip-20.2.3.dist-info to /cygdrive/c/projects/pywbem/test_py38/lib/python3.8/site-packages/pip-20.2.3.dist-info [DEBUG _sync:52]
3549 copy /home/appveyor/.local/share/virtualenv/wheel/3.8/image/1/CopyPipInstall/pip-20.2.3-py2.py3-none-any/pip-20.2.3.virtualenv to /cygdrive/c/projects/pywbem/test_py38/lib/python3.8/site-packages/pip-20.2.3.virtualenv [DEBUG _sync:52]
3552 generated console scripts pip-3.8 pip3.8 pip3 pip [DEBUG base:48]
3552 add activators for Bash, CShell, Fish, PowerShell, Python, Xonsh [INFO session:64]
Traceback (most recent call last):
  File "/usr/lib/python3.8/runpy.py", line 194, in _run_module_as_main
    return _run_code(code, main_globals, None,
  File "/usr/lib/python3.8/runpy.py", line 87, in _run_code
    exec(code, run_globals)
  File "/usr/lib/python3.8/site-packages/virtualenv/__main__.py", line 77, in <module>
    run_with_catch()  # pragma: no cov
  File "/usr/lib/python3.8/site-packages/virtualenv/__main__.py", line 62, in run_with_catch
    run(args, options)
  File "/usr/lib/python3.8/site-packages/virtualenv/__main__.py", line 16, in run
    session = cli_run(args, options)
  File "/usr/lib/python3.8/site-packages/virtualenv/run/__init__.py", line 28, in cli_run
    of_session.run()
  File "/usr/lib/python3.8/site-packages/virtualenv/run/session.py", line 48, in run
    self._activate()
  File "/usr/lib/python3.8/site-packages/virtualenv/run/session.py", line 69, in _activate
    activator.generate(self.creator)
  File "/usr/lib/python3.8/site-packages/virtualenv/activation/via_template.py", line 29, in generate
    replacements = self.replacements(creator, dest_folder)
  File "/usr/lib/python3.8/site-packages/virtualenv/activation/via_template.py", line 41, in replacements
    virtual_env = "/" + match.group(1).lower() + match.group(2)
AttributeError: 'NoneType' object has no attribute 'group'
```

Here is the pip list from before invoking tox, i.e. in the environment when the above error happens:
```
pip 20.2.3 from /usr/lib/python3.8/site-packages/pip (python 3.8)
Package    Version
---------- -------
appdirs    1.4.4
distlib    0.3.1
filelock   3.0.12
packaging  20.4
pip        20.2.3
pluggy     0.13.1
py         1.9.0
pyparsing  2.4.7
setuptools 50.3.0
six        1.15.0
toml       0.10.1
tox        3.20.0
virtualenv 20.0.32
wheel      0.35.1
```

The above is both on CygWin with Python 3.8.
Appveyor run for the above: https://ci.appveyor.com/project/andy-maier/pywbem/builds/35526924/job/dhx7u89pe2tbebwu#L1045

cc @danyeaw seems https://github.com/pypa/virtualenv/pull/1952 introduced this
@gaborbernat thanks I'll take a look
Looking at the above log it seems the path is already cygwin formatted (``/cygdrive/c/projects/pywbem/test_py38/bin``), so we probably should not transform already good paths. 👍 If you can put in a PR to fix this today that would be much appreciated. Thanks!

Resolving patch:
diff --git a/src/virtualenv/activation/via_template.py b/src/virtualenv/activation/via_template.py
--- a/src/virtualenv/activation/via_template.py
+++ b/src/virtualenv/activation/via_template.py
@@ -38,7 +38,10 @@ def replacements(self, creator, dest_folder):
         if any(platform in current_platform for platform in platforms):
             pattern = re.compile("^([A-Za-z]):(.*)")
             match = pattern.match(str(creator.dest))
-            virtual_env = "/" + match.group(1).lower() + match.group(2)
+            if match:
+                virtual_env = "/" + match.group(1).lower() + match.group(2)
+            else:
+                virtual_env = str(creator.dest)
         else:
             virtual_env = str(creator.dest)
         return {


Test patch:
diff --git a/tests/unit/activation/test_activation_support.py b/tests/unit/activation/test_activation_support.py
--- a/tests/unit/activation/test_activation_support.py
+++ b/tests/unit/activation/test_activation_support.py
@@ -84,3 +84,16 @@ def test_win_path_no_conversion(mocker, activator_class):
     mocker.stub(creator.bin_dir.relative_to)
     resource = activator.replacements(creator, "")
     assert resource["__VIRTUAL_ENV__"] == "C:/tools/msys64/home"
+
+
+@pytest.mark.skipif(IS_WIN, reason="Github Actions ships with WSL bash")
+@pytest.mark.parametrize("activator_class", [BashActivator])
+def test_cygwin_path_no_conversion(mocker, activator_class):
+    mocker.patch("sysconfig.get_platform", return_value="cygwin")
+    activator = activator_class(Namespace(prompt=None))
+    creator = Creator()
+    creator.dest = "/c/tools/msys64/home"
+    creator.bin_dir = Path("/c/tools/msys64/home/bin")
+    mocker.stub(creator.bin_dir.relative_to)
+    resource = activator.replacements(creator, "")
+    assert resource["__VIRTUAL_ENV__"] == "/c/tools/msys64/home"