Skip to content

Commit

Permalink
Fixed #1335: Official API for diff capturing
Browse files Browse the repository at this point in the history
  • Loading branch information
timothycrosley committed Jul 20, 2020
1 parent 04dda88 commit e2c48a1
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 12 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@ Changelog

NOTE: isort follows the [semver](https://semver.org/) versioning standard.

### 5.2.0 TBD
- Implemented #1335: Official API for diff capturing.

### 5.1.4 July 19, 2020
- Fixed issue #1333: Use of wrap_length raises an exception about it not being lower or equal to line_length.
- Fixed issue #1330: Ensure stdout can be stubbed dynamically for `show_unified_diff` function.
Expand Down
38 changes: 26 additions & 12 deletions isort/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
from io import StringIO
from itertools import chain
from pathlib import Path
from typing import List, Optional, TextIO, Union
from typing import List, Optional, TextIO, Union, cast
from warnings import warn

from . import io, output, parse
Expand Down Expand Up @@ -36,6 +36,7 @@ def sort_code_string(
config: Config = DEFAULT_CONFIG,
file_path: Optional[Path] = None,
disregard_skip: bool = False,
show_diff: Union[bool, TextIO] = False,
**config_kwargs,
):
"""Sorts any imports within the provided code string, returning a new string with them sorted.
Expand All @@ -45,6 +46,8 @@ def sort_code_string(
- **config**: The config object to use when sorting imports.
- **file_path**: The disk location where the code string was pulled from.
- **disregard_skip**: set to `True` if you want to ignore a skip set in config for this file.
- **show_diff**: If `True` the changes that need to be done will be printed to stdout, if a
TextIO stream is provided results will be written to it, otherwise no diff will be computed.
- ****config_kwargs**: Any config modifications.
"""
input_stream = StringIO(code)
Expand All @@ -57,14 +60,15 @@ def sort_code_string(
config=config,
file_path=file_path,
disregard_skip=disregard_skip,
show_diff=show_diff,
)
output_stream.seek(0)
return output_stream.read()


def check_code_string(
code: str,
show_diff: bool = False,
show_diff: Union[bool, TextIO] = False,
extension: Optional[str] = None,
config: Config = DEFAULT_CONFIG,
file_path: Optional[Path] = None,
Expand All @@ -75,7 +79,8 @@ def check_code_string(
Returns `True` if everything is correct, otherwise `False`.
- **code**: The string of code with imports that need to be sorted.
- **show_diff**: If `True` the changes that need to be done will be printed to stdout.
- **show_diff**: If `True` the changes that need to be done will be printed to stdout, if a
TextIO stream is provided results will be written to it, otherwise no diff will be computed.
- **extension**: The file extension that contains imports. Defaults to filename extension or py.
- **config**: The config object to use when sorting imports.
- **file_path**: The disk location where the code string was pulled from.
Expand All @@ -100,7 +105,7 @@ def sort_stream(
config: Config = DEFAULT_CONFIG,
file_path: Optional[Path] = None,
disregard_skip: bool = False,
show_diff: bool = False,
show_diff: Union[bool, TextIO] = False,
**config_kwargs,
):
"""Sorts any imports within the provided code stream, outputs to the provided output stream.
Expand All @@ -112,6 +117,8 @@ def sort_stream(
- **config**: The config object to use when sorting imports.
- **file_path**: The disk location where the code string was pulled from.
- **disregard_skip**: set to `True` if you want to ignore a skip set in config for this file.
- **show_diff**: If `True` the changes that need to be done will be printed to stdout, if a
TextIO stream is provided results will be written to it, otherwise no diff will be computed.
- ****config_kwargs**: Any config modifications.
"""
if show_diff:
Expand All @@ -132,7 +139,7 @@ def sort_stream(
file_input=_input_stream.read(),
file_output=_output_stream.read(),
file_path=file_path,
output=output_stream,
output=output_stream if show_diff is True else cast(TextIO, show_diff),
)
return changed

Expand Down Expand Up @@ -180,7 +187,7 @@ def sort_stream(

def check_stream(
input_stream: TextIO,
show_diff: bool = False,
show_diff: Union[bool, TextIO] = False,
extension: Optional[str] = None,
config: Config = DEFAULT_CONFIG,
file_path: Optional[Path] = None,
Expand All @@ -191,7 +198,8 @@ def check_stream(
incorrectly imports are found or `True` if no problems are identified.
- **input_stream**: The stream of code with imports that need to be sorted.
- **show_diff**: If `True` the changes that need to be done will be printed to stdout.
- **show_diff**: If `True` the changes that need to be done will be printed to stdout, if a
TextIO stream is provided results will be written to it, otherwise no diff will be computed.
- **extension**: The file extension that contains imports. Defaults to filename extension or py.
- **config**: The config object to use when sorting imports.
- **file_path**: The disk location where the code string was pulled from.
Expand Down Expand Up @@ -230,14 +238,17 @@ def check_stream(
output_stream.seek(0)

show_unified_diff(
file_input=file_contents, file_output=output_stream.read(), file_path=file_path
file_input=file_contents,
file_output=output_stream.read(),
file_path=file_path,
output=None if show_diff is True else cast(TextIO, show_diff),
)
return False


def check_file(
filename: Union[str, Path],
show_diff: bool = False,
show_diff: Union[bool, TextIO] = False,
config: Config = DEFAULT_CONFIG,
file_path: Optional[Path] = None,
disregard_skip: bool = True,
Expand All @@ -248,7 +259,8 @@ def check_file(
incorrectly imports are found or `True` if no problems are identified.
- **filename**: The name or Path of the file to check.
- **show_diff**: If `True` the changes that need to be done will be printed to stdout.
- **show_diff**: If `True` the changes that need to be done will be printed to stdout, if a
TextIO stream is provided results will be written to it, otherwise no diff will be computed.
- **config**: The config object to use when sorting imports.
- **file_path**: The disk location where the code string was pulled from.
- **disregard_skip**: set to `True` if you want to ignore a skip set in config for this file.
Expand All @@ -274,7 +286,7 @@ def sort_file(
file_path: Optional[Path] = None,
disregard_skip: bool = True,
ask_to_apply: bool = False,
show_diff: bool = False,
show_diff: Union[bool, TextIO] = False,
write_to_stdout: bool = False,
**config_kwargs,
):
Expand All @@ -286,7 +298,8 @@ def sort_file(
- **file_path**: The disk location where the code string was pulled from.
- **disregard_skip**: set to `True` if you want to ignore a skip set in config for this file.
- **ask_to_apply**: If `True`, prompt before applying any changes.
- **show_diff**: If `True` the changes that need to be done will be printed to stdout.
- **show_diff**: If `True` the changes that need to be done will be printed to stdout, if a
TextIO stream is provided results will be written to it, otherwise no diff will be computed.
- **write_to_stdout**: If `True`, write to stdout instead of the input file.
- ****config_kwargs**: Any config modifications.
"""
Expand Down Expand Up @@ -326,6 +339,7 @@ def sort_file(
file_input=source_file.stream.read(),
file_output=tmp_file.read_text(encoding=source_file.encoding),
file_path=file_path or source_file.path,
output=None if show_diff is True else cast(TextIO, show_diff),
)
if show_diff or (
ask_to_apply
Expand Down
12 changes: 12 additions & 0 deletions tests/test_ticketed_features.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
"""A growing set of tests designed to ensure when isort implements a feature described in a ticket
it fully works as defined in the associated ticket.
"""
from io import StringIO

import isort


Expand Down Expand Up @@ -149,3 +151,13 @@ def my_function_2():
pass
"""
)


def test_isort_provides_official_api_for_diff_output_issue_1335():
"""Test to ensure isort API for diff capturing allows capturing diff without sys.stdout.
See: https://github.com/timothycrosley/isort/issues/1335.
"""
diff_output = StringIO()
isort.code("import b\nimport a\n", show_diff=diff_output)
diff_output.seek(0)
assert "+import a" in diff_output.read()

0 comments on commit e2c48a1

Please sign in to comment.