diff --git a/bears/python/PyImportSortBear.py b/bears/python/PyImportSortBear.py
index 158543a371..6903996a34 100644
--- a/bears/python/PyImportSortBear.py
+++ b/bears/python/PyImportSortBear.py
@@ -4,21 +4,42 @@
from coalib.bears.LocalBear import LocalBear
from coalib.results.Diff import Diff
from coalib.results.Result import Result
+from coalib.settings.Setting import typed_list
class PyImportSortBear(LocalBear):
LANGUAGES = ("Python",)
- def run(self,
- filename,
- file,
+ def run(self, filename, file,
+ use_parentheses_in_import: bool=True,
+ force_alphabetical_sort_in_import: bool=False,
+ force_sort_within_import_sections: bool=True,
+ from_first_in_import: bool=False,
+ include_trailing_comma_in_import: bool=False,
+ combine_star_imports: bool=True,
+ combine_as_imports: bool=True,
+ lines_after_imports: int=-1,
+ order_imports_by_type: bool=False,
+ balanced_wrapping_in_imports: bool=False,
+ import_heading_localfolder: str="",
+ import_heading_firstparty: str="",
+ import_heading_thirdparty: str="",
+ import_heading_stdlib: str="",
+ import_heading_future: str="",
+ default_import_section: str="FIRSTPARTY",
+ force_grid_wrap_imports: bool=False,
+ force_single_line_imports: bool=True,
+ sort_imports_by_length: bool=False,
use_spaces: bool=True,
tab_width: int=SpacingHelper.DEFAULT_TAB_WIDTH,
+ forced_separate_imports: typed_list(str)=(),
+ isort_multi_line_output: int=4,
+ known_first_party_imports: typed_list(str)=(),
+ known_third_party_imports: typed_list(str)=(),
+ known_standard_library_imports: typed_list(str)=None,
max_line_length: int=80,
- use_parentheses_in_import: bool=True,
- sort_imports_by_length: bool=False,
- isort_multi_line_output: int=4):
+ imports_forced_to_top: typed_list(str)=()):
"""
Handle imports for python using the utility ``isort``. It can sort the
imports, segregate it into various sections, and also add comments
@@ -27,28 +48,129 @@ def run(self,
You can read more about ``isort`` at
.
+ :param use_parentheses_in_import:
+ True if parenthesis are to be used in import statements.
+ :param force_alphabetical_sort_in_import:
+ If set, forces all imports to be sorted as a single section,
+ instead of within other groups (such as straight vs from).
+ :param force_sort_within_import_sections:
+ If set, imports will be sorted within there section independent
+ to the import_type.
+ :param from_first_in_import:
+ If set, imports using "from" will be displayed above normal
+ (straight) imports.
+ :param include_trailing_comma_in_import:
+ If set, will automatically add a trailing comma to the end of
+ "from" imports. Example: ``from abc import (a, b, c,)``
+ :param combine_star_imports:
+ If set to true - ensures that if a star import is present,
+ nothing else is imported from that namespace.
+ :param combine_as_imports:
+ If set to true - isort will combine as imports on the same line
+ within for import statements.
+ :param lines_after_imports:
+ Forces a certain number of lines after the imports and before the
+ first line of functional code. By default this is set to -1 which
+ uses 2 lines if the first line of code is a class or function and
+ 1 line if it's anything else.
+ :param order_imports_by_type:
+ If set to true - isort will create separate sections within "from"
+ imports for CONSTANTS, Classes, and modules/functions.
+ :param balanced_wrapping_in_imports:
+ If set to true - for each multi-line import statement isort will
+ dynamically change the import length to the one that produces
+ the most balanced grid, while staying below the maximum import
+ length defined.
+ :param import_heading_localfolder:
+ A comment to consistently place directly above imports that
+ start with '.'.
+ :param import_heading_firstparty:
+ A comment to consistently place directly above imports from
+ the current project.
+ :param import_heading_thirdparty:
+ A comment to consistently place directly above thirdparty imports.
+ :param import_heading_stdlib:
+ A comment to consistently place directly above imports from
+ the standard library.
+ :param import_heading_future:
+ A comment to consistently place directly above future imports.
+ :param default_import_section:
+ The default section to place imports in, if their section can
+ not be automatically determined.
+ :param force_grid_wrap_imports:
+ Force "from" imports to be grid wrapped regardless of line length.
+ :param force_single_line_imports:
+ If set to true - instead of wrapping multi-line from style imports,
+ each import will be forced to display on its own line.
+ :param sort_imports_by_length:
+ Set to true to sort imports by length instead of alphabetically.
:param use_spaces:
True if spaces are to be used instead of tabs.
:param tab_width:
Number of spaces per indent level.
+ :param forced_separate_imports:
+ A list of modules that you want to appear in their own separate
+ section.
+ :param isort_multi_line_output:
+ An integer that represents how you want imports to be displayed
+ by ``isort`` if they're long enough to span multiple lines.
+ This value is passed to isort as the ``multi_line_output`` setting.
+ Possible values are (0-grid, 1-vertical, 2-hanging, 3-vert-hanging,
+ 4-vert-grid, 5-vert-grid-grouped)
+ A full definition of all possible modes can be found at
+ .
+ :param known_first_party_imports:
+ A list of imports that will be forced to display within the
+ standard library category of imports.
+ :param known_third_party_imports:
+ A list of imports that will be forced to display within the
+ third party category of imports.
+ :param known_standard_library_imports:
+ A list of imports that will be forced to display within the
+ first party category of imports.
+ :param import_wrap_length:
+ An integer that represents the longest line-length you want when
+ wrapping. If not set will default to line_length.
+ :param imports_forced_to_top:
+ Forces a list of imports to the top of their respective section.
+ This works well for handling the unfortunate cases of import
+ dependencies that occur in many projects.
:param max_line_length:
Maximum number of characters for a line.
- :param use_parentheses_in_import:
- True if parenthesis are to be used in import statements.
- :param sort_imports_by_length:
- Set to true to sort imports by length instead of alphabetically.
- :param isort_multi_line_output:
- The type of formatting to be used by isort when indenting imports.
- This value if passed to isort as the `multi_line_output` setting.
"""
- indent = "Tab" if use_spaces == False else tab_width
- new_file = tuple(SortImports(
- file_contents=''.join(file),
- line_length=max_line_length,
- indent=indent,
- multi_line_output=isort_multi_line_output,
+ isort_settings = dict(
use_parentheses=use_parentheses_in_import,
- length_sort=sort_imports_by_length).output.splitlines(True))
+ force_alphabetical_sort=force_alphabetical_sort_in_import,
+ force_sort_within_sections=force_sort_within_import_sections,
+ from_first=from_first_in_import,
+ include_trailing_comma=include_trailing_comma_in_import,
+ combine_star=combine_star_imports,
+ lines_after_imports=lines_after_imports,
+ order_by_type=order_imports_by_type,
+ balanced_wrapping=balanced_wrapping_in_imports,
+ import_heading_localfolder=import_heading_localfolder,
+ import_heading_firstparty=import_heading_firstparty,
+ import_heading_thirdparty=import_heading_thirdparty,
+ import_heading_stdlib=import_heading_stdlib,
+ import_heading_future=import_heading_future,
+ default_section=default_import_section,
+ force_grid_wrap=force_grid_wrap_imports,
+ force_single_line=force_single_line_imports,
+ length_sort=sort_imports_by_length,
+ indent="Tab" if use_spaces == False else tab_width,
+ forced_separate=forced_separate_imports,
+ multi_line_output=isort_multi_line_output,
+ known_first_party=known_first_party_imports,
+ line_length=max_line_length,
+ force_to_top=imports_forced_to_top)
+
+ if known_standard_library_imports is not None:
+ isort_settings["known_standard_library"] = (
+ known_standard_library_imports)
+
+ sort_imports = SortImports(file_contents=''.join(file),
+ **isort_settings)
+ new_file = tuple(sort_imports.output.splitlines(True))
if new_file != tuple(file):
diff = Diff.from_string_arrays(file, new_file)
diff --git a/tests/python/PyImportSortBearTest.py b/tests/python/PyImportSortBearTest.py
index 0ffeec67f4..a44b7eab86 100644
--- a/tests/python/PyImportSortBearTest.py
+++ b/tests/python/PyImportSortBearTest.py
@@ -6,3 +6,18 @@
("import os\n", "import sys\n")),
(["import sys\n", "import os\n"],
("import sys\n", "import os\n")))
+
+PyImportSortBearConfigsTest = verify_local_bear(
+ PyImportSortBear,
+ (("from os import read\n", "from sys import *\n"),),
+ (("from os import read\n", "from os import *\n"),),
+ settings={"combine_star_imports": True})
+
+PyImportSortBearIgnoredConfigsTest = verify_local_bear(
+ PyImportSortBear,
+ (("import xyz\n", "\n", "import abc\n"),
+ ("from xyz import *\n", "\n", "import abc\n")),
+ (("import xyz\n", "import abc\n"),
+ ("import abc\n", "import xyz\n")),
+ settings={"known_standard_library_imports": "xyz",
+ "known_first_party_imports": "abc"})