Skip to content

Commit

Permalink
PyImportSortBear: Add more configs
Browse files Browse the repository at this point in the history
Fixes #26
  • Loading branch information
AbdealiLoKo committed Apr 26, 2016
1 parent 1148090 commit 383cff5
Show file tree
Hide file tree
Showing 2 changed files with 157 additions and 20 deletions.
162 changes: 142 additions & 20 deletions bears/python/PyImportSortBear.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -27,28 +48,129 @@ def run(self,
You can read more about ``isort`` at
<https://isort.readthedocs.org/en/latest/>.
: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
<https://github.com/timothycrosley/isort#multi-line-output-modes>.
: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)
Expand Down
15 changes: 15 additions & 0 deletions tests/python/PyImportSortBearTest.py
Original file line number Diff line number Diff line change
Expand Up @@ -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"})

0 comments on commit 383cff5

Please sign in to comment.