Skip to content

Commit

Permalink
Merge pull request #1732 from EliahKagan/compat
Browse files Browse the repository at this point in the history
Deprecate compat.is_<platform>, rewriting all uses
  • Loading branch information
Byron authored Nov 6, 2023
2 parents c594433 + 562bdee commit d5d897c
Show file tree
Hide file tree
Showing 17 changed files with 117 additions and 130 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/cygwin-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ jobs:
python --version
python -c 'import sys; print(sys.platform)'
python -c 'import os; print(os.name)'
python -c 'import git; print(git.compat.is_win)'
python -c 'import git; print(git.compat.is_win)' # NOTE: Deprecated. Use os.name directly.
- name: Test with pytest
run: |
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/pythonpackage.yml
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ jobs:
python --version
python -c 'import sys; print(sys.platform)'
python -c 'import os; print(os.name)'
python -c 'import git; print(git.compat.is_win)'
python -c 'import git; print(git.compat.is_win)' # NOTE: Deprecated. Use os.name directly.
- name: Check types with mypy
run: |
Expand Down
64 changes: 32 additions & 32 deletions git/cmd.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,19 +16,21 @@
import threading
from textwrap import dedent

from git.compat import (
defenc,
force_bytes,
safe_decode,
is_posix,
is_win,
from git.compat import defenc, force_bytes, safe_decode
from git.exc import (
CommandError,
GitCommandError,
GitCommandNotFound,
UnsafeOptionError,
UnsafeProtocolError,
)
from git.exc import CommandError
from git.util import is_cygwin_git, cygpath, expand_path, remove_password_if_present, patch_env

from .exc import GitCommandError, GitCommandNotFound, UnsafeOptionError, UnsafeProtocolError
from .util import (
from git.util import (
LazyMixin,
cygpath,
expand_path,
is_cygwin_git,
patch_env,
remove_password_if_present,
stream_copy,
)

Expand Down Expand Up @@ -179,14 +181,13 @@ def pump_stream(
t.start()
threads.append(t)

## FIXME: Why Join?? Will block if `stdin` needs feeding...
#
# FIXME: Why join? Will block if stdin needs feeding...
for t in threads:
t.join(timeout=kill_after_timeout)
if t.is_alive():
if isinstance(process, Git.AutoInterrupt):
process._terminate()
else: # Don't want to deal with the other case
else: # Don't want to deal with the other case.
raise RuntimeError(
"Thread join() timed out in cmd.handle_process_output()."
f" kill_after_timeout={kill_after_timeout} seconds"
Expand All @@ -196,11 +197,11 @@ def pump_stream(
"error: process killed because it timed out." f" kill_after_timeout={kill_after_timeout} seconds"
)
if not decode_streams and isinstance(p_stderr, BinaryIO):
# Assume stderr_handler needs binary input
# Assume stderr_handler needs binary input.
error_str = cast(str, error_str)
error_str = error_str.encode()
# We ignore typing on the next line because mypy does not like
# the way we inferred that stderr takes str or bytes
# the way we inferred that stderr takes str or bytes.
stderr_handler(error_str) # type: ignore

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


# value of Windows process creation flag taken from MSDN
CREATE_NO_WINDOW = 0x08000000

## CREATE_NEW_PROCESS_GROUP is needed to allow killing it afterwards,
# see https://docs.python.org/3/library/subprocess.html#subprocess.Popen.send_signal
PROC_CREATIONFLAGS = (
CREATE_NO_WINDOW | subprocess.CREATE_NEW_PROCESS_GROUP if is_win else 0 # type: ignore[attr-defined]
) # mypy error if not Windows.
if os.name == "nt":
# CREATE_NEW_PROCESS_GROUP is needed to allow killing it afterwards. See:
# https://docs.python.org/3/library/subprocess.html#subprocess.Popen.send_signal
PROC_CREATIONFLAGS = subprocess.CREATE_NO_WINDOW | subprocess.CREATE_NEW_PROCESS_GROUP
else:
PROC_CREATIONFLAGS = 0


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

if is_win:
if os.name == "nt":
cmd_not_found_exception = OSError
if kill_after_timeout is not None:
raise GitCommandError(
Expand Down Expand Up @@ -998,11 +997,11 @@ def execute(
env=env,
cwd=cwd,
bufsize=-1,
stdin=istream or DEVNULL,
stdin=(istream or DEVNULL),
stderr=PIPE,
stdout=stdout_sink,
shell=shell,
close_fds=is_posix, # Unsupported on Windows.
close_fds=(os.name == "posix"), # Unsupported on Windows.
universal_newlines=universal_newlines,
creationflags=PROC_CREATIONFLAGS,
**subprocess_kwargs,
Expand Down Expand Up @@ -1072,7 +1071,7 @@ def kill_process(pid: int) -> None:
)
if not universal_newlines:
stderr_value = stderr_value.encode(defenc)
# strip trailing "\n"
# Strip trailing "\n".
if stdout_value.endswith(newline) and strip_newline_in_stdout: # type: ignore
stdout_value = stdout_value[:-1]
if stderr_value.endswith(newline): # type: ignore
Expand Down Expand Up @@ -1146,11 +1145,11 @@ def update_environment(self, **kwargs: Any) -> Dict[str, Union[str, None]]:
"""
old_env = {}
for key, value in kwargs.items():
# set value if it is None
# Set value if it is None.
if value is not None:
old_env[key] = self._environment.get(key)
self._environment[key] = value
# remove key from environment if its value is None
# Remove key from environment if its value is None.
elif key in self._environment:
old_env[key] = self._environment[key]
del self._environment[key]
Expand Down Expand Up @@ -1329,7 +1328,8 @@ def _parse_object_header(self, header_line: str) -> Tuple[str, str, int]:
:return: (hex_sha, type_string, size_as_int)
:raise ValueError: If the header contains indication for an error due to
incorrect input sha"""
incorrect input sha
"""
tokens = header_line.split()
if len(tokens) != 3:
if not tokens:
Expand Down
12 changes: 10 additions & 2 deletions git/compat.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,17 @@
# ---------------------------------------------------------------------------


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

defenc = sys.getfilesystemencoding()


Expand Down
19 changes: 6 additions & 13 deletions git/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,28 +6,21 @@
"""Module containing module parser implementation able to properly read and write
configuration files."""

import sys
import abc
import configparser as cp
import fnmatch
from functools import wraps
import inspect
from io import BufferedReader, IOBase
import logging
import os
import os.path as osp
import re
import fnmatch

from git.compat import (
defenc,
force_text,
is_win,
)
import sys

from git.compat import defenc, force_text
from git.util import LockFile

import os.path as osp

import configparser as cp

# typing-------------------------------------------------------

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

if config_level == "system":
Expand Down
22 changes: 7 additions & 15 deletions git/index/fun.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,9 @@
# NOTE: Autodoc hates it if this is a docstring.

from io import BytesIO
from pathlib import Path
import os
import os.path as osp
from pathlib import Path
from stat import (
S_IFDIR,
S_IFLNK,
Expand All @@ -19,26 +20,17 @@
import subprocess

from git.cmd import PROC_CREATIONFLAGS, handle_process_output
from git.compat import (
defenc,
force_text,
force_bytes,
is_posix,
is_win,
safe_decode,
)
from git.exc import UnmergedEntriesError, HookExecutionError
from git.compat import defenc, force_bytes, force_text, safe_decode
from git.exc import HookExecutionError, UnmergedEntriesError
from git.objects.fun import (
tree_to_stream,
traverse_tree_recursive,
traverse_trees_recursive,
tree_to_stream,
)
from git.util import IndexFileSHA1Writer, finalize_process
from gitdb.base import IStream
from gitdb.typ import str_tree_type

import os.path as osp

from .typ import BaseIndexEntry, IndexEntry, CE_NAMEMASK, CE_STAGESHIFT
from .util import pack, unpack

Expand Down Expand Up @@ -99,7 +91,7 @@ def run_commit_hook(name: str, index: "IndexFile", *args: str) -> None:
env["GIT_EDITOR"] = ":"
cmd = [hp]
try:
if is_win and not _has_file_extension(hp):
if os.name == "nt" and not _has_file_extension(hp):
# Windows only uses extensions to determine how to open files
# (doesn't understand shebangs). Try using bash to run the hook.
relative_hp = Path(hp).relative_to(index.repo.working_dir).as_posix()
Expand All @@ -111,7 +103,7 @@ def run_commit_hook(name: str, index: "IndexFile", *args: str) -> None:
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
cwd=index.repo.working_dir,
close_fds=is_posix,
close_fds=(os.name == "posix"),
creationflags=PROC_CREATIONFLAGS,
)
except Exception as ex:
Expand Down
8 changes: 2 additions & 6 deletions git/index/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,11 @@

from functools import wraps
import os
import os.path as osp
import struct
import tempfile
from types import TracebackType

from git.compat import is_win

import os.path as osp


# typing ----------------------------------------------------------------------

from typing import Any, Callable, TYPE_CHECKING, Optional, Type
Expand Down Expand Up @@ -61,7 +57,7 @@ def __exit__(
exc_tb: Optional[TracebackType],
) -> bool:
if osp.isfile(self.tmp_file_path):
if is_win and osp.exists(self.file_path):
if os.name == "nt" and osp.exists(self.file_path):
os.remove(self.file_path)
os.rename(self.tmp_file_path, self.file_path)

Expand Down
7 changes: 3 additions & 4 deletions git/objects/submodule/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@

import git
from git.cmd import Git
from git.compat import defenc, is_win
from git.compat import defenc
from git.config import GitConfigParser, SectionConstraint, cp
from git.exc import (
BadName,
Expand Down Expand Up @@ -356,9 +356,8 @@ def _write_git_file_and_module_config(cls, working_tree_dir: PathLike, module_ab
"""
git_file = osp.join(working_tree_dir, ".git")
rela_path = osp.relpath(module_abspath, start=working_tree_dir)
if is_win:
if osp.isfile(git_file):
os.remove(git_file)
if os.name == "nt" and osp.isfile(git_file):
os.remove(git_file)
with open(git_file, "wb") as fp:
fp.write(("gitdir: %s" % rela_path).encode(defenc))

Expand Down
Loading

0 comments on commit d5d897c

Please sign in to comment.