diff options
| -rw-r--r-- | .gitignore | 1 | ||||
| -rw-r--r-- | isort/isort.py | 26 | ||||
| -rw-r--r-- | test_isort.py | 21 |
3 files changed, 44 insertions, 4 deletions
@@ -6,6 +6,7 @@ # Packages *.egg *.egg-info +.eggs build eggs parts diff --git a/isort/isort.py b/isort/isort.py index 8f8ddaa0..274be1cf 100644 --- a/isort/isort.py +++ b/isort/isort.py @@ -28,6 +28,7 @@ from __future__ import absolute_import, division, print_function, unicode_litera import codecs import copy +import io import itertools import os import re @@ -89,6 +90,7 @@ class SortImports(object): self._section_comments = ["# " + value for key, value in itemsview(self.config) if key.startswith('import_heading') and value] + self.file_encoding = 'utf-8' file_name = file_path self.file_path = file_path or "" if file_path and not file_contents: @@ -100,9 +102,9 @@ class SortImports(object): file_contents = None else: self.file_path = file_path - with open(file_path) as file_to_import_sort: + self.file_encoding = coding_check(file_path) + with codecs.open(file_path, encoding=self.file_encoding) as file_to_import_sort: file_contents = file_to_import_sort.read() - file_contents = PY2 and file_contents.decode('utf8') or file_contents if file_contents is None or ("isort:" + "skip_file") in file_contents: return @@ -168,7 +170,7 @@ class SortImports(object): elif write_to_stdout: stdout.write(self.output) elif file_name: - with codecs.open(self.file_path, encoding='utf-8', mode='w') as output_file: + with codecs.open(self.file_path, encoding=self.file_encoding, mode='w') as output_file: output_file.write(self.output) def _show_diff(self, file_contents): @@ -754,3 +756,21 @@ class SortImports(object): self.comments['above']['from'].setdefault(module, []).insert(0, self.out_lines.pop(-1)) last = self.out_lines and self.out_lines[-1].rstrip() or "" self.imports[self.place_module(module)][import_type].add(module) + + +def coding_check(fname, default='utf-8'): + + # see https://www.python.org/dev/peps/pep-0263/ + pattern = re.compile(br'coding[:=]\s*([-\w.]+)') + + coding = default + with io.open(fname, 'rb') as f: + for line_number, line in enumerate(f, 1): + groups = re.findall(pattern, line) + if groups: + coding = groups[0].decode('ascii') + break + if line_number > 2: + break + + return coding diff --git a/test_isort.py b/test_isort.py index 574f201e..9769263e 100644 --- a/test_isort.py +++ b/test_isort.py @@ -1,7 +1,8 @@ +# coding: utf-8 """test_isort.py. Tests all major functionality of the isort library -Should be ran using py.test by simply running by.test in the isort project directory +Should be ran using py.test by simply running py.test in the isort project directory Copyright (C) 2013 Timothy Edmund Crosley @@ -23,6 +24,10 @@ OTHER DEALINGS IN THE SOFTWARE. from __future__ import absolute_import, division, print_function, unicode_literals from isort.pie_slice import * +import codecs +import os +import shutil +import tempfile from isort.isort import SortImports from isort.settings import WrapModes @@ -1422,3 +1427,17 @@ def test_import_split_is_word_boundary_aware(): assert test_output == ("from mycompany.model.size_value_array_import_func import \\\n" " get_size_value_array_import_func_jobs\n") + + +def test_other_file_encodings(): + """Test to ensure file encoding is respected""" + try: + tmp_dir = tempfile.mkdtemp() + for encoding in ('latin1', 'utf8'): + tmp_fname = os.path.join(tmp_dir, 'test_{}.py'.format(encoding)) + with codecs.open(tmp_fname, mode='w', encoding=encoding) as f: + file_contents = "# coding: {0}\n\ns = u'ã'\n".format(encoding) + f.write(file_contents) + assert SortImports(file_path=tmp_fname).output == file_contents + finally: + shutil.rmtree(tmp_dir, ignore_errors=True) |
