diff options
Diffstat (limited to 'isort/compat.py')
-rw-r--r-- | isort/compat.py | 66 |
1 files changed, 37 insertions, 29 deletions
diff --git a/isort/compat.py b/isort/compat.py index d3ea4ced..2dd41fa0 100644 --- a/isort/compat.py +++ b/isort/compat.py @@ -2,6 +2,7 @@ import locale import os import re import sys +from pathlib import Path from typing import Any, Optional, Tuple from isort import settings @@ -9,12 +10,12 @@ from isort.format import ask_whether_to_apply_changes_to_file, show_unified_diff from isort.isort import _SortImports -def determine_file_encoding(fname: str, default: str = 'utf-8') -> str: +def determine_file_encoding(file_path: Path, 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: + with file_path.open('rb') as f: for line_number, line in enumerate(f, 1): groups = re.findall(pattern, line) if groups: @@ -26,15 +27,15 @@ def determine_file_encoding(fname: str, default: str = 'utf-8') -> str: 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: +def read_file_contents(file_path: Path, encoding: str, fallback_encoding: str) -> Tuple[Optional[str], Optional[str]]: + with file_path.open(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: + with file_path.open(encoding=fallback_encoding, newline='') as file_to_import_sort: try: file_contents = file_to_import_sort.read() return file_contents, fallback_encoding @@ -42,14 +43,14 @@ def read_file_contents(file_path: str, encoding: str, fallback_encoding: str) -> return None, None -def get_settings_path(settings_path: Optional[str], current_file_path: Optional[str]) -> str: +def get_settings_path(settings_path: Optional[Path], current_file_path: Optional[Path]) -> Path: if settings_path: return settings_path if current_file_path: - return os.path.dirname(os.path.abspath(current_file_path)) + return current_file_path.resolve().parent else: - return os.getcwd() + return Path.cwd() class SortImports(object): @@ -69,44 +70,48 @@ class SortImports(object): check_skip: bool = True, **setting_overrides: Any ): + file_path = None if file_path is None else Path(file_path) + settings_path = None if settings_path is None else Path(settings_path) + 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.file_path = file_path or "" + self.file_path = None if file_path: - file_path = os.path.abspath(file_path) + self.file_path = file_path # raw file path (unresolved) ? + + absolute_file_path = file_path.resolve() if check_skip: - if run_path and file_path.startswith(run_path): - file_name = os.path.relpath(file_path, run_path) + if run_path and run_path in absolute_file_path.parents: + file_name = os.path.relpath(absolute_file_path, run_path) else: - file_name = file_path + file_name = str(absolute_file_path) run_path = '' if settings.file_should_be_skipped(file_name, self.config, run_path): 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(absolute_file_path)) file_contents = None if not self.skipped and not file_contents: - preferred_encoding = determine_file_encoding(file_path) + preferred_encoding = determine_file_encoding(absolute_file_path) # default encoding for open(mode='r') on the system fallback_encoding = locale.getpreferredencoding(False) - file_contents, used_encoding = read_file_contents(file_path, + file_contents, used_encoding = read_file_contents(absolute_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, + "{} encoding or {} fallback encoding".format(str(absolute_file_path), file_encoding, fallback_encoding)) else: @@ -123,19 +128,20 @@ class SortImports(object): self.output = self.sorted_imports.output if self.config['atomic']: + logging_file_path = str(self.file_path or '') try: out_lines_without_top_comment = self.sorted_imports.get_out_lines_without_top_comment() - compile(out_lines_without_top_comment, self.file_path, 'exec', 0, 1) + compile(out_lines_without_top_comment, logging_file_path, 'exec', 0, 1) except SyntaxError: self.output = file_contents self.incorrectly_sorted = True try: in_lines_without_top_comment = self.sorted_imports.get_in_lines_without_top_comment() - compile(in_lines_without_top_comment, self.file_path, 'exec', 0, 1) + compile(in_lines_without_top_comment, logging_file_path, 'exec', 0, 1) print("ERROR: {0} isort would have introduced syntax errors, please report to the project!". - format(self.file_path)) + format(logging_file_path)) except SyntaxError: - print("ERROR: {0} File contains syntax errors.".format(self.file_path)) + print("ERROR: {0} File contains syntax errors.".format(logging_file_path)) return @@ -143,11 +149,12 @@ class SortImports(object): check_output = self.output check_against = file_contents if self.config['ignore_whitespace']: - check_output = check_output.replace(self.sorted_imports.line_separator, "").replace(" ", "").replace("\x0c", "") - check_against = check_against.replace(self.sorted_imports.line_separator, "").replace(" ", "").replace("\x0c", "") + check_output = self.sorted_imports.remove_whitespaces(check_output) + check_against = self.sorted_imports.remove_whitespaces(check_against) - current_input_sorted_correctly = self.sorted_imports.check_if_input_already_sorted(check_output, check_against, - current_file_path=self.file_path) + current_input_sorted_correctly = (self.sorted_imports + .check_if_input_already_sorted(check_output, check_against, + logging_file_path=str(self.file_path or ''))) if current_input_sorted_correctly: return else: @@ -160,18 +167,19 @@ class SortImports(object): elif write_to_stdout: sys.stdout.write(self.output) - elif file_name and not check: + elif self.file_path and not check: + # if file_name resolves to True, file_path never None or '' if self.output == file_contents: return if ask_to_apply: show_unified_diff(file_input=file_contents, file_output=self.output, file_path=self.file_path) - apply_changes = ask_whether_to_apply_changes_to_file(self.file_path) + apply_changes = ask_whether_to_apply_changes_to_file(str(self.file_path)) if not apply_changes: return - with open(self.file_path, 'w', encoding=file_encoding, newline='') as output_file: + with self.file_path.open('w', encoding=file_encoding, newline='') as output_file: if not self.config['quiet']: print("Fixing {0}".format(self.file_path)) |