Skip to content

Commit

Permalink
Merge pull request #92 from bnavigator/support-isort5
Browse files Browse the repository at this point in the history
Support isort5
  • Loading branch information
gforcada committed Aug 7, 2020
2 parents 6aa82a4 + 6b103a0 commit fee5f69
Show file tree
Hide file tree
Showing 6 changed files with 350 additions and 321 deletions.
32 changes: 22 additions & 10 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,20 +1,32 @@
dist: xenial
language: python
matrix:
- python: '2.7'
- python: '3.5'
- python: '3.6'
- python: '3.7'
- python: '3.8'
- python: 'pypy'
- python: 'pypy3'
python:
- '2.7'
- '3.5'
- '3.6'
- '3.7'
- '3.8'
- 'pypy'
- 'pypy3'
env:
- ISORT_VER="4"
- ISORT_VER="5"
jobs:
exclude:
- python: "2.7"
env: ISORT_VER="5"
- python: "3.5"
env: ISORT_VER="5"
- python: "pypy"
env: ISORT_VER="5"
cache: pip
install:
- if [[ $ISORT_VER == "4" ]]; then pip install 'isort < 5'; fi
- pip install .[test]
script:
- flake8 *.py
- pytest run_tests.py
- pytest -v
after_success:
- pip install -q -r requirements-cov.txt
- pytest run_tests.py --cov flake8_isort --cov-report term-missing
- pytest -v --cov flake8_isort --cov-report term-missing
- coveralls
4 changes: 2 additions & 2 deletions CHANGES.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@
Changelog
=========

3.0.2 (unreleased)
4.0.0 (unreleased)
------------------

- Nothing changed yet.
- support isort >= 5 [bnavigator, pkolbus]


3.0.1 (2020-07-08)
Expand Down
114 changes: 108 additions & 6 deletions flake8_isort.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,23 @@
# -*- coding: utf-8 -*-
from difflib import Differ
from isort import SortImports
from testfixtures import OutputCapture

import isort

__version__ = '3.0.2.dev0'

if hasattr(isort, 'api'): # isort 5
from contextlib import redirect_stdout
from difflib import unified_diff
from io import StringIO
from pathlib import Path

class Flake8Isort(object):
import warnings
else:
from difflib import Differ
from testfixtures import OutputCapture

__version__ = '4.0.0.dev0'


class Flake8IsortBase(object):
name = 'flake8_isort'
version = __version__
isort_unsorted = (
Expand Down Expand Up @@ -49,13 +59,17 @@ def parse_options(cls, options):
cls.stdin_display_name = options.stdin_display_name
cls.show_traceback = options.isort_show_traceback


class Flake8Isort4(Flake8IsortBase):
"""class for isort <5"""

def run(self):
if self.filename is not self.stdin_display_name:
file_path = self.filename
else:
file_path = None
with OutputCapture() as buffer:
sort_result = SortImports(
sort_result = isort.SortImports(
file_path=file_path,
file_contents=''.join(self.lines),
check=True,
Expand Down Expand Up @@ -168,3 +182,91 @@ def _fixup_sortimports_wrapped(sort_imports):
for new_idx, new_line in enumerate(
sort_imports.out_lines.pop(idx).splitlines()):
sort_imports.out_lines.insert(idx + new_idx, new_line)


class Flake8Isort5(Flake8IsortBase):
"""class for isort >=5"""

def run(self):
if self.filename is not self.stdin_display_name:
file_path = Path(self.filename)
isort_config = isort.settings.Config(
settings_path=file_path.parent)
else:
file_path = None
isort_config = isort.settings.Config(
settings_path=Path.cwd())
input_string = ''.join(self.lines)
traceback = ''
isort_changed = False
input_stream = StringIO(input_string)
output_stream = StringIO()
isort_stdout = StringIO()
try:
with redirect_stdout(isort_stdout):
isort_changed = isort.api.sort_stream(
input_stream=input_stream,
output_stream=output_stream,
config=isort_config,
file_path=file_path)
except isort.exceptions.FileSkipped:
pass
except isort.exceptions.ISortError as e:
warnings.warn(e)
if isort_changed:
outlines = output_stream.getvalue()
diff_delta = "".join(unified_diff(
input_string.splitlines(keepends=True),
outlines.splitlines(keepends=True),
fromfile="{}:before".format(self.filename),
tofile="{}:after".format(self.filename)))
traceback = (isort_stdout.getvalue() + "\n" + diff_delta)
for line_num, message in self.isort_linenum_msg(diff_delta):
if self.show_traceback:
message += traceback
yield line_num, 0, message, type(self)

def isort_linenum_msg(self, udiff):
"""Parse unified diff for changes and generate messages
Args
----
udiff : unified diff delta
Yields
------
tuple: A tuple of the specific isort line number and message.
"""
line_num = 0
additions = []
moves = []
for line in udiff.splitlines():
if line.startswith('@@', 0, 2):
line_num = int(line[4:].split(' ')[0].split(',')[0])
continue
elif not line_num: # skip lines before first hunk
continue
if line.startswith(' ', 0, 1):
line_num += 1 # Ignore unchanged lines but increment line_num.
elif line.startswith('-', 0, 1):
if line.strip() == '-':
yield line_num, self.isort_blank_unexp
line_num += 1
else:
moves.append(line[1:])
yield line_num, self.isort_unsorted
line_num += 1
elif line.startswith('+', 0, 1):
if line.strip() == '+':
# Include newline additions but do not increment line_num.
yield line_num, self.isort_blank_req
else:
additions.append((line_num, line))

# return all additions that did not move
for line_num, line in additions:
if not line[1:] in moves:
yield line_num, self.isort_add_unexp


Flake8Isort = Flake8Isort5 if hasattr(isort, 'api') else Flake8Isort4
Loading

0 comments on commit fee5f69

Please sign in to comment.