summaryrefslogtreecommitdiff
path: root/isort/compat.py
diff options
context:
space:
mode:
Diffstat (limited to 'isort/compat.py')
-rw-r--r--isort/compat.py73
1 files changed, 44 insertions, 29 deletions
diff --git a/isort/compat.py b/isort/compat.py
index d3ea4ced..5fa33729 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,21 @@ 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 resolve(path: Path) -> Path:
+ if sys.version_info[:2] >= (3, 6):
+ return path.resolve()
+ else:
+ return Path(os.path.abspath(str(path)))
+
+
+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 resolve(current_file_path).parent
else:
- return os.getcwd()
+ return Path.cwd()
class SortImports(object):
@@ -69,44 +77,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 = resolve(file_path)
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 +135,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 +156,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 +174,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))