We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
20b1 feedback: Unable to generate bash "activate" script on Windows.
Hello!

Working on Windows 10, using Git Bash as my default shell pretty much everywhere.

From my understanding, the bash activation script is not generated by default on Windows anymore.
That's going to break users in a similar solution to mine.

But the really bad news for me:
```
$ python -m virtualenv --activators bash myvirtualenv
usage: virtualenv [--version] [-v | -q] [--discovery {builtin}] [-p py] [--creator {builtin,cpython2-win}] [--seeder {app-data,none,pip}] [--without-pip] [--activators comma_separated_list]
virtualenv: error: argument --activators: the following activators are not available bash
```
`bash` is considered not available on Windows, and that's a no-go for me, or anyone using a bash equivalent on Windows.

I'd plead for keeping bash script by default on Windows.
Or at the very least, allow it as an option, although its still going to be a pain.

Cheers!



--- 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/bash/__init__.py`
Content:
```
1 from __future__ import absolute_import, unicode_literals
2 
3 from virtualenv.util.path import Path
4 
5 from ..via_template import ViaTemplateActivator
6 
7 
8 class BashActivator(ViaTemplateActivator):
9     @classmethod
10     def supports(cls, interpreter):
11         return interpreter.os != "nt"
12 
13     def templates(self):
14         yield Path("activate.sh")
15 
16     def as_name(self, template):
17         return template.stem
18
```

Path: `src/virtualenv/activation/fish/__init__.py`
Content:
```
1 from __future__ import absolute_import, unicode_literals
2 
3 from virtualenv.util.path import Path
4 
5 from ..via_template import ViaTemplateActivator
6 
7 
8 class FishActivator(ViaTemplateActivator):
9     def templates(self):
10         yield Path("activate.fish")
11 
12     @classmethod
13     def supports(cls, interpreter):
14         return interpreter.os != "nt"
15
```

Path: `src/virtualenv/util/subprocess/_win_subprocess.py`
Content:
```
1 # flake8: noqa
2 # fmt: off
3 ## issue: https://bugs.python.org/issue19264
4 
5 import ctypes
6 import os
7 import subprocess
8 from ctypes import Structure, WinError, byref, c_char_p, c_void_p, c_wchar, c_wchar_p, sizeof, windll
9 from ctypes.wintypes import BOOL, BYTE, DWORD, HANDLE, LPVOID, LPWSTR, WORD
10 
11 import _subprocess
12 
13 ##
14 ## Types
15 ##
16 
17 CREATE_UNICODE_ENVIRONMENT = 0x00000400
18 LPCTSTR = c_char_p
19 LPTSTR = c_wchar_p
20 LPSECURITY_ATTRIBUTES = c_void_p
21 LPBYTE  = ctypes.POINTER(BYTE)
22 
23 class STARTUPINFOW(Structure):
24     _fields_ = [
25         ("cb",              DWORD),  ("lpReserved",    LPWSTR),
26         ("lpDesktop",       LPWSTR), ("lpTitle",       LPWSTR),
27         ("dwX",             DWORD),  ("dwY",           DWORD),
28         ("dwXSize",         DWORD),  ("dwYSize",       DWORD),
29         ("dwXCountChars",   DWORD),  ("dwYCountChars", DWORD),
30         ("dwFillAtrribute", DWORD),  ("dwFlags",       DWORD),
31         ("wShowWindow",     WORD),   ("cbReserved2",   WORD),
32         ("lpReserved2",     LPBYTE), ("hStdInput",     HANDLE),
33         ("hStdOutput",      HANDLE), ("hStdError",     HANDLE),
34     ]
35 
36 LPSTARTUPINFOW = ctypes.POINTER(STARTUPINFOW)
37 
38 
39 class PROCESS_INFORMATION(Structure):
40     _fields_ = [
41         ("hProcess",         HANDLE), ("hThread",          HANDLE),
42         ("dwProcessId",      DWORD),  ("dwThreadId",       DWORD),
43     ]
44 
45 LPPROCESS_INFORMATION = ctypes.POINTER(PROCESS_INFORMATION)
46 
47 
48 class DUMMY_HANDLE(ctypes.c_void_p):
49 
50     def __init__(self, *a, **kw):
51         super(DUMMY_HANDLE, self).__init__(*a, **kw)
52         self.closed = False
53 
54     def Close(self):
55         if not self.closed:
56             windll.kernel32.CloseHandle(self)
57             self.closed = True
58 
59     def __int__(self):
60         return self.value
61 
62 
63 CreateProcessW = windll.kernel32.CreateProcessW
64 CreateProcessW.argtypes = [
65     LPCTSTR, LPTSTR, LPSECURITY_ATTRIBUTES,
66     LPSECURITY_ATTRIBUTES, BOOL, DWORD, LPVOID, LPCTSTR,
67     LPSTARTUPINFOW, LPPROCESS_INFORMATION,
68 ]
69 CreateProcessW.restype = BOOL
70 
71 
72 ##
73 ## Patched functions/classes
74 ##
75 
76 def CreateProcess(executable, args, _p_attr, _t_attr,
77                   inherit_handles, creation_flags, env, cwd,
78                   startup_info):
79     """Create a process supporting unicode executable and args for win32
80 
81     Python implementation of CreateProcess using CreateProcessW for Win32
82 
83     """
84 
85     si = STARTUPINFOW(
86         dwFlags=startup_info.dwFlags,
87         wShowWindow=startup_info.wShowWindow,
88         cb=sizeof(STARTUPINFOW),
89         ## XXXvlab: not sure of the casting here to ints.
90         hStdInput=startup_info.hStdInput if startup_info.hStdInput is None else int(startup_info.hStdInput),
91         hStdOutput=startup_info.hStdOutput if startup_info.hStdOutput is None else int(startup_info.hStdOutput),
92         hStdError=startup_info.hStdError if startup_info.hStdError is None else int(startup_info.hStdError),
93     )
94 
95     wenv = None
96     if env is not None:
97         ## LPCWSTR seems to be c_wchar_p, so let's say CWSTR is c_wchar
98         env = (unicode("").join([
99             unicode("%s=%s\0") % (k, v)
100             for k, v in env.items()])) + unicode("\0")
101         wenv = (c_wchar * len(env))()
102         wenv.value = env
103 
104     pi = PROCESS_INFORMATION()
105     creation_flags |= CREATE_UNICODE_ENVIRONMENT
106 
107     if CreateProcessW(executable, args, None, None,
108                       inherit_handles, creation_flags,
109                       wenv, cwd, byref(si), byref(pi)):
110         return (DUMMY_HANDLE(pi.hProcess), DUMMY_HANDLE(pi.hThread),
111                 pi.dwProcessId, pi.dwThreadId)
112     raise WinError()
113 
114 
115 class Popen(subprocess.Popen):
116     """This superseeds Popen and corrects a bug in cPython 2.7 implem"""
117 
118     def _execute_child(self, args, executable, preexec_fn, close_fds,
119                        cwd, env, universal_newlines,
120                        startupinfo, creationflags, shell, to_close,
121                        p2cread, p2cwrite,
122                        c2pread, c2pwrite,
123                        errread, errwrite):
124         """Code from part of _execute_child from Python 2.7 (9fbb65e)
125 
126         There are only 2 little changes concerning the construction of
127         the the final string in shell mode: we preempt the creation of
128         the command string when shell is True, because original function
129         will try to encode unicode args which we want to avoid to be able to
130         sending it as-is to ``CreateProcess``.
131 
132         """
133         if startupinfo is None:
134             startupinfo = subprocess.STARTUPINFO()
135         if not isinstance(args, subprocess.types.StringTypes):
136             args = subprocess.list2cmdline(args)
137         startupinfo.dwFlags |= _subprocess.STARTF_USESHOWWINDOW
138         startupinfo.wShowWindow = _subprocess.SW_HIDE
139         comspec = os.environ.get("COMSPEC", unicode("cmd.exe"))
140         if (_subprocess.GetVersion() >= 0x80000000 or
141                 os.path.basename(comspec).lower() == "command.com"):
142             w9xpopen = self._find_w9xpopen()
143             args = unicode('"%s" %s') % (w9xpopen, args)
144             creationflags |= _subprocess.CREATE_NEW_CONSOLE
145 
146         super(Popen, self)._execute_child(args, executable,
147             preexec_fn, close_fds, cwd, env, universal_newlines,
148             startupinfo, creationflags, False, to_close, p2cread,
149             p2cwrite, c2pread, c2pwrite, errread, errwrite)
150 
151 _subprocess.CreateProcess = CreateProcess
152 # fmt: on
153
```
--- 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()

```

