summaryrefslogtreecommitdiff
path: root/isort/compat.py
diff options
context:
space:
mode:
Diffstat (limited to 'isort/compat.py')
-rw-r--r--isort/compat.py69
1 files changed, 52 insertions, 17 deletions
diff --git a/isort/compat.py b/isort/compat.py
index 1b3ba7cb..03d34f11 100644
--- a/isort/compat.py
+++ b/isort/compat.py
@@ -1,14 +1,61 @@
import locale
import os
+import re
import sys
-from typing import Any, Optional
+from typing import Any, Dict, Optional, Tuple
from isort import settings
from isort.format import ask_whether_to_apply_changes_to_file, show_unified_diff
-from isort.isort import _SortImports, determine_file_encoding, read_file_contents
+from isort.isort import _SortImports
+
+
+def determine_file_encoding(fname: str, default: str = 'utf-8') -> str:
+ # see https://www.python.org/dev/peps/pep-0263/
+ pattern = re.compile(br'coding[:=]\s*([-\w.]+)')
+
+ coding = default
+ with 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
+
+
+def read_file_contents(file_path: str, encoding: str, fallback_encoding: str) -> Tuple[Optional[str], Optional[str]]:
+ with open(file_path, encoding=encoding, newline='') as file_to_import_sort:
+ try:
+ file_contents = file_to_import_sort.read()
+ return file_contents, encoding
+ except UnicodeDecodeError:
+ pass
+
+ with open(file_path, encoding=fallback_encoding, newline='') as file_to_import_sort:
+ try:
+ file_contents = file_to_import_sort.read()
+ return file_contents, fallback_encoding
+ except UnicodeDecodeError:
+ return None, None
+
+
+def get_settings_path(settings_path: Optional[str], current_file_path: str) -> str:
+ if settings_path:
+ return settings_path
+
+ if current_file_path:
+ return os.path.dirname(os.path.abspath(current_file_path))
+ else:
+ return os.getcwd()
class SortImports(object):
+ incorrectly_sorted = False
+ skipped = False
+
def __init__(
self,
file_path: Optional[str] = None,
@@ -22,21 +69,13 @@ class SortImports(object):
check_skip: bool = True,
**setting_overrides: Any
):
- _settings_path = settings_path
- if _settings_path is None:
- if file_path:
- _settings_path = os.path.dirname(os.path.abspath(file_path))
- else:
- _settings_path = os.getcwd()
-
- self.config = settings.prepare_config(_settings_path, **setting_overrides)
+ self.config = settings.prepare_config(get_settings_path(settings_path, file_path),
+ **setting_overrides)
self.output = None
file_encoding = 'utf-8'
file_name = file_path
- self.skipped = False
-
self.file_path = file_path or ""
if file_path:
file_path = os.path.abspath(file_path)
@@ -75,7 +114,6 @@ class SortImports(object):
if file_contents is None or ("isort:" + "skip_file") in file_contents:
self.skipped = True
- # self.output = None
if write_to_stdout and file_contents:
sys.stdout.write(file_contents)
return
@@ -85,6 +123,7 @@ class SortImports(object):
check=check,
config=self.config)
self.output = self.sorted_imports.output
+ self.incorrectly_sorted = self.sorted_imports.incorrectly_sorted
if show_diff or self.config['show_diff']:
show_unified_diff(file_input=file_contents, file_output=self.output,
@@ -115,9 +154,5 @@ class SortImports(object):
return self.sorted_imports.sections
@property
- def incorrectly_sorted(self):
- return self.sorted_imports.incorrectly_sorted
-
- @property
def length_change(self) -> int:
return self.sorted_imports.length_change