diff options
author | Timothy Crosley <timothy.crosley@gmail.com> | 2019-11-08 00:34:48 -0800 |
---|---|---|
committer | Timothy Crosley <timothy.crosley@gmail.com> | 2019-11-08 00:34:48 -0800 |
commit | 592d07a364a7d8a2fcf2c2b55e42a8f6507209e6 (patch) | |
tree | 4d8c4b37aba36811c037ae50970ab064efc20d08 | |
parent | aaac1ae0667dabe6fd038c9f5a42c157b9457ef1 (diff) | |
download | isort-592d07a364a7d8a2fcf2c2b55e42a8f6507209e6.tar.gz |
Fix all discovered mypy errors
-rw-r--r-- | isort/api.py | 70 | ||||
-rw-r--r-- | isort/compat.py | 53 | ||||
-rw-r--r-- | isort/exceptions.py | 22 | ||||
-rw-r--r-- | isort/finders.py | 25 | ||||
-rw-r--r-- | isort/format.py | 6 | ||||
-rw-r--r-- | isort/io.py | 13 | ||||
-rw-r--r-- | isort/isort.py | 57 | ||||
-rw-r--r-- | isort/main.py | 30 | ||||
-rw-r--r-- | isort/output.py | 17 | ||||
-rw-r--r-- | isort/settings.py | 58 | ||||
-rw-r--r-- | isort/wrap.py | 10 | ||||
-rw-r--r-- | tests/test_isort.py | 17 |
12 files changed, 199 insertions, 179 deletions
diff --git a/isort/api.py b/isort/api.py index 1f7cbdec..22802a97 100644 --- a/isort/api.py +++ b/isort/api.py @@ -3,27 +3,48 @@ from pathlib import Path from typing import Any, NamedTuple, Optional, Tuple from . import output, parse -from .exceptions import FileSkipComment, IntroducedSyntaxErrors, UnableToDetermineEncoding, ExistingSyntaxErrors, FileSkipSetting +from .exceptions import ( + ExistingSyntaxErrors, + FileSkipComment, + FileSkipSetting, + IntroducedSyntaxErrors, + UnableToDetermineEncoding, +) +from .format import remove_whitespace, show_unified_diff from .io import File -from .format import remove_whitespace from .settings import DEFAULT_CONFIG, FILE_SKIP_COMMENT, Config -def _config(path: Optional[Path]=None, config: Config=DEFAULT_CONFIG, **config_kwargs) -> Config: +def _config( + path: Optional[Path] = None, config: Config = DEFAULT_CONFIG, **config_kwargs +) -> Config: if path: - if config is DEFAULT_CONFIG and not "settings_path" in config_kwargs and not "settings_file" in config_kwargs: + if ( + config is DEFAULT_CONFIG + and not "settings_path" in config_kwargs + and not "settings_file" in config_kwargs + ): config_kwargs["settings_path"] = path if config_kwargs and config is not DEFAULT_CONFIG: - raise ValueError("You can either specify custom configuration options using kwargs or " - "passing in a Config object. Not Both!") + raise ValueError( + "You can either specify custom configuration options using kwargs or " + "passing in a Config object. Not Both!" + ) elif config_kwargs: config = Config(**config_kwargs) return config -def sorted_imports(file_contents: str, extension: str = "py", config: Config=DEFAULT_CONFIG, file_path: Optional[Path]=None, disregard_skip: bool=False, **config_kwargs) -> str: +def sorted_imports( + file_contents: str, + extension: str = "py", + config: Config = DEFAULT_CONFIG, + file_path: Optional[Path] = None, + disregard_skip: bool = False, + **config_kwargs, +) -> str: config = _config(config=config, **config_kwargs) content_source = str(file_path or "Passed in content") if not disregard_skip: @@ -31,7 +52,7 @@ def sorted_imports(file_contents: str, extension: str = "py", config: Config=DEF raise FileSkipComment(content_source) elif file_path and config.is_skipped(file_path): - raise FileSkipSetting(file_path) + raise FileSkipSetting(content_source) if config.atomic: try: @@ -39,7 +60,9 @@ def sorted_imports(file_contents: str, extension: str = "py", config: Config=DEF except SyntaxError: raise ExistingSyntaxErrors(content_source) - parsed_output = output.sorted_imports(parse.file_contents(file_contents, config=config), config, extension) + parsed_output = output.sorted_imports( + parse.file_contents(file_contents, config=config), config, extension + ) if config.atomic: try: compile(file_contents, content_source, "exec", 0, 1) @@ -48,10 +71,25 @@ def sorted_imports(file_contents: str, extension: str = "py", config: Config=DEF return parsed_output -def check_imports(file_contents: str, show_diff: bool=False, extension: str = "py", config: Config=DEFAULT_CONFIG, file_path: Optional[Path]=None, disregard_skip: bool=False, **config_kwargs) -> str: +def check_imports( + file_contents: str, + show_diff: bool = False, + extension: str = "py", + config: Config = DEFAULT_CONFIG, + file_path: Optional[Path] = None, + disregard_skip: bool = False, + **config_kwargs, +) -> bool: config = _config(config=config, **config_kwargs) - sorted_output = sorted_imports(file_contents=file_contents, extension=extension, config=config, file_path=file_path, disregard_skip=disregard_skip, **config_kwargs) + sorted_output = sorted_imports( + file_contents=file_contents, + extension=extension, + config=config, + file_path=file_path, + disregard_skip=disregard_skip, + **config_kwargs, + ) if config.ignore_whitespace: line_separator = config.line_ending or parse._infer_line_separator(file_contents) compare_in = remove_whitespace(file_contents, line_separator=line_separator).strip() @@ -73,7 +111,13 @@ def check_imports(file_contents: str, show_diff: bool=False, extension: str = "p return False -def sorted_file(filename: str, config: Config=DEFAULT_CONFIG, **config_kwargs) -> str: +def sorted_file(filename: str, config: Config = DEFAULT_CONFIG, **config_kwargs) -> str: file_data = File.read(filename) config = _config(path=file_data.path.parent, config=config) - return sorted_contents(file_contents=file_data.contents, extension=file_data.extension, config=config, file_path=file_data.path, **config_kwargs) + return sorted_imports( + file_contents=file_data.contents, + extension=file_data.extension, + config=config, + file_path=file_data.path, + **config_kwargs, + ) diff --git a/isort/compat.py b/isort/compat.py index 0b92aed6..3ff70f62 100644 --- a/isort/compat.py +++ b/isort/compat.py @@ -7,10 +7,9 @@ from typing import Any, Optional, Tuple from warnings import warn from . import api, settings -from .exceptions import FileSkipped, ExistingSyntaxErrors, IntroducedSyntaxErrors +from .exceptions import ExistingSyntaxErrors, FileSkipped, IntroducedSyntaxErrors from .format import ask_whether_to_apply_changes_to_file, show_unified_diff from .io import File -from .isort import _SortImports from .settings import Config @@ -30,7 +29,7 @@ class SortImports: def __init__( self, - file_path: Optional[str] = None, + filename: Optional[str] = None, file_contents: str = "", write_to_stdout: bool = False, check: bool = False, @@ -39,15 +38,16 @@ class SortImports: ask_to_apply: bool = False, run_path: str = "", check_skip: bool = True, - extension: Optional[str] = None, + extension: str = "", **setting_overrides: Any, ): file_encoding = "utf-8" - if file_path: + file_path: Optional[Path] = None + if filename: if file_contents: - file_data = File.from_contents(file_contents, filename=file_path) + file_data = File.from_contents(file_contents, filename=filename) else: - file_data = File.read(file_path) + file_data = File.read(filename) file_contents, file_path, file_encoding = file_data if not extension: extension = file_data.extension @@ -61,16 +61,24 @@ class SortImports: try: if check: - self.incorrectly_sorted = not api.check_imports(file_contents, extension=extension, config=config, file_path=file_path, show_diff=show_diff) + self.incorrectly_sorted = not api.check_imports( + file_contents, + extension=extension, + config=config, + file_path=file_path, + show_diff=show_diff, + ) self.output = "" return else: - self.output = api.sorted_imports(file_contents, extension=extension, config=config, file_path=file_path) + self.output = api.sorted_imports( + file_contents, extension=extension, config=config, file_path=file_path + ) except FileSkipped as error: self.skipped = True - self.output = None + self.output = "" if config.verbose: - warn(error.message) + warn(str(error)) return except ExistingSyntaxErrors: warn("{file_path} unable to sort due to existing syntax errors") @@ -81,21 +89,6 @@ class SortImports: self.output = file_contents return - if check: - check_output = self.output - check_against = file_contents - if config.ignore_whitespace: - 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, logging_file_path=str(file_path or "") - ) - if current_input_sorted_correctly: - return - else: - self.incorrectly_sorted = True - if show_diff: show_unified_diff( file_input=file_contents, file_output=self.output, file_path=file_path @@ -122,11 +115,3 @@ class SortImports: print(f"Fixing {file_path}") output_file.write(self.output) - - @property - def sections(self): - return self.sorted_imports.parsed.sections - - @property - def length_change(self) -> int: - return self.sorted_imports.parsed.change_count diff --git a/isort/exceptions.py b/isort/exceptions.py index 02a4eb93..4c512fd3 100644 --- a/isort/exceptions.py +++ b/isort/exceptions.py @@ -24,7 +24,7 @@ class UnableToDetermineEncoding(ISortError): class ExistingSyntaxErrors(ISortError): """Raised when isort is told to sort imports within code that has existing syntax errors""" - def __init__(self, file_path: Path): + def __init__(self, file_path: str): super().__init__( f"isort was told to sort imports within code that contains syntax errors: " f"{file_path}." @@ -34,7 +34,7 @@ class ExistingSyntaxErrors(ISortError): class IntroducedSyntaxErrors(ISortError): """Raised when isort has introduced a syntax error in the process of sorting imports""" - def __init__(self, file_path: Path): + def __init__(self, file_path: str): super().__init__( f"isort introduced syntax errors when attempting to sort the imports contained within " f"{file_path}." @@ -44,7 +44,7 @@ class IntroducedSyntaxErrors(ISortError): class FileSkipped(ISortError): """Should be raised when a file is skipped for any reason""" - def __init__(self, message: str, file_path: Path): + def __init__(self, message: str, file_path: str): super().__init__(message) self.file_path = file_path @@ -52,13 +52,19 @@ class FileSkipped(ISortError): class FileSkipComment(FileSkipped): """Raised when an entire file is skipped due to a isort skip file comment""" - def __init__(self, file_path: Path): - super().__init__(f"{file_path} contains an {FILE_SKIP_COMMENT} comment and was skipped.", file_path=file_path) + def __init__(self, file_path: str): + super().__init__( + f"{file_path} contains an {FILE_SKIP_COMMENT} comment and was skipped.", + file_path=file_path, + ) class FileSkipSetting(FileSkipped): """Raised when an entire file is skipped due to provided isort settings""" - def __init__(self, file_path: Path): - super().__init__(f"{file_path} was skipped as it's listed in 'skip' setting" - " or matches a glob in 'skip_glob' setting", file_path=file_path) + def __init__(self, file_path: str): + super().__init__( + f"{file_path} was skipped as it's listed in 'skip' setting" + " or matches a glob in 'skip_glob' setting", + file_path=file_path, + ) diff --git a/isort/finders.py b/isort/finders.py index 2cd2e37e..d63cc94b 100644 --- a/isort/finders.py +++ b/isort/finders.py @@ -10,12 +10,23 @@ from abc import ABCMeta, abstractmethod from fnmatch import fnmatch from functools import lru_cache from glob import glob -from typing import (Any, Dict, Iterable, Iterator, List, Mapping, - Optional, Pattern, Sequence, Tuple, Type) +from typing import ( + Any, + Dict, + Iterable, + Iterator, + List, + Mapping, + Optional, + Pattern, + Sequence, + Tuple, + Type, +) +from . import sections from .settings import DEFAULT_CONFIG, Config from .utils import chdir, exists_case_sensitive -from . import sections try: from pipreqs import pipreqs @@ -77,7 +88,9 @@ class KnownPatternFinder(BaseFinder): for placement in reversed(config.sections): known_placement = KNOWN_SECTION_MAPPING.get(placement, placement).lower() config_key = f"known_{known_placement}" - known_patterns = list(getattr(self.config, config_key, self.config.known_other.get(known_placement, []))) + known_patterns = list( + getattr(self.config, config_key, self.config.known_other.get(known_placement, [])) + ) known_patterns = [ pattern for known_pattern in known_patterns @@ -361,9 +374,7 @@ class FindersManager: ) def __init__( - self, - config: Config, - finder_classes: Optional[Iterable[Type[BaseFinder]]] = None, + self, config: Config, finder_classes: Optional[Iterable[Type[BaseFinder]]] = None ) -> None: self.verbose: bool = config.verbose diff --git a/isort/format.py b/isort/format.py index a03bea5d..f98b10ef 100644 --- a/isort/format.py +++ b/isort/format.py @@ -58,8 +58,6 @@ def ask_whether_to_apply_changes_to_file(file_path: str) -> bool: return True -def remove_whitespace(content: str, line_separator: str="\n") -> str: - content = ( - content.replace(line_separator, "").replace(" ", "").replace("\x0c", "") - ) +def remove_whitespace(content: str, line_separator: str = "\n") -> str: + content = content.replace(line_separator, "").replace(" ", "").replace("\x0c", "") return content diff --git a/isort/io.py b/isort/io.py index 4ad5dd1c..5845e9c1 100644 --- a/isort/io.py +++ b/isort/io.py @@ -1,8 +1,11 @@ """Defines any IO utilities used by isort""" +import locale import re from pathlib import Path from typing import NamedTuple, Optional, Tuple +from .exceptions import UnableToDetermineEncoding + _ENCODING_PATTERN = re.compile(br"^[ \t\f]*#.*?coding[:=][ \t]*([-_.a-zA-Z0-9]+)") @@ -19,7 +22,9 @@ class File(NamedTuple): @staticmethod def from_contents(contents: str, filename: str) -> "File": - return File(contents, path=Path(filename).resolve(), encoding=_determine_content_encoding(contents)) + return File( + contents, path=Path(filename).resolve(), encoding=_determine_content_encoding(contents) + ) @property def extension(self): @@ -47,9 +52,7 @@ def _determine_file_encoding(file_path: Path, default: str = "utf-8") -> str: return _determine_stream_encoding(open_file, default=default) -def _read_file_contents( - file_path: Path -) -> Tuple[Optional[str], Optional[str]]: +def _read_file_contents(file_path: Path) -> Tuple[str, str]: encoding = _determine_file_encoding(file_path) with file_path.open(encoding=encoding, newline="") as file_to_import_sort: try: @@ -59,7 +62,7 @@ def _read_file_contents( pass # Try default encoding for open(mode='r') on the system - fallback_encoding = _locale.getpreferredencoding(False) + fallback_encoding = locale.getpreferredencoding(False) with file_path.open(encoding=fallback_encoding, newline="") as file_to_import_sort: try: file_contents = file_to_import_sort.read() diff --git a/isort/isort.py b/isort/isort.py index d71d2966..30e5a5c9 100644 --- a/isort/isort.py +++ b/isort/isort.py @@ -1,56 +1 @@ -"""Exposes a simple library to sort through imports within Python code - -usage: - SortImports(file_name) -or: - sorted = SortImports(file_contents=file_contents).output -""" -# isort:skip_file -import copy -import itertools -import re -from collections import OrderedDict, defaultdict, namedtuple -from typing import Any, Dict, Iterable, List, Mapping, Optional, Sequence, Tuple - -from isort import utils - -from . import output, parse, settings, sorting, wrap - - -class _SortImports: - def __init__(self, file_contents: str, config: Dict[str, Any], extension: str = "py") -> None: - self.config = config - - self.parsed = parse.file_contents(file_contents, config=self.config) - self.output = output.sorted_imports(self.parsed, self.config, extension) - - def remove_whitespaces(self, contents: str) -> str: - contents = ( - contents.replace(self.parsed.line_separator, "").replace(" ", "").replace("\x0c", "") - ) - return contents - - def get_out_lines_without_top_comment(self) -> str: - return self._strip_top_comments(self.out_lines, self.parsed.line_separator) - - def get_in_lines_without_top_comment(self) -> str: - return self._strip_top_comments(self.parsed.in_lines, self.parsed.line_separator) - - def check_if_input_already_sorted( - self, output: str, check_against: str, *, logging_file_path: str - ) -> bool: - if output.strip() == check_against.strip(): - if self.config["verbose"]: - print(f"SUCCESS: {logging_file_path} Everything Looks Good!") - return True - - print(f"ERROR: {logging_file_path} Imports are incorrectly sorted.") - return False - - @staticmethod - def _strip_top_comments(lines: Sequence[str], line_separator: str) -> str: - """Strips # comments that exist at the top of the given lines""" - lines = copy.copy(lines) - while lines and lines[0].startswith("#"): - lines = lines[1:] - return line_separator.join(lines) +from .compat import SortImports diff --git a/isort/main.py b/isort/main.py index ef82bead..1616f9c5 100644 --- a/isort/main.py +++ b/isort/main.py @@ -13,15 +13,8 @@ import setuptools from isort import SortImports, __version__ from isort.logo import ASCII_ART -from isort.settings import ( - VALID_PY_TARGETS, - WrapModes, - Config - # default, - # file_should_be_skipped, - # from_path, - # wrap_mode_from_string, -) +from isort.settings import DEFAULT_CONFIG, VALID_PY_TARGETS, Config, WrapModes + from . import sections shebang_re = re.compile(br"^#!.*\bpython[23w]?\b") @@ -62,9 +55,7 @@ def sort_imports(file_name: str, **arguments: Any) -> Optional[SortAttempt]: return None -def iter_source_code( - paths: Iterable[str], config: Config, skipped: List[str] -) -> Iterator[str]: +def iter_source_code(paths: Iterable[str], config: Config, skipped: List[str]) -> Iterator[str]: """Iterate over all Python source files defined in paths.""" for path in paths: if os.path.isdir(path): @@ -94,14 +85,14 @@ class ISortCommand(setuptools.Command): user_options: List[Any] = [] def initialize_options(self) -> None: - default_settings = default.copy() + default_settings = vars(DEFAULT_CONFIG).copy() for key, value in default_settings.items(): setattr(self, key, value) def finalize_options(self) -> None: "Get options from config files." self.arguments: Dict[str, Any] = {} - computed_settings = from_path(os.getcwd()) + computed_settings = vars(Config(directory=os.getcwd())) for key, value in computed_settings.items(): self.arguments[key] = value @@ -319,8 +310,9 @@ def parse_args(argv: Optional[Sequence[str]] = None) -> Dict[str, Any]: "-m", "--multi-line", dest="multi_line_output", - choices=WrapModes.__members__, - type=WrapModes.__getitem__, + choices=list(WrapModes.__members__.keys()) + + [str(mode.value) for mode in WrapModes.__members__.values()], + type=str, help="Multi line output (0-grid, 1-vertical, 2-hanging, 3-vert-hanging, 4-vert-grid, " "5-vert-grid-grouped, 6-vert-grid-grouped-no-comma).", ) @@ -537,6 +529,12 @@ def parse_args(argv: Optional[Sequence[str]] = None) -> Dict[str, Any]: arguments = {key: value for key, value in vars(parser.parse_args(argv)).items() if value} if "dont_order_by_type" in arguments: arguments["order_by_type"] = False + multi_line_output = arguments.get("multi_line_output", None) + if multi_line_output: + if multi_line_output.isdigit(): + arguments["multi_line_output"] = WrapModes(int(multi_line_output)) + else: + arguments["multi_line_output"] = WrapModes[multi_line_output] return arguments diff --git a/isort/output.py b/isort/output.py index 9161cfdf..fe58466b 100644 --- a/isort/output.py +++ b/isort/output.py @@ -439,27 +439,28 @@ def _with_from_imports( len(import_statement) > config.line_length and len(from_import_section) > 0 and config.multi_line_output - not in (wrap.Modes.GRID, wrap.Modes.VERTICAL) # type: ignore # type: ignore + not in (wrap.Modes.GRID, wrap.Modes.VERTICAL) # type: ignore ): do_multiline_reformat = True if do_multiline_reformat: import_statement = wrap.import_statement( - import_start=import_start, from_imports=from_import_section, comments=comments, line_separator=parsed.line_separator, config=config + import_start=import_start, + from_imports=from_import_section, + comments=comments, + line_separator=parsed.line_separator, + config=config, ) - if config.multi_line_output == wrap.Modes.GRID: # type: ignore # type: ignore + if config.multi_line_output == wrap.Modes.GRID: # type: ignore other_import_statement = wrap.import_statement( import_start=import_start, from_imports=from_import_section, comments=comments, line_separator=parsed.line_separator, config=config, - multi_line_output=wrap.Modes.VERTICAL_GRID + multi_line_output=wrap.Modes.VERTICAL_GRID, # type: ignore ) - if ( - max(len(x) for x in import_statement.split("\n")) - > config.line_length - ): + if max(len(x) for x in import_statement.split("\n")) > config.line_length: import_statement = other_import_statement if not do_multiline_reformat and len(import_statement) > config.line_length: import_statement = wrap.line(import_statement, parsed.line_separator, config) diff --git a/isort/settings.py b/isort/settings.py index 17a74ceb..5ac7938d 100644 --- a/isort/settings.py +++ b/isort/settings.py @@ -13,7 +13,6 @@ import posixpath import re import sys import warnings -from pathlib import Path from distutils.util import strtobool as _as_bool from functools import lru_cache from pathlib import Path @@ -21,18 +20,19 @@ from typing import ( Any, Callable, Dict, + FrozenSet, Iterable, List, Mapping, MutableMapping, Optional, + Set, Tuple, Union, - FrozenSet, ) from warnings import warn -from . import stdlibs, sections +from . import sections, stdlibs from ._future import dataclass, field from .utils import difference, union from .wrap_modes import WrapModes @@ -51,7 +51,7 @@ try: except ImportError: appdirs = None -FILE_SKIP_COMMENT: str = ("isort:" + "skip_file") # Concatenated to avoid this file being skipped +FILE_SKIP_COMMENT: str = ("isort:" + "skip_file") # Concatenated to avoid this file being skipped MAX_CONFIG_SEARCH_DEPTH: int = 25 # The number of parent directories to for a config file within STOP_CONFIG_SEARCH_ON_DIRS: Tuple[str, ...] = (".git", ".hg") VALID_PY_TARGETS: Tuple[str, ...] = tuple( @@ -92,9 +92,27 @@ class _Config: NOTE: known lists, such as known_standard_library, are intentionally not complete as they are dynamically determined later on. """ + py_version: str = "3" force_to_top: FrozenSet[str] = frozenset() - skip: FrozenSet[str] = frozenset({".venv", "venv", ".tox", ".eggs", ".git", ".hg", ".mypy_cache", ".nox", "_build", "buck-out", "build", "dist", ".pants.d", "node_modules"}) + skip: FrozenSet[str] = frozenset( + { + ".venv", + "venv", + ".tox", + ".eggs", + ".git", + ".hg", + ".mypy_cache", + ".nox", + "_build", + "buck-out", + "build", + "dist", + ".pants.d", + "node_modules", + } + ) skip_glob: FrozenSet[str] = frozenset() line_length: int = 79 wrap_length: int = 0 @@ -172,9 +190,7 @@ class _Config: if not self.known_standard_library: object.__setattr__( - self, - "known_standard_library", - frozenset(getattr(stdlibs, self.py_version).stdlib), + self, "known_standard_library", frozenset(getattr(stdlibs, self.py_version).stdlib) ) if self.force_alphabetical_sort: @@ -219,15 +235,19 @@ class Config(_Config): indent = "\t" combined_config["indent"] = indent - known_other = {} import_headings = {} for key, value in combined_config.items(): # Collect all known sections beyond those that have direct entries - if key.startswith(KNOWN_PREFIX) and key not in ("known_standard_library", "known_future_library", "known_third_party", "known_first_party"): - known_other[key[len(KNOWN_PREFIX):].lower()] = frozenset(value) + if key.startswith(KNOWN_PREFIX) and key not in ( + "known_standard_library", + "known_future_library", + "known_third_party", + "known_first_party", + ): + known_other[key[len(KNOWN_PREFIX) :].lower()] = frozenset(value) if key.startswith(IMPORT_HEADING_PREFIX): - import_headings[key[len(IMPORT_HEADING_PREFIX):].lower()] = str(value) + import_headings[key[len(IMPORT_HEADING_PREFIX) :].lower()] = str(value) # Coerce all provided config values into their correct type default_value = _DEFAULT_SETTINGS.get(key, None) @@ -237,7 +257,9 @@ class Config(_Config): combined_config[key] = type(default_value)(value) if "directory" not in combined_config: - combined_config["directory"] = os.path.basename(config_settings.get("source", None) or os.getcwd()) + combined_config["directory"] = os.path.basename( + config_settings.get("source", None) or os.getcwd() + ) # Remove any config values that are used for creating config object but aren't defined in dataclass combined_config.pop("source", None) @@ -250,7 +272,7 @@ class Config(_Config): combined_config.pop(f"{IMPORT_HEADING_PREFIX}{import_heading_key}") combined_config["import_headings"] = import_headings - super().__init__(sources=tuple(sources), **combined_config) + super().__init__(sources=tuple(sources), **combined_config) # type: ignore def is_skipped(self, file_path: Path) -> bool: """Returns True if the file and/or folder should be skipped based on current settings.""" @@ -303,7 +325,7 @@ def _as_list(value: str) -> List[str]: return filtered -def _abspaths(cwd: str, values: Iterable[str]) -> List[str]: +def _abspaths(cwd: str, values: Iterable[str]) -> Set[str]: paths = set( [ os.path.join(cwd, value) @@ -405,14 +427,16 @@ def _get_config_data(file_path: str, sections: Iterable[str]) -> Dict[str, Any]: settings["line_length"] = ( float("inf") if max_line_length == "off" else int(max_line_length) ) - settings = {key: value for key, value in settings.items() if key in _DEFAULT_SETTINGS.keys()} + settings = { + key: value for key, value in settings.items() if key in _DEFAULT_SETTINGS.keys() + } for key, value in settings.items(): existing_value_type = _get_str_to_type_converter(key) if existing_value_type == tuple: settings[key] = tuple(_as_list(value)) elif existing_value_type == frozenset: - settings[key] = frozenset(_as_list(settings.get(key))) + settings[key] = frozenset(_as_list(settings.get(key))) # type: ignore elif existing_value_type == bool: # Only some configuration formats support native boolean values. if not isinstance(value, bool): diff --git a/isort/wrap.py b/isort/wrap.py index fa7349ba..db67f105 100644 --- a/isort/wrap.py +++ b/isort/wrap.py @@ -12,8 +12,8 @@ def import_statement( from_imports: List[str], comments: Sequence[str], line_separator: str, - config: Config=DEFAULT_CONFIG, - multi_line_output: Optional[Modes]=None + config: Config = DEFAULT_CONFIG, + multi_line_output: Optional[Modes] = None, ) -> str: """Returns a multi-line wrapped form of the provided from import statement.""" formatter = formatter_from_string((multi_line_output or config.multi_line_output).name) @@ -61,7 +61,7 @@ def import_statement( return import_statement -def line(line: str, line_separator: str, config: Config=DEFAULT_CONFIG) -> str: +def line(line: str, line_separator: str, config: Config = DEFAULT_CONFIG) -> str: """Returns a line wrapped to the specified line-length, if possible.""" wrap_mode = config.multi_line_output if len(line) > config.line_length and wrap_mode != Modes.NOQA: # type: ignore @@ -79,9 +79,7 @@ def line(line: str, line_separator: str, config: Config=DEFAULT_CONFIG) -> str: _comma_maybe = "," if config.include_trailing_comma else "" line_parts[-1] = f"{line_parts[-1].strip()}{_comma_maybe} #{comment}" next_line = [] - while (len(line) + 2) > ( - config.wrap_length or config.line_length - ) and line_parts: + while (len(line) + 2) > (config.wrap_length or config.line_length) and line_parts: next_line.append(line_parts.pop()) line = splitter.join(line_parts) if not line: diff --git a/tests/test_isort.py b/tests/test_isort.py index b65140c8..8424ed6a 100644 --- a/tests/test_isort.py +++ b/tests/test_isort.py @@ -486,7 +486,7 @@ def test_length_sort_section() -> None: "import looooooooooooooooooooooooooooooooooooooong\n" "import medium_sizeeeeeeeeeeeeea\n" ) - test_output = SortImports(file_contents=test_input, length_sort_sections=("stdlib", )).output + test_output = SortImports(file_contents=test_input, length_sort_sections=("stdlib",)).output assert test_output == ( "import os\n" "import sys\n" @@ -1217,7 +1217,9 @@ def test_smart_lines_after_import_section() -> None: def test_settings_overwrite() -> None: """Test to ensure settings overwrite instead of trying to combine.""" - assert Config(known_standard_library=["not_std_library"]).known_standard_library == frozenset({"not_std_library"}) + assert Config(known_standard_library=["not_std_library"]).known_standard_library == frozenset( + {"not_std_library"} + ) assert Config(known_first_party=["thread"]).known_first_party == frozenset({"thread"}) @@ -1574,7 +1576,9 @@ def test_long_line_comments() -> None: "sync_stage_envdir, " "update_stage_app, update_stage_cron # noqa\n" ) - assert SortImports(file_contents=test_input, line_length=100, balanced_wrapping=True).output == ( + assert SortImports( + file_contents=test_input, line_length=100, balanced_wrapping=True + ).output == ( "from foo.utils.fabric_stuff.live import (check_clean_live, deploy_live, # noqa\n" " sync_live_envdir, update_live_app, " "update_live_cron)\n" @@ -2681,7 +2685,10 @@ def test_no_extra_lines_issue_557() -> None: ) assert ( SortImports( - file_contents=test_input, force_alphabetical_sort=True, force_sort_within_sections=True, line_length=100 + file_contents=test_input, + force_alphabetical_sort=True, + force_sort_within_sections=True, + line_length=100, ).output == expected_output ) @@ -3087,7 +3094,7 @@ def test_monkey_patched_urllib() -> None: def test_path_finder(monkeypatch) -> None: - config = config=Config() + config = config = Config() finder = finders.PathFinder(config=config) third_party_prefix = next(path for path in finder.paths if "site-packages" in path) ext_suffixes = importlib.machinery.EXTENSION_SUFFIXES |