Skip to content

Commit d5d897c

Browse files
authored
Merge pull request gitpython-developers#1732 from EliahKagan/compat
Deprecate compat.is_<platform>, rewriting all uses
2 parents c594433 + 562bdee commit d5d897c

17 files changed

+117
-130
lines changed

Diff for: .github/workflows/cygwin-test.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ jobs:
7272
python --version
7373
python -c 'import sys; print(sys.platform)'
7474
python -c 'import os; print(os.name)'
75-
python -c 'import git; print(git.compat.is_win)'
75+
python -c 'import git; print(git.compat.is_win)' # NOTE: Deprecated. Use os.name directly.
7676
7777
- name: Test with pytest
7878
run: |

Diff for: .github/workflows/pythonpackage.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ jobs:
6363
python --version
6464
python -c 'import sys; print(sys.platform)'
6565
python -c 'import os; print(os.name)'
66-
python -c 'import git; print(git.compat.is_win)'
66+
python -c 'import git; print(git.compat.is_win)' # NOTE: Deprecated. Use os.name directly.
6767
6868
- name: Check types with mypy
6969
run: |

Diff for: git/cmd.py

+32-32
Original file line numberDiff line numberDiff line change
@@ -16,19 +16,21 @@
1616
import threading
1717
from textwrap import dedent
1818

