summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore1
-rw-r--r--isort/isort.py26
-rw-r--r--test_isort.py21
3 files changed, 44 insertions, 4 deletions
diff --git a/.gitignore b/.gitignore
index 186e1599..85f78d3a 100644
--- a/.gitignore
+++ b/.gitignore
@@ -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)