Skip to content

Commit 865c6e8

Browse files
committed
Further expand "not from cwd" test re: cmd.exe
On Python versions for which python/cpython#101283 is not patched, using Popen with shell=True can find cmd.exe in the current directory on Windows, in the rare case that the ComSpec environment variable is not defined. This is not necessarily worth addressing, because it is a bug in CPython rahter than GitPython, because that bug has been patched, and because it is very rare that ComSpec is undefined. However: - Changing the code to avoid it would also make that code simpler. - Patched versions of Python <=3.9 don't have python.org builds. This commit just expands the test to add cases where a repository also has a file cmd.exe and where ComSpec is undefined, showing that this case is not covered.
1 parent 7da9c3b commit 865c6e8

File tree

1 file changed

+33
-6
lines changed

1 file changed

+33
-6
lines changed

‎test/test_git.py

+33-6
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,21 @@
2929
from test.lib import TestBase, fixture_path, with_rw_directory
3030

3131

32+
@contextlib.contextmanager
33+
def _patch_out_env(name):
34+
try:
35+
old_value = os.environ[name]
36+
except KeyError:
37+
old_value = None
38+
else:
39+
del os.environ[name]
40+
try:
41+
yield
42+
finally:
43+
if old_value is not None:
44+
os.environ[name] = old_value
45+
46+
3247
@ddt.ddt
3348
class TestGit(TestBase):
3449
@classmethod
@@ -137,14 +152,17 @@ def test_it_executes_git_and_returns_result(self):
137152
self.assertRegex(self.git.execute(["git", "version"]), r"^git version [\d\.]{2}.*$")
138153

139154
@ddt.data(
140-
(False, False, ["git", "version"]),
141-
(False, True, "git version"),
142-
(True, False, ["git", "version"]),
143-
(True, True, "git version"),
155+
# chdir_to_repo, shell, command, use_shell_impostor
156+
(False, False, ["git", "version"], False),
157+
(False, True, "git version", False),
158+
(False, True, "git version", True),
159+
(True, False, ["git", "version"], False),
160+
(True, True, "git version", False),
161+
(True, True, "git version", True),
144162
)
145163
@with_rw_directory
146164
def test_it_executes_git_not_from_cwd(self, rw_dir, case):
147-
chdir_to_repo, shell, command = case
165+
chdir_to_repo, shell, command, use_shell_impostor = case
148166

149167
repo = Repo.init(rw_dir)
150168

@@ -160,7 +178,16 @@ def test_it_executes_git_not_from_cwd(self, rw_dir, case):
160178
impostor_path.write_text("#!/bin/sh\n", encoding="utf-8")
161179
os.chmod(impostor_path, 0o755)
162180

163-
with cwd(rw_dir) if chdir_to_repo else contextlib.nullcontext():
181+
if use_shell_impostor:
182+
shell_name = "cmd.exe" if os.name == "nt" else "sh"
183+
shutil.copy(impostor_path, Path(rw_dir, shell_name))
184+
185+
with contextlib.ExitStack() as stack:
186+
if chdir_to_repo:
187+
stack.enter_context(cwd(rw_dir))
188+
if use_shell_impostor:
189+
stack.enter_context(_patch_out_env("ComSpec"))
190+
164191
# Run the command without raising an exception on failure, as the exception
165192
# message is currently misleading when the command is a string rather than a
166193
# sequence of strings (it really runs "git", but then wrongly reports "g").

0 commit comments

Comments
 (0)