diff --git a/pre_commit/commands/run.py b/pre_commit/commands/run.py index 1b08df91..95dd28b6 100644 --- a/pre_commit/commands/run.py +++ b/pre_commit/commands/run.py @@ -173,7 +173,7 @@ def _run_single_hook( if out.strip(): output.write_line() - output.write_line(out.strip(), logfile_name=hook.log_file) + output.write_line_b(out.strip(), logfile_name=hook.log_file) output.write_line() return files_modified or bool(retcode) diff --git a/pre_commit/error_handler.py b/pre_commit/error_handler.py index 44e19fd4..77b35698 100644 --- a/pre_commit/error_handler.py +++ b/pre_commit/error_handler.py @@ -3,10 +3,9 @@ import os.path import sys import traceback from typing import Generator -from typing import Union +from typing import Optional import pre_commit.constants as C -from pre_commit import five from pre_commit import output from pre_commit.store import Store @@ -15,25 +14,24 @@ class FatalError(RuntimeError): pass -def _to_bytes(exc: BaseException) -> bytes: - return str(exc).encode() - - def _log_and_exit(msg: str, exc: BaseException, formatted: str) -> None: error_msg = b''.join(( - five.to_bytes(msg), b': ', - five.to_bytes(type(exc).__name__), b': ', - _to_bytes(exc), + msg.encode(), b': ', + type(exc).__name__.encode(), b': ', + str(exc).encode(), )) - output.write_line(error_msg) + output.write_line_b(error_msg) store = Store() log_path = os.path.join(store.directory, 'pre-commit.log') output.write_line(f'Check the log at {log_path}') with open(log_path, 'wb') as log: - def _log_line(s: Union[None, str, bytes] = None) -> None: + def _log_line(s: Optional[str] = None) -> None: output.write_line(s, stream=log) + def _log_line_b(s: Optional[bytes] = None) -> None: + output.write_line_b(s, stream=log) + _log_line('### version information') _log_line() _log_line('```') @@ -50,7 +48,7 @@ def _log_and_exit(msg: str, exc: BaseException, formatted: str) -> None: _log_line('### error information') _log_line() _log_line('```') - _log_line(error_msg) + _log_line_b(error_msg) _log_line('```') _log_line() _log_line('```') diff --git a/pre_commit/five.py b/pre_commit/five.py deleted file mode 100644 index a7ffd978..00000000 --- a/pre_commit/five.py +++ /dev/null @@ -1,12 +0,0 @@ -from typing import Union - - -def to_text(s: Union[str, bytes]) -> str: - return s if isinstance(s, str) else s.decode() - - -def to_bytes(s: Union[str, bytes]) -> bytes: - return s if isinstance(s, bytes) else s.encode() - - -n = to_text diff --git a/pre_commit/languages/pygrep.py b/pre_commit/languages/pygrep.py index 06d91903..c6d1131d 100644 --- a/pre_commit/languages/pygrep.py +++ b/pre_commit/languages/pygrep.py @@ -27,7 +27,7 @@ def _process_filename_by_line(pattern: Pattern[bytes], filename: str) -> int: if pattern.search(line): retv = 1 output.write(f'{filename}:{line_no}:') - output.write_line(line.rstrip(b'\r\n')) + output.write_line_b(line.rstrip(b'\r\n')) return retv @@ -44,7 +44,7 @@ def _process_filename_at_once(pattern: Pattern[bytes], filename: str) -> int: matched_lines = match[0].split(b'\n') matched_lines[0] = contents.split(b'\n')[line_no] - output.write_line(b'\n'.join(matched_lines)) + output.write_line_b(b'\n'.join(matched_lines)) return retv diff --git a/pre_commit/main.py b/pre_commit/main.py index ce902c07..eae4f909 100644 --- a/pre_commit/main.py +++ b/pre_commit/main.py @@ -9,7 +9,6 @@ from typing import Union import pre_commit.constants as C from pre_commit import color -from pre_commit import five from pre_commit import git from pre_commit.commands.autoupdate import autoupdate from pre_commit.commands.clean import clean @@ -155,7 +154,6 @@ def _adjust_args_and_chdir(args: argparse.Namespace) -> None: def main(argv: Optional[Sequence[str]] = None) -> int: argv = argv if argv is not None else sys.argv[1:] - argv = [five.to_text(arg) for arg in argv] parser = argparse.ArgumentParser(prog='pre-commit') # https://stackoverflow.com/a/8521644/812183 diff --git a/pre_commit/output.py b/pre_commit/output.py index 5d262839..b20b8ab4 100644 --- a/pre_commit/output.py +++ b/pre_commit/output.py @@ -1,11 +1,10 @@ import contextlib import sys +from typing import Any from typing import IO from typing import Optional -from typing import Union from pre_commit import color -from pre_commit import five def get_hook_message( @@ -60,12 +59,12 @@ def get_hook_message( def write(s: str, stream: IO[bytes] = sys.stdout.buffer) -> None: - stream.write(five.to_bytes(s)) + stream.write(s.encode()) stream.flush() -def write_line( - s: Union[None, str, bytes] = None, +def write_line_b( + s: Optional[bytes] = None, stream: IO[bytes] = sys.stdout.buffer, logfile_name: Optional[str] = None, ) -> None: @@ -77,6 +76,10 @@ def write_line( for output_stream in output_streams: if s is not None: - output_stream.write(five.to_bytes(s)) + output_stream.write(s) output_stream.write(b'\n') output_stream.flush() + + +def write_line(s: Optional[str] = None, **kwargs: Any) -> None: + write_line_b(s.encode() if s is not None else s, **kwargs) diff --git a/pre_commit/repository.py b/pre_commit/repository.py index 08d8647c..9b071089 100644 --- a/pre_commit/repository.py +++ b/pre_commit/repository.py @@ -12,7 +12,6 @@ from typing import Set from typing import Tuple import pre_commit.constants as C -from pre_commit import five from pre_commit.clientlib import load_manifest from pre_commit.clientlib import LOCAL from pre_commit.clientlib import MANIFEST_HOOK_DICT @@ -49,7 +48,7 @@ def _write_state(prefix: Prefix, venv: str, state: object) -> None: state_filename = _state_filename(prefix, venv) staging = state_filename + 'staging' with open(staging, 'w') as state_file: - state_file.write(five.to_text(json.dumps(state))) + state_file.write(json.dumps(state)) # Move the file into place atomically to indicate we've installed os.rename(staging, state_filename) diff --git a/pre_commit/util.py b/pre_commit/util.py index 54ae7ece..f5858be2 100644 --- a/pre_commit/util.py +++ b/pre_commit/util.py @@ -17,7 +17,6 @@ from typing import Tuple from typing import Type from typing import Union -from pre_commit import five from pre_commit import parse_shebang if sys.version_info >= (3, 7): # pragma: no cover (PY37+) @@ -116,19 +115,9 @@ class CalledProcessError(RuntimeError): return self.__bytes__().decode() -def _cmd_kwargs( - *cmd: str, - **kwargs: Any, -) -> Tuple[Tuple[str, ...], Dict[str, Any]]: - # py2/py3 on windows are more strict about the types here - cmd = tuple(five.n(arg) for arg in cmd) - kwargs['env'] = { - five.n(key): five.n(value) - for key, value in kwargs.pop('env', {}).items() - } or None +def _setdefault_kwargs(kwargs: Dict[str, Any]) -> None: for arg in ('stdin', 'stdout', 'stderr'): kwargs.setdefault(arg, subprocess.PIPE) - return cmd, kwargs def cmd_output_b( @@ -136,7 +125,7 @@ def cmd_output_b( **kwargs: Any, ) -> Tuple[int, bytes, Optional[bytes]]: retcode = kwargs.pop('retcode', 0) - cmd, kwargs = _cmd_kwargs(*cmd, **kwargs) + _setdefault_kwargs(kwargs) try: cmd = parse_shebang.normalize_cmd(cmd) @@ -205,7 +194,7 @@ if os.name != 'nt': # pragma: windows no cover ) -> Tuple[int, bytes, Optional[bytes]]: assert kwargs.pop('retcode') is None assert kwargs['stderr'] == subprocess.STDOUT, kwargs['stderr'] - cmd, kwargs = _cmd_kwargs(*cmd, **kwargs) + _setdefault_kwargs(kwargs) try: cmd = parse_shebang.normalize_cmd(cmd) diff --git a/tests/conftest.py b/tests/conftest.py index 8149bb9a..335d2614 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -256,10 +256,9 @@ class Fixture: def cap_out(): stream = FakeStream() write = functools.partial(output.write, stream=stream) - write_line = functools.partial(output.write_line, stream=stream) - with mock.patch.object(output, 'write', write): - with mock.patch.object(output, 'write_line', write_line): - yield Fixture(stream) + write_line_b = functools.partial(output.write_line_b, stream=stream) + with mock.patch.multiple(output, write=write, write_line_b=write_line_b): + yield Fixture(stream) @pytest.fixture diff --git a/tests/repository_test.py b/tests/repository_test.py index f3ca6c5b..7a22dee6 100644 --- a/tests/repository_test.py +++ b/tests/repository_test.py @@ -10,7 +10,6 @@ import cfgv import pytest import pre_commit.constants as C -from pre_commit import five from pre_commit.clientlib import CONFIG_SCHEMA from pre_commit.clientlib import load_manifest from pre_commit.envcontext import envcontext @@ -119,7 +118,7 @@ def test_python_hook(tempdir_factory, store): _test_hook_repo( tempdir_factory, store, 'python_hooks_repo', 'foo', [os.devnull], - b"['" + five.to_bytes(os.devnull) + b"']\nHello World\n", + f'[{os.devnull!r}]\nHello World\n'.encode(), ) @@ -154,7 +153,7 @@ def test_python_hook_weird_setup_cfg(in_git_dir, tempdir_factory, store): _test_hook_repo( tempdir_factory, store, 'python_hooks_repo', 'foo', [os.devnull], - b"['" + five.to_bytes(os.devnull) + b"']\nHello World\n", + f'[{os.devnull!r}]\nHello World\n'.encode(), ) @@ -163,7 +162,7 @@ def test_python_venv(tempdir_factory, store): # pragma: no cover (no venv) _test_hook_repo( tempdir_factory, store, 'python_venv_hooks_repo', 'foo', [os.devnull], - b"['" + five.to_bytes(os.devnull) + b"']\nHello World\n", + f'[{os.devnull!r}]\nHello World\n'.encode(), ) @@ -188,7 +187,7 @@ def test_versioned_python_hook(tempdir_factory, store): tempdir_factory, store, 'python3_hooks_repo', 'python3-hook', [os.devnull], - b"3\n['" + five.to_bytes(os.devnull) + b"']\nHello World\n", + f'3\n[{os.devnull!r}]\nHello World\n'.encode(), )