diff --git a/src/virtualenv/activation/bash/__init__.py b/src/virtualenv/activation/bash/__init__.py
--- a/src/virtualenv/activation/bash/__init__.py
+++ b/src/virtualenv/activation/bash/__init__.py
@@ -6,10 +6,6 @@
 
 
 class BashActivator(ViaTemplateActivator):
-    @classmethod
-    def supports(cls, interpreter):
-        return interpreter.os != "nt"
-
     def templates(self):
         yield Path("activate.sh")
 
diff --git a/src/virtualenv/activation/fish/__init__.py b/src/virtualenv/activation/fish/__init__.py
--- a/src/virtualenv/activation/fish/__init__.py
+++ b/src/virtualenv/activation/fish/__init__.py
@@ -8,7 +8,3 @@
 class FishActivator(ViaTemplateActivator):
     def templates(self):
         yield Path("activate.fish")
-
-    @classmethod
-    def supports(cls, interpreter):
-        return interpreter.os != "nt"
diff --git a/src/virtualenv/util/subprocess/_win_subprocess.py b/src/virtualenv/util/subprocess/_win_subprocess.py
--- a/src/virtualenv/util/subprocess/_win_subprocess.py
+++ b/src/virtualenv/util/subprocess/_win_subprocess.py
@@ -4,6 +4,7 @@
 
 import ctypes
 import os