19-
from git.compat import (
20-
defenc,
21-
force_bytes,
22-
safe_decode,
23-
is_posix,
24-
is_win,
19+
from git.compat import defenc, force_bytes, safe_decode
20+
from git.exc import (
21+
CommandError,
22+
GitCommandError,
23+
GitCommandNotFound,
24+
UnsafeOptionError,
25+
UnsafeProtocolError,
2526
)
26-
from git.exc import CommandError
27-
from git.util import is_cygwin_git, cygpath, expand_path, remove_password_if_present, patch_env
28-
29-
from .exc import GitCommandError, GitCommandNotFound, UnsafeOptionError, UnsafeProtocolError
30-
from .util import (
27+
from git.util import (
3128
LazyMixin,
29+
cygpath,
30+
expand_path,
31+
is_cygwin_git,
32+
patch_env,
33+
remove_password_if_present,
3234
stream_copy,
3335
)
3436

@@ -179,14 +181,13 @@ def pump_stream(
179181
t.start()
180182
threads.append(t)
181183

182-
## FIXME: Why Join?? Will block if `stdin` needs feeding...
183-
#
184+
# FIXME: Why join? Will block if stdin needs feeding...
184185
for t in threads:
185186
t.join(timeout=kill_after_timeout)
186187
if t.is_alive():
187188
if isinstance(process, Git.AutoInterrupt):
188189
process._terminate()
189-
else: # Don't want to deal with the other case
190+
else: # Don't want to deal with the other case.
190191
raise RuntimeError(
191192
"Thread join() timed out in cmd.handle_process_output()."
192193
f" kill_after_timeout={kill_after_timeout} seconds"
@@ -196,11 +197,11 @@ def pump_stream(
196197
"error: process killed because it timed out." f" kill_after_timeout={kill_after_timeout} seconds"
197198
)
198199
if not decode_streams and isinstance(p_stderr, BinaryIO):
199-
# Assume stderr_handler needs binary input
200+
# Assume stderr_handler needs binary input.
200201
error_str = cast(str, error_str)
201202
error_str = error_str.encode()
202203
# We ignore typing on the next line because mypy does not like
203-
# the way we inferred that stderr takes str or bytes
204+
# the way we inferred that stderr takes str or bytes.
204205
stderr_handler(error_str) # type: ignore
205206

206207
if finalizer:
@@ -227,14 +228,12 @@ def dict_to_slots_and__excluded_are_none(self: object, d: Mapping[str, Any], exc
227228
## -- End Utilities -- @}
228229

229230

230-
# value of Windows process creation flag taken from MSDN
231-
CREATE_NO_WINDOW = 0x08000000
232-
233-
## CREATE_NEW_PROCESS_GROUP is needed to allow killing it afterwards,
234-
# see https://docs.python.org/3/library/subprocess.html#subprocess.Popen.send_signal
235-
PROC_CREATIONFLAGS = (
236-
CREATE_NO_WINDOW | subprocess.CREATE_NEW_PROCESS_GROUP if is_win else 0 # type: ignore[attr-defined]
237-
) # mypy error if not Windows.
231+
if os.name == "nt":
232+
# CREATE_NEW_PROCESS_GROUP is needed to allow killing it afterwards. See:
233+
# https://docs.python.org/3/library/subprocess.html#subprocess.Popen.send_signal
234+
PROC_CREATIONFLAGS = subprocess.CREATE_NO_WINDOW | subprocess.CREATE_NEW_PROCESS_GROUP
235+
else:
236+
PROC_CREATIONFLAGS = 0
238237

239238

240239
class Git(LazyMixin):
@@ -550,7 +549,7 @@ def _terminate(self) -> None:
550549
# For some reason, providing None for stdout/stderr still prints something. This is why
551550
# we simply use the shell and redirect to nul. Slower than CreateProcess. The question
552551
# is whether we really want to see all these messages. It's annoying no matter what.
553-
if is_win:
552+
if os.name == "nt":
554553
call(
555554
("TASKKILL /F /T /PID %s 2>nul 1>nul" % str(proc.pid)),
556555
shell=True,
@@ -966,7 +965,7 @@ def execute(
966965
if inline_env is not None:
967966
env.update(inline_env)
968967

969-
if is_win:
968+
if os.name == "nt":
970969
cmd_not_found_exception = OSError
971970
if kill_after_timeout is not None:
972971
raise GitCommandError(
@@ -998,11 +997,11 @@ def execute(
998997
env=env,
999998
cwd=cwd,
1000999
bufsize=-1,
1001-
stdin=istream or DEVNULL,
1000+
stdin=(istream or DEVNULL),
10021001
stderr=PIPE,
10031002
stdout=stdout_sink,
10041003
shell=shell,
1005-
close_fds=is_posix, # Unsupported on Windows.
1004+
close_fds=(os.name == "posix"), # Unsupported on Windows.
10061005
universal_newlines=universal_newlines,
10071006
creationflags=PROC_CREATIONFLAGS,
10081007
**subprocess_kwargs,
@@ -1072,7 +1071,7 @@ def kill_process(pid: int) -> None:
10721071
)
10731072
if not universal_newlines:
10741073
stderr_value = stderr_value.encode(defenc)
1075-
# strip trailing "\n"
1074+
# Strip trailing "\n".
10761075
if stdout_value.endswith(newline) and strip_newline_in_stdout: # type: ignore
10771076
stdout_value = stdout_value[:-1]
10781077
if stderr_value.endswith(newline): # type: ignore
@@ -1146,11 +1145,11 @@ def update_environment(self, **kwargs: Any) -> Dict[str, Union[str, None]]:
11461145
"""
11471146
old_env = {}
11481147
for key, value in kwargs.items():
1149-
# set value if it is None
1148+
# Set value if it is None.
11501149
if value is not None:
11511150
old_env[key] = self._environment.get(key)
11521151
self._environment[key] = value
1153-
# remove key from environment if its value is None
1152+
# Remove key from environment if its value is None.
11541153
elif key in self._environment:
11551154
old_env[key] = self._environment[key]
11561155
del self._environment[key]
@@ -1329,7 +1328,8 @@ def _parse_object_header(self, header_line: str) -> Tuple[str, str, int]:
13291328
:return: (hex_sha, type_string, size_as_int)
13301329
13311330
:raise ValueError: If the header contains indication for an error due to
1332-
incorrect input sha"""
1331+
incorrect input sha
1332+
"""
13331333
tokens = header_line.split()
13341334
if len(tokens) != 3:
13351335
if not tokens:

Diff for: git/compat.py

+10-2
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,17 @@
3333
# ---------------------------------------------------------------------------
3434

3535

36-
is_win: bool = os.name == "nt"
36+
# DEPRECATED attributes providing shortcuts to operating system checks based on os.name.
37+
#
38+
# These are deprecated because it is clearer, and helps avoid bugs, to write out the
39+
# os.name or sys.platform checks explicitly, especially in cases where it matters which
40+
# is used. For example, is_win is False on Cygwin, but is often assumed True. To detect
41+
# Cygwin, use sys.platform == "cygwin". (Also, in the past, is_darwin was unreliable.)
42+
#
43+
is_win = os.name == "nt"
3744
is_posix = os.name == "posix"
38-
is_darwin = os.name == "darwin"
45+
is_darwin = sys.platform == "darwin"
46+
3947
defenc = sys.getfilesystemencoding()
4048

4149

Diff for: git/config.py

+6-13
Original file line numberDiff line numberDiff line change
@@ -6,28 +6,21 @@
66
"""Module containing module parser implementation able to properly read and write
77
configuration files."""
88

9-
import sys
109
import abc
10+
import configparser as cp
11+
import fnmatch
1112
from functools import wraps
1213
import inspect
1314
from io import BufferedReader, IOBase
1415
import logging
1516
import os
17+
import os.path as osp
1618
import re
17-
import fnmatch
18-
19-
from git.compat import (
20-
defenc,
21-
force_text,
22-
is_win,
23-
)
19+
import sys
2420

21+
from git.compat import defenc, force_text
2522
from git.util import LockFile
2623

27-
import os.path as osp
28-
29-
import configparser as cp
30-
3124
# typing-------------------------------------------------------
3225

3326
from typing import (
@@ -249,7 +242,7 @@ def items_all(self) -> List[Tuple[str, List[_T]]]:
249242
def get_config_path(config_level: Lit_config_levels) -> str:
250243
# We do not support an absolute path of the gitconfig on Windows.
251244
# Use the global config instead.
252-
if is_win and config_level == "system":
245+
if os.name == "nt" and config_level == "system":
253246
config_level = "global"
254247

255248
if config_level == "system":

Diff for: git/index/fun.py

+7-15
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,9 @@
55
# NOTE: Autodoc hates it if this is a docstring.
66

77
from io import BytesIO
8-
from pathlib import Path
98
import os
9+
import os.path as osp
10+
from pathlib import Path
1011
from stat import (
1112
S_IFDIR,
1213
S_IFLNK,
@@ -19,26 +20,17 @@
1920
import subprocess
2021

2122
from git.cmd import PROC_CREATIONFLAGS, handle_process_output
22-
from git.compat import (
23-
defenc,
24-
force_text,
25-
force_bytes,
26-
is_posix,
27-
is_win,
28-
safe_decode,
29-
)
30-
from git.exc import UnmergedEntriesError, HookExecutionError
23+
from git.compat import defenc, force_bytes, force_text, safe_decode
24+
from git.exc import HookExecutionError, UnmergedEntriesError
3125
from git.objects.fun import (
32-
tree_to_stream,
3326
traverse_tree_recursive,
3427
traverse_trees_recursive,
28+
tree_to_stream,
3529
)
3630
from git.util import IndexFileSHA1Writer, finalize_process
3731
from gitdb.base import IStream
3832
from gitdb.typ import str_tree_type
3933

40-
import os.path as osp
41-
4234
from .typ import BaseIndexEntry, IndexEntry, CE_NAMEMASK, CE_STAGESHIFT
4335
from .util import pack, unpack
4436

@@ -99,7 +91,7 @@ def run_commit_hook(name: str, index: "IndexFile", *args: str) -> None:
9991
env["GIT_EDITOR"] = ":"
10092
cmd = [hp]
10193
try:
102-
if is_win and not _has_file_extension(hp):
94+
if os.name == "nt" and not _has_file_extension(hp):
10395
# Windows only uses extensions to determine how to open files
10496
# (doesn't understand shebangs). Try using bash to run the hook.
10597
relative_hp = Path(hp).relative_to(index.repo.working_dir).as_posix()
@@ -111,7 +103,7 @@ def run_commit_hook(name: str, index: "IndexFile", *args: str) -> None:
111103
stdout=subprocess.PIPE,
112104
stderr=subprocess.PIPE,
113105
cwd=index.repo.working_dir,
114-
close_fds=is_posix,
106+
close_fds=(os.name == "posix"),
115107
creationflags=PROC_CREATIONFLAGS,
116108
)
117109
except Exception as ex:

Diff for: git/index/util.py

+2-6
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,11 @@
55

66
from functools import wraps
77
import os
8+
import os.path as osp
89
import struct
910
import tempfile
1011
from types import TracebackType
1112

12-
from git.compat import is_win
13-
14-
import os.path as osp
15-
16-
1713
# typing ----------------------------------------------------------------------
1814

1915
from typing import Any, Callable, TYPE_CHECKING, Optional, Type
@@ -61,7 +57,7 @@ def __exit__(
6157
exc_tb: Optional[TracebackType],
6258
) -> bool:
6359
if osp.isfile(self.tmp_file_path):
64-
if is_win and osp.exists(self.file_path):
60+
if os.name == "nt" and osp.exists(self.file_path):
6561
os.remove(self.file_path)
6662
os.rename(self.tmp_file_path, self.file_path)
6763

Diff for: git/objects/submodule/base.py

+3-4
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010

1111
import git
1212
from git.cmd import Git
13-
from git.compat import defenc, is_win
13+
from git.compat import defenc
1414
from git.config import GitConfigParser, SectionConstraint, cp
1515
from git.exc import (
1616
BadName,
@@ -356,9 +356,8 @@ def _write_git_file_and_module_config(cls, working_tree_dir: PathLike, module_ab
356356
"""
357357
git_file = osp.join(working_tree_dir, ".git")
358358
rela_path = osp.relpath(module_abspath, start=working_tree_dir)
359-
if is_win:
360-
if osp.isfile(git_file):
361-
os.remove(git_file)
359+
if os.name == "nt" and osp.isfile(git_file):
360+
os.remove(git_file)
362361
with open(git_file, "wb") as fp:
363362
fp.write(("gitdir: %s" % rela_path).encode(defenc))
364363

0 commit comments

Comments
 (0)