prompt: We are currently solving the following issue within our repository. Here is the issue text:
  --- BEGIN 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
  ```
  
  --- END ISSUE ---
  
  Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
  --- BEGIN FILES ---
  Path: `src/virtualenv/activation/via_template.py`
  Content:
  ```
  1 from __future__ import absolute_import, unicode_literals
  2 
  3 import os
  4 import re
  5 import sys
  6 import sysconfig
  7 from abc import ABCMeta, abstractmethod
  8 
  9 from six import add_metaclass
  10 
  11 from virtualenv.util.six import ensure_text
  12 
  13 from .activator import Activator
  14 
  15 if sys.version_info >= (3, 7):
  16     from importlib.resources import read_binary
  17 else:
  18     from importlib_resources import read_binary
  19 
  20 
  21 @add_metaclass(ABCMeta)
  22 class ViaTemplateActivator(Activator):
  23     @abstractmethod
  24     def templates(self):
  25         raise NotImplementedError
  26 
  27     def generate(self, creator):
  28         dest_folder = creator.bin_dir
  29         replacements = self.replacements(creator, dest_folder)
  30         generated = self._generate(replacements, self.templates(), dest_folder, creator)
  31         if self.flag_prompt is not None:
  32             creator.pyenv_cfg["prompt"] = self.flag_prompt
  33         return generated
  34 
  35     def replacements(self, creator, dest_folder):
  36         current_platform = sysconfig.get_platform()
  37         platforms = ["mingw", "cygwin", "msys"]
  38         if any(platform in current_platform for platform in platforms):
  39             pattern = re.compile("^([A-Za-z]):(.*)")
  40             match = pattern.match(str(creator.dest))
  41             virtual_env = "/" + match.group(1).lower() + match.group(2)
  42         else:
  43             virtual_env = str(creator.dest)
  44         return {
  45             "__VIRTUAL_PROMPT__": "" if self.flag_prompt is None else self.flag_prompt,
  46             "__VIRTUAL_ENV__": ensure_text(virtual_env),
  47             "__VIRTUAL_NAME__": creator.env_name,
  48             "__BIN_NAME__": ensure_text(str(creator.bin_dir.relative_to(creator.dest))),
  49             "__PATH_SEP__": ensure_text(os.pathsep),
  50         }
  51 
  52     def _generate(self, replacements, templates, to_folder, creator):
  53         generated = []
  54         for template in templates:
  55             text = self.instantiate_template(replacements, template, creator)
  56             dest = to_folder / self.as_name(template)
  57             # use write_bytes to avoid platform specific line normalization (\n -> \r\n)
  58             dest.write_bytes(text.encode("utf-8"))
  59             generated.append(dest)
  60         return generated
  61 
  62     def as_name(self, template):
  63         return template.name
  64 
  65     def instantiate_template(self, replacements, template, creator):
  66         # read content as binary to avoid platform specific line normalization (\n -> \r\n)
  67         binary = read_binary(self.__module__, str(template))
  68         text = binary.decode("utf-8", errors="strict")
  69         for key, value in replacements.items():
  70             value = self._repr_unicode(creator, value)
  71             text = text.replace(key, value)
  72         return text
  73 
  74     @staticmethod
  75     def _repr_unicode(creator, value):
  76         # by default we just let it be unicode
  77         return value
  78
  ```
  --- END FILES ---
  
  Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.
  
  Here is an example:
  
  ```diff
  diff --git a/examples/server_async.py b/examples/server_async.py
  --- a/examples/server_async.py
  +++ b/examples/server_async.py
  @@ -313,4 +313,4 @@
   
   
   if __name__ == "__main__":
  -    asyncio.run(run_async_server("."), debug=True)
  +    asyncio.run(run_async_server(), debug=True)
  diff --git a/examples/server_sync.py b/examples/server_sync.py
  --- a/examples/server_sync.py
  +++ b/examples/server_sync.py
  @@ -313,5 +313,5 @@
   
   
   if __name__ == "__main__":
  -    server = run_sync_server(".")
  +    server = run_sync_server()
       server.shutdown()
  
  ```
  
golden_diff: 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 @@
           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 {
  
verification_info: {"golden_diff": "diff --git a/src/virtualenv/activation/via_template.py b/src/virtualenv/activation/via_template.py\n--- a/src/virtualenv/activation/via_template.py\n+++ b/src/virtualenv/activation/via_template.py\n@@ -38,7 +38,10 @@\n         if any(platform in current_platform for platform in platforms):\n             pattern = re.compile(\"^([A-Za-z]):(.*)\")\n             match = pattern.match(str(creator.dest))\n-            virtual_env = \"/\" + match.group(1).lower() + match.group(2)\n+            if match:\n+                virtual_env = \"/\" + match.group(1).lower() + match.group(2)\n+            else:\n+                virtual_env = str(creator.dest)\n         else:\n             virtual_env = str(creator.dest)\n         return {\n", "issue": "AttributeError: 'NoneType' object has no attribute 'group' with virtualenv 20.0.32 on CygWin\n**Issue**\r\nWe 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.\r\nSince virtualenv 20.0.32 was released just 4h ago, I suspect that to be the culprit.\r\n\r\nFrom https://ci.appveyor.com/project/andy-maier/pywbem/builds/35526352/job/l3k6a2vb39bweqsw#L936:\r\n```\r\nif \"%UNIX_PATH%\"==\"C:\\cygwin64\\bin\" ( bash -c \"which tox && tox -vv -e %TOX_ENV% && echo appveyor.yml: tox rc=$?\" )\r\n/usr/bin/tox\r\nusing tox.ini: /cygdrive/c/projects/pywbem/tox.ini (pid 1822)\r\nusing tox-3.20.0 from /usr/lib/python3.8/site-packages/tox/__init__.py (pid 1822)\r\nskipping sdist step\r\ncygwin64_py38 uses /usr/bin/python3.8.exe\r\ncygwin64_py38 start: getenv /cygdrive/c/projects/pywbem/.tox/cygwin64_py38\r\ncygwin64_py38 cannot reuse: no previous config /cygdrive/c/projects/pywbem/.tox/cygwin64_py38/.tox-config1\r\ncygwin64_py38 create: /cygdrive/c/projects/pywbem/.tox/cygwin64_py38\r\nsetting PATH=/cygdrive/c/projects/pywbem/.tox/cygwin64_py38/bin:/usr/bin:/cygdrive/c/Windows/system32:/cygdrive/c/Windows:/cygdrive/c/ProgramData/chocolatey/bin\r\n[1825] /cygdrive/c/projects/pywbem/.tox$ /usr/bin/python3.8.exe -m virtualenv --no-download --python /usr/bin/python3.8.exe cygwin64_py38\r\nAttributeError: 'NoneType' object has no attribute 'group'\r\nERROR: invocation failed (exit code 1)\r\nERROR: InvocationError for command /usr/bin/python3.8.exe -m virtualenv --no-download --python /usr/bin/python3.8.exe cygwin64_py38 (exited with code 1)\r\ncygwin64_py38 finish: getenv /cygdrive/c/projects/pywbem/.tox/cygwin64_py38 after 4.23 seconds\r\n```\r\n\r\nI am setting up a direct invocation of virtualenv in that environment, in order to get the full traceback, and will post that here.\r\n\r\n**Environment**\r\n\r\nProvide at least:\r\n- OS: CygWin64\r\n- ``pip list`` of the host python where ``virtualenv`` is installed:\r\n  ```console\r\n  See next comment, below\r\n  ```\r\n\r\n**Output of the virtual environment creation**\r\n\r\nMake sure to run the creation with `-vvv --with-traceback`:\r\n\r\n```console\r\nSee next comment, below\r\n```\n", "before_files": [{"content": "from __future__ import absolute_import, unicode_literals\n\nimport os\nimport re\nimport sys\nimport sysconfig\nfrom abc import ABCMeta, abstractmethod\n\nfrom six import add_metaclass\n\nfrom virtualenv.util.six import ensure_text\n\nfrom .activator import Activator\n\nif sys.version_info >= (3, 7):\n    from importlib.resources import read_binary\nelse:\n    from importlib_resources import read_binary\n\n\n@add_metaclass(ABCMeta)\nclass ViaTemplateActivator(Activator):\n    @abstractmethod\n    def templates(self):\n        raise NotImplementedError\n\n    def generate(self, creator):\n        dest_folder = creator.bin_dir\n        replacements = self.replacements(creator, dest_folder)\n        generated = self._generate(replacements, self.templates(), dest_folder, creator)\n        if self.flag_prompt is not None:\n            creator.pyenv_cfg[\"prompt\"] = self.flag_prompt\n        return generated\n\n    def replacements(self, creator, dest_folder):\n        current_platform = sysconfig.get_platform()\n        platforms = [\"mingw\", \"cygwin\", \"msys\"]\n        if any(platform in current_platform for platform in platforms):\n            pattern = re.compile(\"^([A-Za-z]):(.*)\")\n            match = pattern.match(str(creator.dest))\n            virtual_env = \"/\" + match.group(1).lower() + match.group(2)\n        else:\n            virtual_env = str(creator.dest)\n        return {\n            \"__VIRTUAL_PROMPT__\": \"\" if self.flag_prompt is None else self.flag_prompt,\n            \"__VIRTUAL_ENV__\": ensure_text(virtual_env),\n            \"__VIRTUAL_NAME__\": creator.env_name,\n            \"__BIN_NAME__\": ensure_text(str(creator.bin_dir.relative_to(creator.dest))),\n            \"__PATH_SEP__\": ensure_text(os.pathsep),\n        }\n\n    def _generate(self, replacements, templates, to_folder, creator):\n        generated = []\n        for template in templates:\n            text = self.instantiate_template(replacements, template, creator)\n            dest = to_folder / self.as_name(template)\n            # use write_bytes to avoid platform specific line normalization (\\n -> \\r\\n)\n            dest.write_bytes(text.encode(\"utf-8\"))\n            generated.append(dest)\n        return generated\n\n    def as_name(self, template):\n        return template.name\n\n    def instantiate_template(self, replacements, template, creator):\n        # read content as binary to avoid platform specific line normalization (\\n -> \\r\\n)\n        binary = read_binary(self.__module__, str(template))\n        text = binary.decode(\"utf-8\", errors=\"strict\")\n        for key, value in replacements.items():\n            value = self._repr_unicode(creator, value)\n            text = text.replace(key, value)\n        return text\n\n    @staticmethod\n    def _repr_unicode(creator, value):\n        # by default we just let it be unicode\n        return value\n", "path": "src/virtualenv/activation/via_template.py"}], "after_files": [{"content": "from __future__ import absolute_import, unicode_literals\n\nimport os\nimport re\nimport sys\nimport sysconfig\nfrom abc import ABCMeta, abstractmethod\n\nfrom six import add_metaclass\n\nfrom virtualenv.util.six import ensure_text\n\nfrom .activator import Activator\n\nif sys.version_info >= (3, 7):\n    from importlib.resources import read_binary\nelse:\n    from importlib_resources import read_binary\n\n\n@add_metaclass(ABCMeta)\nclass ViaTemplateActivator(Activator):\n    @abstractmethod\n    def templates(self):\n        raise NotImplementedError\n\n    def generate(self, creator):\n        dest_folder = creator.bin_dir\n        replacements = self.replacements(creator, dest_folder)\n        generated = self._generate(replacements, self.templates(), dest_folder, creator)\n        if self.flag_prompt is not None:\n            creator.pyenv_cfg[\"prompt\"] = self.flag_prompt\n        return generated\n\n    def replacements(self, creator, dest_folder):\n        current_platform = sysconfig.get_platform()\n        platforms = [\"mingw\", \"cygwin\", \"msys\"]\n        if any(platform in current_platform for platform in platforms):\n            pattern = re.compile(\"^([A-Za-z]):(.*)\")\n            match = pattern.match(str(creator.dest))\n            if match:\n                virtual_env = \"/\" + match.group(1).lower() + match.group(2)\n            else:\n                virtual_env = str(creator.dest)\n        else:\n            virtual_env = str(creator.dest)\n        return {\n            \"__VIRTUAL_PROMPT__\": \"\" if self.flag_prompt is None else self.flag_prompt,\n            \"__VIRTUAL_ENV__\": ensure_text(virtual_env),\n            \"__VIRTUAL_NAME__\": creator.env_name,\n            \"__BIN_NAME__\": ensure_text(str(creator.bin_dir.relative_to(creator.dest))),\n            \"__PATH_SEP__\": ensure_text(os.pathsep),\n        }\n\n    def _generate(self, replacements, templates, to_folder, creator):\n        generated = []\n        for template in templates:\n            text = self.instantiate_template(replacements, template, creator)\n            dest = to_folder / self.as_name(template)\n            # use write_bytes to avoid platform specific line normalization (\\n -> \\r\\n)\n            dest.write_bytes(text.encode(\"utf-8\"))\n            generated.append(dest)\n        return generated\n\n    def as_name(self, template):\n        return template.name\n\n    def instantiate_template(self, replacements, template, creator):\n        # read content as binary to avoid platform specific line normalization (\\n -> \\r\\n)\n        binary = read_binary(self.__module__, str(template))\n        text = binary.decode(\"utf-8\", errors=\"strict\")\n        for key, value in replacements.items():\n            value = self._repr_unicode(creator, value)\n            text = text.replace(key, value)\n        return text\n\n    @staticmethod\n    def _repr_unicode(creator, value):\n        # by default we just let it be unicode\n        return value\n", "path": "src/virtualenv/activation/via_template.py"}]}