Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit874f0bf

Browse files
authored
Merge pull request#1687 from EliahKagan/popen-shell
Fix Git.execute shell use and reporting bugs
2 parentsf9a3b83 +baf3457 commit874f0bf

File tree

3 files changed

+63
-9
lines changed

3 files changed

+63
-9
lines changed

‎git/cmd.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -974,6 +974,8 @@ def execute(
974974
istream_ok="None"
975975
ifistream:
976976
istream_ok="<valid stream>"
977+
ifshellisNone:
978+
shell=self.USE_SHELL
977979
log.debug(
978980
"Popen(%s, cwd=%s, universal_newlines=%s, shell=%s, istream=%s)",
979981
redacted_command,
@@ -992,7 +994,7 @@ def execute(
992994
stdin=istreamorDEVNULL,
993995
stderr=PIPE,
994996
stdout=stdout_sink,
995-
shell=shellisnotNoneandshellorself.USE_SHELL,
997+
shell=shell,
996998
close_fds=is_posix,# unsupported on windows
997999
universal_newlines=universal_newlines,
9981000
creationflags=PROC_CREATIONFLAGS,

‎test-requirements.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
black
22
coverage[toml]
3-
ddt>=1.1.1, !=1.4.3
3+
ddt >= 1.1.1, != 1.4.3
4+
mock ; python_version < "3.8"
45
mypy
56
pre-commit
67
pytest

‎test/test_git.py

Lines changed: 58 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,23 +4,31 @@
44
#
55
# This module is part of GitPython and is released under
66
# the BSD License: https://opensource.org/license/bsd-3-clause/
7+
importcontextlib
8+
importlogging
79
importos
10+
importos.pathasosp
11+
importre
812
importshutil
913
importsubprocess
1014
importsys
1115
fromtempfileimportTemporaryDirectory,TemporaryFile
12-
fromunittestimportmock,skipUnless
16+
fromunittestimportskipUnless
1317

14-
fromgitimportGit,refresh,GitCommandError,GitCommandNotFound,Repo,cmd
15-
fromtest.libimportTestBase,fixture_path
16-
fromtest.libimportwith_rw_directory
17-
fromgit.utilimportcwd,finalize_process
18+
ifsys.version_info>= (3,8):
19+
fromunittestimportmock
20+
else:
21+
importmock# To be able to examine call_args.kwargs on a mock.
1822

19-
importos.pathasosp
23+
importddt
2024

25+
fromgitimportGit,refresh,GitCommandError,GitCommandNotFound,Repo,cmd
2126
fromgit.compatimportis_win
27+
fromgit.utilimportcwd,finalize_process
28+
fromtest.libimportTestBase,fixture_path,with_rw_directory
2229

2330

31+
@ddt.ddt
2432
classTestGit(TestBase):
2533
@classmethod
2634
defsetUpClass(cls):
@@ -73,7 +81,50 @@ def test_it_transforms_kwargs_into_git_command_arguments(self):
7381
res=self.git.transform_kwargs(**{"s":True,"t":True})
7482
self.assertEqual({"-s","-t"},set(res))
7583

76-
deftest_it_executes_git_to_shell_and_returns_result(self):
84+
_shell_cases= (
85+
# value_in_call, value_from_class, expected_popen_arg
86+
(None,False,False),
87+
(None,True,True),
88+
(False,True,False),
89+
(False,False,False),
90+
(True,False,True),
91+
(True,True,True),
92+
)
93+
94+
def_do_shell_combo(self,value_in_call,value_from_class):
95+
withmock.patch.object(Git,"USE_SHELL",value_from_class):
96+
# git.cmd gets Popen via a "from" import, so patch it there.
97+
withmock.patch.object(cmd,"Popen",wraps=cmd.Popen)asmock_popen:
98+
# Use a command with no arguments (besides the program name), so it runs
99+
# with or without a shell, on all OSes, with the same effect. Since git
100+
# errors out when run with no arguments, we swallow that error.
101+
withcontextlib.suppress(GitCommandError):
102+
self.git.execute(["git"],shell=value_in_call)
103+
104+
returnmock_popen
105+
106+
@ddt.idata(_shell_cases)
107+
deftest_it_uses_shell_or_not_as_specified(self,case):
108+
"""A bool passed as ``shell=`` takes precedence over `Git.USE_SHELL`."""
109+
value_in_call,value_from_class,expected_popen_arg=case
110+
mock_popen=self._do_shell_combo(value_in_call,value_from_class)
111+
mock_popen.assert_called_once()
112+
self.assertIs(mock_popen.call_args.kwargs["shell"],expected_popen_arg)
113+
114+
@ddt.idata(full_case[:2]forfull_casein_shell_cases)
115+
deftest_it_logs_if_it_uses_a_shell(self,case):
116+
"""``shell=`` in the log message agrees with what is passed to `Popen`."""
117+
value_in_call,value_from_class=case
118+
119+
withself.assertLogs(cmd.log,level=logging.DEBUG)aslog_watcher:
120+
mock_popen=self._do_shell_combo(value_in_call,value_from_class)
121+
122+
popen_shell_arg=mock_popen.call_args.kwargs["shell"]
123+
expected_message=re.compile(rf"DEBUG:git.cmd:Popen\(.*\bshell={popen_shell_arg}\b.*\)")
124+
match_attempts= [expected_message.fullmatch(message)formessageinlog_watcher.output]
125+
self.assertTrue(any(match_attempts),repr(log_watcher.output))
126+
127+
deftest_it_executes_git_and_returns_result(self):
77128
self.assertRegex(self.git.execute(["git","version"]),r"^git version [\d\.]{2}.*$")
78129

79130
deftest_it_executes_git_not_from_cwd(self):

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp