Skip to content

Commit

Permalink
Fix Windows subprocess calls with cwd are broken
Browse files Browse the repository at this point in the history
Signed-off-by: Bernát Gábor <bgabor8@bloomberg.net>
  • Loading branch information
gaborbernat committed Oct 15, 2020
1 parent 644bb08 commit 58b7edc
Show file tree
Hide file tree
Showing 4 changed files with 27 additions and 5 deletions.
2 changes: 1 addition & 1 deletion docs/changelog/1982.bugfix.rst
Original file line number Diff line number Diff line change
@@ -1 +1 @@
Bump embeded setuptools from ``50.3.0`` to ``50.3.1`` - by :user:`gaborbernat`.
Bump embedded setuptools from ``50.3.0`` to ``50.3.1`` - by :user:`gaborbernat`.
1 change: 1 addition & 0 deletions docs/changelog/1983.bugfix.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
After importing virtualenv passing cwd to a subprocess calls breaks with ``invalid directory`` - by :user:`gaborbernat`.
12 changes: 8 additions & 4 deletions src/virtualenv/util/subprocess/_win_subprocess.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
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
from ctypes.wintypes import BOOL, BYTE, DWORD, HANDLE, LPCWSTR, LPVOID, LPWSTR, WORD

import _subprocess

Expand Down Expand Up @@ -63,8 +63,8 @@ def __int__(self):

CreateProcessW = windll.kernel32.CreateProcessW
CreateProcessW.argtypes = [
LPCTSTR, LPTSTR, LPSECURITY_ATTRIBUTES,
LPSECURITY_ATTRIBUTES, BOOL, DWORD, LPVOID, LPCTSTR,
LPCWSTR, LPWSTR, LPSECURITY_ATTRIBUTES,
LPSECURITY_ATTRIBUTES, BOOL, DWORD, LPVOID, LPCWSTR,
LPSTARTUPINFOW, LPPROCESS_INFORMATION,
]
CreateProcessW.restype = BOOL
Expand Down Expand Up @@ -107,13 +107,17 @@ def CreateProcess(
wenv = (c_wchar * len(env))()
wenv.value = env

wcwd = None
if cwd is not None:
wcwd = unicode(cwd)

pi = PROCESS_INFORMATION()
creation_flags |= CREATE_UNICODE_ENVIRONMENT

if CreateProcessW(
executable, args, None, None,
inherit_handles, creation_flags,
wenv, cwd, byref(si), byref(pi),
wenv, wcwd, byref(si), byref(pi),
):
return (
DUMMY_HANDLE(pi.hProcess), DUMMY_HANDLE(pi.hThread),
Expand Down
17 changes: 17 additions & 0 deletions tests/unit/test_util.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
from __future__ import absolute_import, unicode_literals

import subprocess
import sys

import pytest

from virtualenv.info import IS_WIN, PY2
from virtualenv.util.subprocess import run_cmd


Expand All @@ -8,3 +14,14 @@ def test_run_fail(tmp_path):
assert err
assert not out
assert code


@pytest.mark.skipif(not (PY2 and IS_WIN), reason="subprocess patch only applied on Windows python2")
def test_windows_py2_cwd_works(tmp_path):
cwd = str(tmp_path)
result = subprocess.check_output(
[sys.executable, "-c", "import os; print(os.getcwd())"],
cwd=cwd,
universal_newlines=True,
)
assert result == "{}\n".format(cwd)

0 comments on commit 58b7edc

Please sign in to comment.