From e272c219fda351da520374a6f2e3ab4e904dcef3 Mon Sep 17 00:00:00 2001 From: Anthony Sottile Date: Wed, 19 Apr 2017 08:11:57 -0700 Subject: [PATCH] Default to UTF-8 encoding in open() calls --- pre_commit/commands/install_uninstall.py | 10 +++++----- pre_commit/languages/ruby.py | 4 ++-- pre_commit/parse_shebang.py | 3 +-- pre_commit/repository.py | 6 +++--- pre_commit/schema.py | 5 +++-- pre_commit/staged_files_only.py | 3 +-- pre_commit/store.py | 4 ++-- pre_commit/util.py | 9 +++++++++ 8 files changed, 26 insertions(+), 18 deletions(-) diff --git a/pre_commit/commands/install_uninstall.py b/pre_commit/commands/install_uninstall.py index 6268b918..ac1eef86 100644 --- a/pre_commit/commands/install_uninstall.py +++ b/pre_commit/commands/install_uninstall.py @@ -1,11 +1,11 @@ from __future__ import print_function from __future__ import unicode_literals -import io import os.path import sys from pre_commit import output +from pre_commit import util from pre_commit.util import make_executable from pre_commit.util import mkdirp from pre_commit.util import resource_filename @@ -25,7 +25,7 @@ CURRENT_HASH = '138fd403232d2ddd5efb44317e38bf03' def is_our_script(filename): if not os.path.exists(filename): return False - contents = io.open(filename).read() + contents = util.open(filename).read() return any(h in contents for h in (CURRENT_HASH,) + PRIOR_HASHES) @@ -54,15 +54,15 @@ def install( ) ) - with io.open(hook_path, 'w') as pre_commit_file_obj: + with util.open(hook_path, 'w') as pre_commit_file_obj: if hook_type == 'pre-push': - with io.open(resource_filename('pre-push-tmpl')) as fp: + with util.open(resource_filename('pre-push-tmpl')) as fp: pre_push_contents = fp.read() else: pre_push_contents = '' skip_on_missing_conf = 'true' if skip_on_missing_conf else 'false' - contents = io.open(resource_filename('hook-tmpl')).read().format( + contents = util.open(resource_filename('hook-tmpl')).read().format( sys_executable=sys.executable, hook_type=hook_type, pre_push=pre_push_contents, diff --git a/pre_commit/languages/ruby.py b/pre_commit/languages/ruby.py index d3896d90..30252ea4 100644 --- a/pre_commit/languages/ruby.py +++ b/pre_commit/languages/ruby.py @@ -1,11 +1,11 @@ from __future__ import unicode_literals import contextlib -import io import os.path import shutil import tarfile +from pre_commit import util from pre_commit.envcontext import envcontext from pre_commit.envcontext import Var from pre_commit.languages import helpers @@ -65,7 +65,7 @@ def _install_rbenv( tf.extractall(repo_cmd_runner.path(directory, 'plugins')) activate_path = repo_cmd_runner.path(directory, 'bin', 'activate') - with io.open(activate_path, 'w') as activate_file: + with util.open(activate_path, 'w') as activate_file: # This is similar to how you would install rbenv to your home directory # However we do a couple things to make the executables exposed and # configure it to work in our directory. diff --git a/pre_commit/parse_shebang.py b/pre_commit/parse_shebang.py index be38d15f..783a0c41 100644 --- a/pre_commit/parse_shebang.py +++ b/pre_commit/parse_shebang.py @@ -1,7 +1,6 @@ from __future__ import absolute_import from __future__ import unicode_literals -import io import os.path import shlex import string @@ -41,7 +40,7 @@ def parse_filename(filename): if not os.path.exists(filename) or not os.access(filename, os.X_OK): return () - with io.open(filename, 'rb') as f: + with open(filename, 'rb') as f: return parse_bytesio(f) diff --git a/pre_commit/repository.py b/pre_commit/repository.py index 2c1eedb3..beb69cb1 100644 --- a/pre_commit/repository.py +++ b/pre_commit/repository.py @@ -1,6 +1,5 @@ from __future__ import unicode_literals -import io import json import logging import os @@ -13,6 +12,7 @@ from cached_property import cached_property import pre_commit.constants as C from pre_commit import five from pre_commit import git +from pre_commit import util from pre_commit.clientlib import is_local_repo from pre_commit.clientlib import MANIFEST_HOOK_DICT from pre_commit.languages.all import languages @@ -41,13 +41,13 @@ def _read_installed_state(cmd_runner, venv): if not os.path.exists(filename): return None else: - return json.loads(io.open(filename).read()) + return json.loads(util.open(filename).read()) def _write_installed_state(cmd_runner, venv, state): state_filename = _state_filename(cmd_runner, venv) staging = state_filename + 'staging' - with io.open(staging, 'w') as state_file: + with util.open(staging, 'w') as state_file: state_file.write(five.to_text(json.dumps(state))) # Move the file into place atomically to indicate we've installed os.rename(staging, state_filename) diff --git a/pre_commit/schema.py b/pre_commit/schema.py index d34ad737..353172bc 100644 --- a/pre_commit/schema.py +++ b/pre_commit/schema.py @@ -3,13 +3,14 @@ from __future__ import unicode_literals import collections import contextlib -import io import os.path import re import sys import six +from pre_commit import util + class ValidationError(ValueError): def __init__(self, error_msg, ctx=None): @@ -266,7 +267,7 @@ def load_from_filename(filename, schema, load_strategy, exc_tp): if not os.path.exists(filename): raise ValidationError('{} does not exist'.format(filename)) - with io.open(filename) as f: + with util.open(filename) as f: contents = f.read() with validate_context('File {}'.format(filename)): diff --git a/pre_commit/staged_files_only.py b/pre_commit/staged_files_only.py index a63662bf..ff236c8d 100644 --- a/pre_commit/staged_files_only.py +++ b/pre_commit/staged_files_only.py @@ -1,7 +1,6 @@ from __future__ import unicode_literals import contextlib -import io import logging import time @@ -35,7 +34,7 @@ def staged_files_only(cmd_runner): 'Stashing unstaged files to {}.'.format(patch_filename), ) # Save the current unstaged changes as a patch - with io.open(patch_filename, 'wb') as patch_file: + with open(patch_filename, 'wb') as patch_file: patch_file.write(diff_stdout_binary) # Clear the working directory of unstaged changes diff --git a/pre_commit/store.py b/pre_commit/store.py index 67564483..5a161e7b 100644 --- a/pre_commit/store.py +++ b/pre_commit/store.py @@ -1,7 +1,6 @@ from __future__ import unicode_literals import contextlib -import io import logging import os.path import sqlite3 @@ -10,6 +9,7 @@ import tempfile from cached_property import cached_property import pre_commit.constants as C +from pre_commit import util from pre_commit.prefixed_command_runner import PrefixedCommandRunner from pre_commit.util import clean_path_on_failure from pre_commit.util import cmd_output @@ -46,7 +46,7 @@ class Store(object): self.__created = False def _write_readme(self): - with io.open(os.path.join(self.directory, 'README'), 'w') as readme: + with util.open(os.path.join(self.directory, 'README'), 'w') as readme: readme.write( 'This directory is maintained by the pre-commit project.\n' 'Learn more: https://github.com/pre-commit/pre-commit\n' diff --git a/pre_commit/util.py b/pre_commit/util.py index 4c3ad421..b1ea03e4 100644 --- a/pre_commit/util.py +++ b/pre_commit/util.py @@ -3,6 +3,7 @@ from __future__ import unicode_literals import contextlib import errno import functools +import io import os.path import shutil import stat @@ -16,6 +17,14 @@ from pre_commit import five from pre_commit import parse_shebang +def open(*args, **kwargs): + """Some strange interaction with python2, osx, and vscode makes default + encoding detection go wrong. See #519 + """ + kwargs.setdefault('encoding', 'UTF-8') + return io.open(*args, **kwargs) + + @contextlib.contextmanager def cwd(path): original_cwd = os.getcwd()