diff options
Diffstat (limited to 'isort/compat.py')
-rw-r--r-- | isort/compat.py | 69 |
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 |