From 1662754ac4a5d3bf3ec1059810e828da89ea788a Mon Sep 17 00:00:00 2001 From: Timothy Crosley Date: Fri, 10 Jan 2020 08:13:56 -0800 Subject: Fix issue #1095 --- isort/main.py | 65 ++++---------------------------------------- isort/setuptools_commands.py | 65 ++++++++++++++++++++++++++++++++++++++++++++ tests/test_main.py | 5 ++++ 3 files changed, 76 insertions(+), 59 deletions(-) create mode 100644 isort/setuptools_commands.py diff --git a/isort/main.py b/isort/main.py index 27d01cc1..ca94c4ac 100644 --- a/isort/main.py +++ b/isort/main.py @@ -1,7 +1,6 @@ """Tool for sorting imports alphabetically, and automatically separated into sections.""" import argparse import functools -import glob import os import re import stat @@ -11,12 +10,15 @@ from pprint import pprint from typing import Any, Dict, Iterable, Iterator, List, Optional, Sequence from warnings import warn -import setuptools - from . import SortImports, __version__, sections from .logo import ASCII_ART from .profiles import profiles -from .settings import DEFAULT_CONFIG, SUPPORTED_EXTENSIONS, VALID_PY_TARGETS, Config, WrapModes +from .settings import SUPPORTED_EXTENSIONS, VALID_PY_TARGETS, Config, WrapModes + +try: + from .setuptools_commands import ISortCommand +except ImportError: + pass shebang_re = re.compile(br"^#!.*\bpython[23w]?\b") QUICK_GUIDE = f""" @@ -97,61 +99,6 @@ def iter_source_code(paths: Iterable[str], config: Config, skipped: List[str]) - yield path -class ISortCommand(setuptools.Command): - """The :class:`ISortCommand` class is used by setuptools to perform - imports checks on registered modules. - """ - - description = "Run isort on modules registered in setuptools" - user_options: List[Any] = [] - - def initialize_options(self) -> None: - 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 = vars(Config(directory=os.getcwd())) - for key, value in computed_settings.items(): - self.arguments[key] = value - - def distribution_files(self) -> Iterator[str]: - """Find distribution packages.""" - # This is verbatim from flake8 - if self.distribution.packages: - package_dirs = self.distribution.package_dir or {} - for package in self.distribution.packages: - pkg_dir = package - if package in package_dirs: - pkg_dir = package_dirs[package] - elif "" in package_dirs: - pkg_dir = package_dirs[""] + os.path.sep + pkg_dir - yield pkg_dir.replace(".", os.path.sep) - - if self.distribution.py_modules: - for filename in self.distribution.py_modules: - yield "%s.py" % filename - # Don't miss the setup.py file itself - yield "setup.py" - - def run(self) -> None: - arguments = self.arguments - wrong_sorted_files = False - arguments["check"] = True - for path in self.distribution_files(): - for python_file in glob.iglob(os.path.join(path, "*.py")): - try: - incorrectly_sorted = SortImports(python_file, **arguments).incorrectly_sorted - if incorrectly_sorted: - wrong_sorted_files = True - except OSError as error: - warn(f"Unable to parse file {python_file} due to {error}") - if wrong_sorted_files: - sys.exit(1) - - def parse_args(argv: Optional[Sequence[str]] = None) -> Dict[str, Any]: parser = argparse.ArgumentParser( description="Sort Python import definitions alphabetically " diff --git a/isort/setuptools_commands.py b/isort/setuptools_commands.py new file mode 100644 index 00000000..8da5c7f6 --- /dev/null +++ b/isort/setuptools_commands.py @@ -0,0 +1,65 @@ +import glob +import os +import sys +from typing import Any, Dict, Iterator, List +from warnings import warn + +import setuptools + +from . import SortImports +from .settings import DEFAULT_CONFIG, Config + + +class ISortCommand(setuptools.Command): + """The :class:`ISortCommand` class is used by setuptools to perform + imports checks on registered modules. + """ + + description = "Run isort on modules registered in setuptools" + user_options: List[Any] = [] + + def initialize_options(self) -> None: + 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 = vars(Config(directory=os.getcwd())) + for key, value in computed_settings.items(): + self.arguments[key] = value + + def distribution_files(self) -> Iterator[str]: + """Find distribution packages.""" + # This is verbatim from flake8 + if self.distribution.packages: + package_dirs = self.distribution.package_dir or {} + for package in self.distribution.packages: + pkg_dir = package + if package in package_dirs: + pkg_dir = package_dirs[package] + elif "" in package_dirs: + pkg_dir = package_dirs[""] + os.path.sep + pkg_dir + yield pkg_dir.replace(".", os.path.sep) + + if self.distribution.py_modules: + for filename in self.distribution.py_modules: + yield "%s.py" % filename + # Don't miss the setup.py file itself + yield "setup.py" + + def run(self) -> None: + arguments = self.arguments + wrong_sorted_files = False + arguments["check"] = True + for path in self.distribution_files(): + for python_file in glob.iglob(os.path.join(path, "*.py")): + try: + incorrectly_sorted = SortImports(python_file, **arguments).incorrectly_sorted + if incorrectly_sorted: + wrong_sorted_files = True + except OSError as error: + warn(f"Unable to parse file {python_file} due to {error}") + if wrong_sorted_files: + sys.exit(1) diff --git a/tests/test_main.py b/tests/test_main.py index 300108a0..f8447a37 100644 --- a/tests/test_main.py +++ b/tests/test_main.py @@ -19,3 +19,8 @@ def test_is_python_file_fifo(tmpdir): fifo_file = os.path.join(tmpdir, "fifo_file") os.mkfifo(fifo_file) assert not main.is_python_file(fifo_file) + + +def test_isort_command(): + """Ensure ISortCommand got registered, otherwise setuptools error must have occured""" + assert main.ISortCommand -- cgit v1.2.1