+import platform
 import subprocess
 from ctypes import Structure, WinError, byref, c_char_p, c_void_p, c_wchar, c_wchar_p, sizeof, windll
 from ctypes.wintypes import BOOL, BYTE, DWORD, HANDLE, LPVOID, LPWSTR, WORD
@@ -133,7 +134,10 @@
         if startupinfo is None:
             startupinfo = subprocess.STARTUPINFO()
         if not isinstance(args, subprocess.types.StringTypes):
+            args = [i if isinstance(i, bytes) else i.encode('utf-8') for i in args]
             args = subprocess.list2cmdline(args)
+            if platform.python_implementation() == "CPython":
+                args = args.decode('utf-8')
         startupinfo.dwFlags |= _subprocess.STARTF_USESHOWWINDOW
         startupinfo.wShowWindow = _subprocess.SW_HIDE
         comspec = os.environ.get("COMSPEC", unicode("cmd.exe"))

{"golden_diff": "diff --git a/src/virtualenv/activation/bash/__init__.py b/src/virtualenv/activation/bash/__init__.py\n--- a/src/virtualenv/activation/bash/__init__.py\n+++ b/src/virtualenv/activation/bash/__init__.py\n@@ -6,10 +6,6 @@\n \n \n class BashActivator(ViaTemplateActivator):\n-    @classmethod\n-    def supports(cls, interpreter):\n-        return interpreter.os != \"nt\"\n-\n     def templates(self):\n         yield Path(\"activate.sh\")\n \ndiff --git a/src/virtualenv/activation/fish/__init__.py b/src/virtualenv/activation/fish/__init__.py\n--- a/src/virtualenv/activation/fish/__init__.py\n+++ b/src/virtualenv/activation/fish/__init__.py\n@@ -8,7 +8,3 @@\n class FishActivator(ViaTemplateActivator):\n     def templates(self):\n         yield Path(\"activate.fish\")\n-\n-    @classmethod\n-    def supports(cls, interpreter):\n-        return interpreter.os != \"nt\"\ndiff --git a/src/virtualenv/util/subprocess/_win_subprocess.py b/src/virtualenv/util/subprocess/_win_subprocess.py\n--- a/src/virtualenv/util/subprocess/_win_subprocess.py\n+++ b/src/virtualenv/util/subprocess/_win_subprocess.py\n@@ -4,6 +4,7 @@\n \n import ctypes\n import os\n+import platform\n import subprocess\n from ctypes import Structure, WinError, byref, c_char_p, c_void_p, c_wchar, c_wchar_p, sizeof, windll\n from ctypes.wintypes import BOOL, BYTE, DWORD, HANDLE, LPVOID, LPWSTR, WORD\n@@ -133,7 +134,10 @@\n         if startupinfo is None:\n             startupinfo = subprocess.STARTUPINFO()\n         if not isinstance(args, subprocess.types.StringTypes):\n+            args = [i if isinstance(i, bytes) else i.encode('utf-8') for i in args]\n             args = subprocess.list2cmdline(args)\n+            if platform.python_implementation() == \"CPython\":\n+                args = args.decode('utf-8')\n         startupinfo.dwFlags |= _subprocess.STARTF_USESHOWWINDOW\n         startupinfo.wShowWindow = _subprocess.SW_HIDE\n         comspec = os.environ.get(\"COMSPEC\", unicode(\"cmd.exe\"))\n", "issue": "20b1 feedback: Unable to generate bash \"activate\" script on Windows.\nHello!\r\n\r\nWorking on Windows 10, using Git Bash as my default shell pretty much everywhere.\r\n\r\nFrom my understanding, the bash activation script is not generated by default on Windows anymore.\r\nThat's going to break users in a similar solution to mine.\r\n\r\nBut the really bad news for me:\r\n```\r\n$ python -m virtualenv --activators bash myvirtualenv\r\nusage: virtualenv [--version] [-v | -q] [--discovery {builtin}] [-p py] [--creator {builtin,cpython2-win}] [--seeder {app-data,none,pip}] [--without-pip] [--activators comma_separated_list]\r\nvirtualenv: error: argument --activators: the following activators are not available bash\r\n```\r\n`bash` is considered not available on Windows, and that's a no-go for me, or anyone using a bash equivalent on Windows.\r\n\r\nI'd plead for keeping bash script by default on Windows.\r\nOr at the very least, allow it as an option, although its still going to be a pain.\r\n\r\nCheers!\r\n\r\n\n", "before_files": [{"content": "from __future__ import absolute_import, unicode_literals\n\nfrom virtualenv.util.path import Path\n\nfrom ..via_template import ViaTemplateActivator\n\n\nclass BashActivator(ViaTemplateActivator):\n    @classmethod\n    def supports(cls, interpreter):\n        return interpreter.os != \"nt\"\n\n    def templates(self):\n        yield Path(\"activate.sh\")\n\n    def as_name(self, template):\n        return template.stem\n", "path": "src/virtualenv/activation/bash/__init__.py"}, {"content": "from __future__ import absolute_import, unicode_literals\n\nfrom virtualenv.util.path import Path\n\nfrom ..via_template import ViaTemplateActivator\n\n\nclass FishActivator(ViaTemplateActivator):\n    def templates(self):\n        yield Path(\"activate.fish\")\n\n    @classmethod\n    def supports(cls, interpreter):\n        return interpreter.os != \"nt\"\n", "path": "src/virtualenv/activation/fish/__init__.py"}, {"content": "# flake8: noqa\n# fmt: off\n## issue: https://bugs.python.org/issue19264\n\nimport ctypes\nimport os\nimport subprocess\nfrom ctypes import Structure, WinError, byref, c_char_p, c_void_p, c_wchar, c_wchar_p, sizeof, windll\nfrom ctypes.wintypes import BOOL, BYTE, DWORD, HANDLE, LPVOID, LPWSTR, WORD\n\nimport _subprocess\n\n##\n## Types\n##\n\nCREATE_UNICODE_ENVIRONMENT = 0x00000400\nLPCTSTR = c_char_p\nLPTSTR = c_wchar_p\nLPSECURITY_ATTRIBUTES = c_void_p\nLPBYTE  = ctypes.POINTER(BYTE)\n\nclass STARTUPINFOW(Structure):\n    _fields_ = [\n        (\"cb\",              DWORD),  (\"lpReserved\",    LPWSTR),\n        (\"lpDesktop\",       LPWSTR), (\"lpTitle\",       LPWSTR),\n        (\"dwX\",             DWORD),  (\"dwY\",           DWORD),\n        (\"dwXSize\",         DWORD),  (\"dwYSize\",       DWORD),\n        (\"dwXCountChars\",   DWORD),  (\"dwYCountChars\", DWORD),\n        (\"dwFillAtrribute\", DWORD),  (\"dwFlags\",       DWORD),\n        (\"wShowWindow\",     WORD),   (\"cbReserved2\",   WORD),\n        (\"lpReserved2\",     LPBYTE), (\"hStdInput\",     HANDLE),\n        (\"hStdOutput\",      HANDLE), (\"hStdError\",     HANDLE),\n    ]\n\nLPSTARTUPINFOW = ctypes.POINTER(STARTUPINFOW)\n\n\nclass PROCESS_INFORMATION(Structure):\n    _fields_ = [\n        (\"hProcess\",         HANDLE), (\"hThread\",          HANDLE),\n        (\"dwProcessId\",      DWORD),  (\"dwThreadId\",       DWORD),\n    ]\n\nLPPROCESS_INFORMATION = ctypes.POINTER(PROCESS_INFORMATION)\n\n\nclass DUMMY_HANDLE(ctypes.c_void_p):\n\n    def __init__(self, *a, **kw):\n        super(DUMMY_HANDLE, self).__init__(*a, **kw)\n        self.closed = False\n\n    def Close(self):\n        if not self.closed:\n            windll.kernel32.CloseHandle(self)\n            self.closed = True\n\n    def __int__(self):\n        return self.value\n\n\nCreateProcessW = windll.kernel32.CreateProcessW\nCreateProcessW.argtypes = [\n    LPCTSTR, LPTSTR, LPSECURITY_ATTRIBUTES,\n    LPSECURITY_ATTRIBUTES, BOOL, DWORD, LPVOID, LPCTSTR,\n    LPSTARTUPINFOW, LPPROCESS_INFORMATION,\n]\nCreateProcessW.restype = BOOL\n\n\n##\n## Patched functions/classes\n##\n\ndef CreateProcess(executable, args, _p_attr, _t_attr,\n                  inherit_handles, creation_flags, env, cwd,\n                  startup_info):\n    \"\"\"Create a process supporting unicode executable and args for win32\n\n    Python implementation of CreateProcess using CreateProcessW for Win32\n\n    \"\"\"\n\n    si = STARTUPINFOW(\n        dwFlags=startup_info.dwFlags,\n        wShowWindow=startup_info.wShowWindow,\n        cb=sizeof(STARTUPINFOW),\n        ## XXXvlab: not sure of the casting here to ints.\n        hStdInput=startup_info.hStdInput if startup_info.hStdInput is None else int(startup_info.hStdInput),\n        hStdOutput=startup_info.hStdOutput if startup_info.hStdOutput is None else int(startup_info.hStdOutput),\n        hStdError=startup_info.hStdError if startup_info.hStdError is None else int(startup_info.hStdError),\n    )\n\n    wenv = None\n    if env is not None:\n        ## LPCWSTR seems to be c_wchar_p, so let's say CWSTR is c_wchar\n        env = (unicode(\"\").join([\n            unicode(\"%s=%s\\0\") % (k, v)\n            for k, v in env.items()])) + unicode(\"\\0\")\n        wenv = (c_wchar * len(env))()\n        wenv.value = env\n\n    pi = PROCESS_INFORMATION()\n    creation_flags |= CREATE_UNICODE_ENVIRONMENT\n\n    if CreateProcessW(executable, args, None, None,\n                      inherit_handles, creation_flags,\n                      wenv, cwd, byref(si), byref(pi)):\n        return (DUMMY_HANDLE(pi.hProcess), DUMMY_HANDLE(pi.hThread),\n                pi.dwProcessId, pi.dwThreadId)\n    raise WinError()\n\n\nclass Popen(subprocess.Popen):\n    \"\"\"This superseeds Popen and corrects a bug in cPython 2.7 implem\"\"\"\n\n    def _execute_child(self, args, executable, preexec_fn, close_fds,\n                       cwd, env, universal_newlines,\n                       startupinfo, creationflags, shell, to_close,\n                       p2cread, p2cwrite,\n                       c2pread, c2pwrite,\n                       errread, errwrite):\n        \"\"\"Code from part of _execute_child from Python 2.7 (9fbb65e)\n\n        There are only 2 little changes concerning the construction of\n        the the final string in shell mode: we preempt the creation of\n        the command string when shell is True, because original function\n        will try to encode unicode args which we want to avoid to be able to\n        sending it as-is to ``CreateProcess``.\n\n        \"\"\"\n        if startupinfo is None:\n            startupinfo = subprocess.STARTUPINFO()\n        if not isinstance(args, subprocess.types.StringTypes):\n            args = subprocess.list2cmdline(args)\n        startupinfo.dwFlags |= _subprocess.STARTF_USESHOWWINDOW\n        startupinfo.wShowWindow = _subprocess.SW_HIDE\n        comspec = os.environ.get(\"COMSPEC\", unicode(\"cmd.exe\"))\n        if (_subprocess.GetVersion() >= 0x80000000 or\n                os.path.basename(comspec).lower() == \"command.com\"):\n            w9xpopen = self._find_w9xpopen()\n            args = unicode('\"%s\" %s') % (w9xpopen, args)\n            creationflags |= _subprocess.CREATE_NEW_CONSOLE\n\n        super(Popen, self)._execute_child(args, executable,\n            preexec_fn, close_fds, cwd, env, universal_newlines,\n            startupinfo, creationflags, False, to_close, p2cread,\n            p2cwrite, c2pread, c2pwrite, errread, errwrite)\n\n_subprocess.CreateProcess = CreateProcess\n# fmt: on\n", "path": "src/virtualenv/util/subprocess/_win_subprocess.py"}], "after_files": [{"content": "from __future__ import absolute_import, unicode_literals\n\nfrom virtualenv.util.path import Path\n\nfrom ..via_template import ViaTemplateActivator\n\n\nclass BashActivator(ViaTemplateActivator):\n    def templates(self):\n        yield Path(\"activate.sh\")\n\n    def as_name(self, template):\n        return template.stem\n", "path": "src/virtualenv/activation/bash/__init__.py"}, {"content": "from __future__ import absolute_import, unicode_literals\n\nfrom virtualenv.util.path import Path\n\nfrom ..via_template import ViaTemplateActivator\n\n\nclass FishActivator(ViaTemplateActivator):\n    def templates(self):\n        yield Path(\"activate.fish\")\n", "path": "src/virtualenv/activation/fish/__init__.py"}, {"content": "# flake8: noqa\n# fmt: off\n## issue: https://bugs.python.org/issue19264\n\nimport ctypes\nimport os\nimport platform\nimport subprocess\nfrom ctypes import Structure, WinError, byref, c_char_p, c_void_p, c_wchar, c_wchar_p, sizeof, windll\nfrom ctypes.wintypes import BOOL, BYTE, DWORD, HANDLE, LPVOID, LPWSTR, WORD\n\nimport _subprocess\n\n##\n## Types\n##\n\nCREATE_UNICODE_ENVIRONMENT = 0x00000400\nLPCTSTR = c_char_p\nLPTSTR = c_wchar_p\nLPSECURITY_ATTRIBUTES = c_void_p\nLPBYTE  = ctypes.POINTER(BYTE)\n\nclass STARTUPINFOW(Structure):\n    _fields_ = [\n        (\"cb\",              DWORD),  (\"lpReserved\",    LPWSTR),\n        (\"lpDesktop\",       LPWSTR), (\"lpTitle\",       LPWSTR),\n        (\"dwX\",             DWORD),  (\"dwY\",           DWORD),\n        (\"dwXSize\",         DWORD),  (\"dwYSize\",       DWORD),\n        (\"dwXCountChars\",   DWORD),  (\"dwYCountChars\", DWORD),\n        (\"dwFillAtrribute\", DWORD),  (\"dwFlags\",       DWORD),\n        (\"wShowWindow\",     WORD),   (\"cbReserved2\",   WORD),\n        (\"lpReserved2\",     LPBYTE), (\"hStdInput\",     HANDLE),\n        (\"hStdOutput\",      HANDLE), (\"hStdError\",     HANDLE),\n    ]\n\nLPSTARTUPINFOW = ctypes.POINTER(STARTUPINFOW)\n\n\nclass PROCESS_INFORMATION(Structure):\n    _fields_ = [\n        (\"hProcess\",         HANDLE), (\"hThread\",          HANDLE),\n        (\"dwProcessId\",      DWORD),  (\"dwThreadId\",       DWORD),\n    ]\n\nLPPROCESS_INFORMATION = ctypes.POINTER(PROCESS_INFORMATION)\n\n\nclass DUMMY_HANDLE(ctypes.c_void_p):\n\n    def __init__(self, *a, **kw):\n        super(DUMMY_HANDLE, self).__init__(*a, **kw)\n        self.closed = False\n\n    def Close(self):\n        if not self.closed:\n            windll.kernel32.CloseHandle(self)\n            self.closed = True\n\n    def __int__(self):\n        return self.value\n\n\nCreateProcessW = windll.kernel32.CreateProcessW\nCreateProcessW.argtypes = [\n    LPCTSTR, LPTSTR, LPSECURITY_ATTRIBUTES,\n    LPSECURITY_ATTRIBUTES, BOOL, DWORD, LPVOID, LPCTSTR,\n    LPSTARTUPINFOW, LPPROCESS_INFORMATION,\n]\nCreateProcessW.restype = BOOL\n\n\n##\n## Patched functions/classes\n##\n\ndef CreateProcess(executable, args, _p_attr, _t_attr,\n                  inherit_handles, creation_flags, env, cwd,\n                  startup_info):\n    \"\"\"Create a process supporting unicode executable and args for win32\n\n    Python implementation of CreateProcess using CreateProcessW for Win32\n\n    \"\"\"\n\n    si = STARTUPINFOW(\n        dwFlags=startup_info.dwFlags,\n        wShowWindow=startup_info.wShowWindow,\n        cb=sizeof(STARTUPINFOW),\n        ## XXXvlab: not sure of the casting here to ints.\n        hStdInput=startup_info.hStdInput if startup_info.hStdInput is None else int(startup_info.hStdInput),\n        hStdOutput=startup_info.hStdOutput if startup_info.hStdOutput is None else int(startup_info.hStdOutput),\n        hStdError=startup_info.hStdError if startup_info.hStdError is None else int(startup_info.hStdError),\n    )\n\n    wenv = None\n    if env is not None:\n        ## LPCWSTR seems to be c_wchar_p, so let's say CWSTR is c_wchar\n        env = (unicode(\"\").join([\n            unicode(\"%s=%s\\0\") % (k, v)\n            for k, v in env.items()])) + unicode(\"\\0\")\n        wenv = (c_wchar * len(env))()\n        wenv.value = env\n\n    pi = PROCESS_INFORMATION()\n    creation_flags |= CREATE_UNICODE_ENVIRONMENT\n\n    if CreateProcessW(executable, args, None, None,\n                      inherit_handles, creation_flags,\n                      wenv, cwd, byref(si), byref(pi)):\n        return (DUMMY_HANDLE(pi.hProcess), DUMMY_HANDLE(pi.hThread),\n                pi.dwProcessId, pi.dwThreadId)\n    raise WinError()\n\n\nclass Popen(subprocess.Popen):\n    \"\"\"This superseeds Popen and corrects a bug in cPython 2.7 implem\"\"\"\n\n    def _execute_child(self, args, executable, preexec_fn, close_fds,\n                       cwd, env, universal_newlines,\n                       startupinfo, creationflags, shell, to_close,\n                       p2cread, p2cwrite,\n                       c2pread, c2pwrite,\n                       errread, errwrite):\n        \"\"\"Code from part of _execute_child from Python 2.7 (9fbb65e)\n\n        There are only 2 little changes concerning the construction of\n        the the final string in shell mode: we preempt the creation of\n        the command string when shell is True, because original function\n        will try to encode unicode args which we want to avoid to be able to\n        sending it as-is to ``CreateProcess``.\n\n        \"\"\"\n        if startupinfo is None:\n            startupinfo = subprocess.STARTUPINFO()\n        if not isinstance(args, subprocess.types.StringTypes):\n            args = [i if isinstance(i, bytes) else i.encode('utf-8') for i in args]\n            args = subprocess.list2cmdline(args)\n            if platform.python_implementation() == \"CPython\":\n                args = args.decode('utf-8')\n        startupinfo.dwFlags |= _subprocess.STARTF_USESHOWWINDOW\n        startupinfo.wShowWindow = _subprocess.SW_HIDE\n        comspec = os.environ.get(\"COMSPEC\", unicode(\"cmd.exe\"))\n        if (_subprocess.GetVersion() >= 0x80000000 or\n                os.path.basename(comspec).lower() == \"command.com\"):\n            w9xpopen = self._find_w9xpopen()\n            args = unicode('\"%s\" %s') % (w9xpopen, args)\n            creationflags |= _subprocess.CREATE_NEW_CONSOLE\n\n        super(Popen, self)._execute_child(args, executable,\n            preexec_fn, close_fds, cwd, env, universal_newlines,\n            startupinfo, creationflags, False, to_close, p2cread,\n            p2cwrite, c2pread, c2pwrite, errread, errwrite)\n\n_subprocess.CreateProcess = CreateProcess\n# fmt: on\n", "path": "src/virtualenv/util/subprocess/_win_subprocess.py"}]}