From 2179650b05f54dc00f9c01d687ea6dc7f1b80e42 Mon Sep 17 00:00:00 2001 From: Maxim Kurnikov Date: Thu, 25 Apr 2019 23:04:20 +0300 Subject: extract file contents read into separate method --- isort/isort.py | 86 +++++++++++++++++++++++++++++++--------------------------- 1 file changed, 46 insertions(+), 40 deletions(-) diff --git a/isort/isort.py b/isort/isort.py index 3776bb01..370c6b72 100644 --- a/isort/isort.py +++ b/isort/isort.py @@ -26,6 +26,7 @@ OTHER DEALINGS IN THE SOFTWARE. """ import copy import itertools +import locale import os import re import sys @@ -84,7 +85,6 @@ class _SortImports(object): self.file_encoding = 'utf-8' file_name = file_path self.file_path = file_path or "" - if file_path: file_path = os.path.abspath(file_path) if check_skip: @@ -98,34 +98,26 @@ class _SortImports(object): self.skipped = True if self.config['verbose']: print("WARNING: {0} was skipped as it's listed in 'skip' setting" - " or matches a glob in 'skip_glob' setting".format(file_path)) + " or matches a glob in 'skip_glob' setting".format(file_path)) file_contents = None + if not self.skipped and not file_contents: - file_encoding = coding_check(file_path) - with open(file_path, encoding=file_encoding, newline='') as file_to_import_sort: - try: - file_contents = file_to_import_sort.read() - self.file_path = file_path - self.file_encoding = file_encoding - encoding_success = True - except UnicodeDecodeError: - encoding_success = False - - if not encoding_success: - with open(file_path, newline='') as file_to_import_sort: - try: - file_contents = file_to_import_sort.read() - self.file_path = file_path - self.file_encoding = file_to_import_sort.encoding - except UnicodeDecodeError: - encoding_success = False - file_contents = None - self.skipped = True - if self.config['verbose']: - print("WARNING: {} was skipped as it couldn't be opened with the given " - "{} encoding or {} fallback encoding".format(file_path, - self.file_encoding, - file_to_import_sort.encoding)) + preferred_encoding = determine_file_encoding(file_path) + # default encoding for open(mode='r') on the system + fallback_encoding = locale.getpreferredencoding(False) + + file_contents, used_encoding = self.read_file_contents(file_path, + encoding=preferred_encoding, + fallback_encoding=fallback_encoding) + if used_encoding is None: + self.skipped = True + if self.config['verbose']: + print("WARNING: {} was skipped as it couldn't be opened with the given " + "{} encoding or {} fallback encoding".format(file_path, + self.file_encoding, + fallback_encoding)) + else: + self.file_encoding = used_encoding if file_contents is None or ("isort:" + "skip_file") in file_contents: self.skipped = True @@ -134,10 +126,7 @@ class _SortImports(object): sys.stdout.write(file_contents) return - if self.config['line_ending']: - self.line_separator = self.config['line_ending'] - else: - self.line_separator = utils.infer_line_separator(file_contents) + self.line_separator = self.determine_line_separator(file_contents) self.in_lines = file_contents.split(self.line_separator) self.original_num_of_lines = len(self.in_lines) @@ -172,19 +161,20 @@ class _SortImports(object): self.output = self.line_separator.join(self.out_lines) if self.config['atomic']: try: - compile(self._strip_top_comments(self.out_lines, self.line_separator), self.file_path, 'exec', 0, 1) + out_lines_without_top_comment = self._strip_top_comments(self.out_lines, self.line_separator) + compile(out_lines_without_top_comment, self.file_path, 'exec', 0, 1) except SyntaxError: self.output = file_contents self.incorrectly_sorted = True try: - compile(self._strip_top_comments(self.in_lines, self.line_separator), self.file_path, 'exec', 0, 1) + in_lines_without_top_comment = self._strip_top_comments(self.in_lines, self.line_separator) + compile(in_lines_without_top_comment, self.file_path, 'exec', 0, 1) print("ERROR: {0} isort would have introduced syntax errors, please report to the project!". format(self.file_path)) except SyntaxError: print("ERROR: {0} File contains syntax errors.".format(self.file_path)) return - if check: check_output = self.output check_against = file_contents @@ -199,7 +189,6 @@ class _SortImports(object): print("ERROR: {0} Imports are incorrectly sorted.".format(self.file_path)) self.incorrectly_sorted = True - if show_diff or self.config['show_diff']: self._show_diff(file_contents) elif write_to_stdout: @@ -223,6 +212,27 @@ class _SortImports(object): print("Fixing {0}".format(self.file_path)) output_file.write(self.output) + def determine_line_separator(self, file_contents: str) -> str: + if self.config['line_ending']: + return self.config['line_ending'] + else: + return utils.infer_line_separator(file_contents) + + def read_file_contents(self, 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 + @property def correctly_sorted(self) -> bool: return not self.incorrectly_sorted @@ -1088,11 +1098,7 @@ class _SortImports(object): self.imports[placed_module][import_type][module] = None -def coding_check( - fname: str, - default: str = 'utf-8' -) -> str: - +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.]+)') -- cgit v1.2.1