parent
c7bc22388d
commit
07b1b2f3dd
162
black.py
162
black.py
@ -159,6 +159,19 @@ class Changed(Enum):
|
|||||||
"silence those with 2>/dev/null."
|
"silence those with 2>/dev/null."
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
@click.option(
|
||||||
|
"--pyi",
|
||||||
|
is_flag=True,
|
||||||
|
help="Force pyi (stub file) formatting, regardless of file extension.",
|
||||||
|
)
|
||||||
|
@click.option(
|
||||||
|
"--py36",
|
||||||
|
is_flag=True,
|
||||||
|
help=(
|
||||||
|
"Force Python 3.6 mode, even if file doesn't currently use "
|
||||||
|
"Python 3.6-only syntax."
|
||||||
|
),
|
||||||
|
)
|
||||||
@click.version_option(version=__version__)
|
@click.version_option(version=__version__)
|
||||||
@click.argument(
|
@click.argument(
|
||||||
"src",
|
"src",
|
||||||
@ -174,6 +187,8 @@ def main(
|
|||||||
check: bool,
|
check: bool,
|
||||||
diff: bool,
|
diff: bool,
|
||||||
fast: bool,
|
fast: bool,
|
||||||
|
pyi: bool,
|
||||||
|
py36: bool,
|
||||||
quiet: bool,
|
quiet: bool,
|
||||||
src: List[str],
|
src: List[str],
|
||||||
) -> None:
|
) -> None:
|
||||||
@ -204,14 +219,30 @@ def main(
|
|||||||
return
|
return
|
||||||
|
|
||||||
elif len(sources) == 1:
|
elif len(sources) == 1:
|
||||||
reformat_one(sources[0], line_length, fast, write_back, report)
|
reformat_one(
|
||||||
|
src=sources[0],
|
||||||
|
line_length=line_length,
|
||||||
|
fast=fast,
|
||||||
|
pyi=pyi,
|
||||||
|
py36=py36,
|
||||||
|
write_back=write_back,
|
||||||
|
report=report,
|
||||||
|
)
|
||||||
else:
|
else:
|
||||||
loop = asyncio.get_event_loop()
|
loop = asyncio.get_event_loop()
|
||||||
executor = ProcessPoolExecutor(max_workers=os.cpu_count())
|
executor = ProcessPoolExecutor(max_workers=os.cpu_count())
|
||||||
try:
|
try:
|
||||||
loop.run_until_complete(
|
loop.run_until_complete(
|
||||||
schedule_formatting(
|
schedule_formatting(
|
||||||
sources, line_length, fast, write_back, report, loop, executor
|
sources=sources,
|
||||||
|
line_length=line_length,
|
||||||
|
fast=fast,
|
||||||
|
pyi=pyi,
|
||||||
|
py36=py36,
|
||||||
|
write_back=write_back,
|
||||||
|
report=report,
|
||||||
|
loop=loop,
|
||||||
|
executor=executor,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
finally:
|
finally:
|
||||||
@ -223,33 +254,49 @@ def main(
|
|||||||
|
|
||||||
|
|
||||||
def reformat_one(
|
def reformat_one(
|
||||||
src: Path, line_length: int, fast: bool, write_back: WriteBack, report: "Report"
|
src: Path,
|
||||||
|
line_length: int,
|
||||||
|
fast: bool,
|
||||||
|
pyi: bool,
|
||||||
|
py36: bool,
|
||||||
|
write_back: WriteBack,
|
||||||
|
report: "Report",
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Reformat a single file under `src` without spawning child processes.
|
"""Reformat a single file under `src` without spawning child processes.
|
||||||
|
|
||||||
If `quiet` is True, non-error messages are not output. `line_length`,
|
If `quiet` is True, non-error messages are not output. `line_length`,
|
||||||
`write_back`, and `fast` options are passed to :func:`format_file_in_place`.
|
`write_back`, `fast` and `pyi` options are passed to
|
||||||
|
:func:`format_file_in_place` or :func:`format_stdin_to_stdout`.
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
changed = Changed.NO
|
changed = Changed.NO
|
||||||
if not src.is_file() and str(src) == "-":
|
if not src.is_file() and str(src) == "-":
|
||||||
if format_stdin_to_stdout(
|
if format_stdin_to_stdout(
|
||||||
line_length=line_length, fast=fast, write_back=write_back
|
line_length=line_length,
|
||||||
|
fast=fast,
|
||||||
|
is_pyi=pyi,
|
||||||
|
force_py36=py36,
|
||||||
|
write_back=write_back,
|
||||||
):
|
):
|
||||||
changed = Changed.YES
|
changed = Changed.YES
|
||||||
else:
|
else:
|
||||||
cache: Cache = {}
|
cache: Cache = {}
|
||||||
if write_back != WriteBack.DIFF:
|
if write_back != WriteBack.DIFF:
|
||||||
cache = read_cache(line_length)
|
cache = read_cache(line_length, pyi, py36)
|
||||||
src = src.resolve()
|
src = src.resolve()
|
||||||
if src in cache and cache[src] == get_cache_info(src):
|
if src in cache and cache[src] == get_cache_info(src):
|
||||||
changed = Changed.CACHED
|
changed = Changed.CACHED
|
||||||
if changed is not Changed.CACHED and format_file_in_place(
|
if changed is not Changed.CACHED and format_file_in_place(
|
||||||
src, line_length=line_length, fast=fast, write_back=write_back
|
src,
|
||||||
|
line_length=line_length,
|
||||||
|
fast=fast,
|
||||||
|
force_pyi=pyi,
|
||||||
|
force_py36=py36,
|
||||||
|
write_back=write_back,
|
||||||
):
|
):
|
||||||
changed = Changed.YES
|
changed = Changed.YES
|
||||||
if write_back == WriteBack.YES and changed is not Changed.NO:
|
if write_back == WriteBack.YES and changed is not Changed.NO:
|
||||||
write_cache(cache, [src], line_length)
|
write_cache(cache, [src], line_length, pyi, py36)
|
||||||
report.done(src, changed)
|
report.done(src, changed)
|
||||||
except Exception as exc:
|
except Exception as exc:
|
||||||
report.failed(src, str(exc))
|
report.failed(src, str(exc))
|
||||||
@ -259,6 +306,8 @@ async def schedule_formatting(
|
|||||||
sources: List[Path],
|
sources: List[Path],
|
||||||
line_length: int,
|
line_length: int,
|
||||||
fast: bool,
|
fast: bool,
|
||||||
|
pyi: bool,
|
||||||
|
py36: bool,
|
||||||
write_back: WriteBack,
|
write_back: WriteBack,
|
||||||
report: "Report",
|
report: "Report",
|
||||||
loop: BaseEventLoop,
|
loop: BaseEventLoop,
|
||||||
@ -268,12 +317,12 @@ async def schedule_formatting(
|
|||||||
|
|
||||||
(Use ProcessPoolExecutors for actual parallelism.)
|
(Use ProcessPoolExecutors for actual parallelism.)
|
||||||
|
|
||||||
`line_length`, `write_back`, and `fast` options are passed to
|
`line_length`, `write_back`, `fast`, and `pyi` options are passed to
|
||||||
:func:`format_file_in_place`.
|
:func:`format_file_in_place`.
|
||||||
"""
|
"""
|
||||||
cache: Cache = {}
|
cache: Cache = {}
|
||||||
if write_back != WriteBack.DIFF:
|
if write_back != WriteBack.DIFF:
|
||||||
cache = read_cache(line_length)
|
cache = read_cache(line_length, pyi, py36)
|
||||||
sources, cached = filter_cached(cache, sources)
|
sources, cached = filter_cached(cache, sources)
|
||||||
for src in cached:
|
for src in cached:
|
||||||
report.done(src, Changed.CACHED)
|
report.done(src, Changed.CACHED)
|
||||||
@ -288,7 +337,15 @@ async def schedule_formatting(
|
|||||||
lock = manager.Lock()
|
lock = manager.Lock()
|
||||||
tasks = {
|
tasks = {
|
||||||
loop.run_in_executor(
|
loop.run_in_executor(
|
||||||
executor, format_file_in_place, src, line_length, fast, write_back, lock
|
executor,
|
||||||
|
format_file_in_place,
|
||||||
|
src,
|
||||||
|
line_length,
|
||||||
|
fast,
|
||||||
|
pyi,
|
||||||
|
py36,
|
||||||
|
write_back,
|
||||||
|
lock,
|
||||||
): src
|
): src
|
||||||
for src in sorted(sources)
|
for src in sorted(sources)
|
||||||
}
|
}
|
||||||
@ -313,13 +370,15 @@ async def schedule_formatting(
|
|||||||
if cancelled:
|
if cancelled:
|
||||||
await asyncio.gather(*cancelled, loop=loop, return_exceptions=True)
|
await asyncio.gather(*cancelled, loop=loop, return_exceptions=True)
|
||||||
if write_back == WriteBack.YES and formatted:
|
if write_back == WriteBack.YES and formatted:
|
||||||
write_cache(cache, formatted, line_length)
|
write_cache(cache, formatted, line_length, pyi, py36)
|
||||||
|
|
||||||
|
|
||||||
def format_file_in_place(
|
def format_file_in_place(
|
||||||
src: Path,
|
src: Path,
|
||||||
line_length: int,
|
line_length: int,
|
||||||
fast: bool,
|
fast: bool,
|
||||||
|
force_pyi: bool = False,
|
||||||
|
force_py36: bool = False,
|
||||||
write_back: WriteBack = WriteBack.NO,
|
write_back: WriteBack = WriteBack.NO,
|
||||||
lock: Any = None, # multiprocessing.Manager().Lock() is some crazy proxy
|
lock: Any = None, # multiprocessing.Manager().Lock() is some crazy proxy
|
||||||
) -> bool:
|
) -> bool:
|
||||||
@ -328,13 +387,17 @@ def format_file_in_place(
|
|||||||
If `write_back` is True, write reformatted code back to stdout.
|
If `write_back` is True, write reformatted code back to stdout.
|
||||||
`line_length` and `fast` options are passed to :func:`format_file_contents`.
|
`line_length` and `fast` options are passed to :func:`format_file_contents`.
|
||||||
"""
|
"""
|
||||||
is_pyi = src.suffix == ".pyi"
|
is_pyi = force_pyi or src.suffix == ".pyi"
|
||||||
|
|
||||||
with tokenize.open(src) as src_buffer:
|
with tokenize.open(src) as src_buffer:
|
||||||
src_contents = src_buffer.read()
|
src_contents = src_buffer.read()
|
||||||
try:
|
try:
|
||||||
dst_contents = format_file_contents(
|
dst_contents = format_file_contents(
|
||||||
src_contents, line_length=line_length, fast=fast, is_pyi=is_pyi
|
src_contents,
|
||||||
|
line_length=line_length,
|
||||||
|
fast=fast,
|
||||||
|
is_pyi=is_pyi,
|
||||||
|
force_py36=force_py36,
|
||||||
)
|
)
|
||||||
except NothingChanged:
|
except NothingChanged:
|
||||||
return False
|
return False
|
||||||
@ -357,17 +420,28 @@ def format_file_in_place(
|
|||||||
|
|
||||||
|
|
||||||
def format_stdin_to_stdout(
|
def format_stdin_to_stdout(
|
||||||
line_length: int, fast: bool, write_back: WriteBack = WriteBack.NO
|
line_length: int,
|
||||||
|
fast: bool,
|
||||||
|
is_pyi: bool = False,
|
||||||
|
force_py36: bool = False,
|
||||||
|
write_back: WriteBack = WriteBack.NO,
|
||||||
) -> bool:
|
) -> bool:
|
||||||
"""Format file on stdin. Return True if changed.
|
"""Format file on stdin. Return True if changed.
|
||||||
|
|
||||||
If `write_back` is True, write reformatted code back to stdout.
|
If `write_back` is True, write reformatted code back to stdout.
|
||||||
`line_length` and `fast` arguments are passed to :func:`format_file_contents`.
|
`line_length`, `fast`, `is_pyi`, and `force_py36` arguments are passed to
|
||||||
|
:func:`format_file_contents`.
|
||||||
"""
|
"""
|
||||||
src = sys.stdin.read()
|
src = sys.stdin.read()
|
||||||
dst = src
|
dst = src
|
||||||
try:
|
try:
|
||||||
dst = format_file_contents(src, line_length=line_length, fast=fast)
|
dst = format_file_contents(
|
||||||
|
src,
|
||||||
|
line_length=line_length,
|
||||||
|
fast=fast,
|
||||||
|
is_pyi=is_pyi,
|
||||||
|
force_py36=force_py36,
|
||||||
|
)
|
||||||
return True
|
return True
|
||||||
|
|
||||||
except NothingChanged:
|
except NothingChanged:
|
||||||
@ -383,7 +457,12 @@ def format_stdin_to_stdout(
|
|||||||
|
|
||||||
|
|
||||||
def format_file_contents(
|
def format_file_contents(
|
||||||
src_contents: str, *, line_length: int, fast: bool, is_pyi: bool = False
|
src_contents: str,
|
||||||
|
*,
|
||||||
|
line_length: int,
|
||||||
|
fast: bool,
|
||||||
|
is_pyi: bool = False,
|
||||||
|
force_py36: bool = False,
|
||||||
) -> FileContent:
|
) -> FileContent:
|
||||||
"""Reformat contents a file and return new contents.
|
"""Reformat contents a file and return new contents.
|
||||||
|
|
||||||
@ -394,20 +473,30 @@ def format_file_contents(
|
|||||||
if src_contents.strip() == "":
|
if src_contents.strip() == "":
|
||||||
raise NothingChanged
|
raise NothingChanged
|
||||||
|
|
||||||
dst_contents = format_str(src_contents, line_length=line_length, is_pyi=is_pyi)
|
dst_contents = format_str(
|
||||||
|
src_contents, line_length=line_length, is_pyi=is_pyi, force_py36=force_py36
|
||||||
|
)
|
||||||
if src_contents == dst_contents:
|
if src_contents == dst_contents:
|
||||||
raise NothingChanged
|
raise NothingChanged
|
||||||
|
|
||||||
if not fast:
|
if not fast:
|
||||||
assert_equivalent(src_contents, dst_contents)
|
assert_equivalent(src_contents, dst_contents)
|
||||||
assert_stable(
|
assert_stable(
|
||||||
src_contents, dst_contents, line_length=line_length, is_pyi=is_pyi
|
src_contents,
|
||||||
|
dst_contents,
|
||||||
|
line_length=line_length,
|
||||||
|
is_pyi=is_pyi,
|
||||||
|
force_py36=force_py36,
|
||||||
)
|
)
|
||||||
return dst_contents
|
return dst_contents
|
||||||
|
|
||||||
|
|
||||||
def format_str(
|
def format_str(
|
||||||
src_contents: str, line_length: int, *, is_pyi: bool = False
|
src_contents: str,
|
||||||
|
line_length: int,
|
||||||
|
*,
|
||||||
|
is_pyi: bool = False,
|
||||||
|
force_py36: bool = False,
|
||||||
) -> FileContent:
|
) -> FileContent:
|
||||||
"""Reformat a string and return new contents.
|
"""Reformat a string and return new contents.
|
||||||
|
|
||||||
@ -417,7 +506,7 @@ def format_str(
|
|||||||
dst_contents = ""
|
dst_contents = ""
|
||||||
future_imports = get_future_imports(src_node)
|
future_imports = get_future_imports(src_node)
|
||||||
elt = EmptyLineTracker(is_pyi=is_pyi)
|
elt = EmptyLineTracker(is_pyi=is_pyi)
|
||||||
py36 = is_python36(src_node)
|
py36 = force_py36 or is_python36(src_node)
|
||||||
lines = LineGenerator(
|
lines = LineGenerator(
|
||||||
remove_u_prefix=py36 or "unicode_literals" in future_imports, is_pyi=is_pyi
|
remove_u_prefix=py36 or "unicode_literals" in future_imports, is_pyi=is_pyi
|
||||||
)
|
)
|
||||||
@ -2836,9 +2925,13 @@ def _v(node: ast.AST, depth: int = 0) -> Iterator[str]:
|
|||||||
) from None
|
) from None
|
||||||
|
|
||||||
|
|
||||||
def assert_stable(src: str, dst: str, line_length: int, is_pyi: bool = False) -> None:
|
def assert_stable(
|
||||||
|
src: str, dst: str, line_length: int, is_pyi: bool = False, force_py36: bool = False
|
||||||
|
) -> None:
|
||||||
"""Raise AssertionError if `dst` reformats differently the second time."""
|
"""Raise AssertionError if `dst` reformats differently the second time."""
|
||||||
newdst = format_str(dst, line_length=line_length, is_pyi=is_pyi)
|
newdst = format_str(
|
||||||
|
dst, line_length=line_length, is_pyi=is_pyi, force_py36=force_py36
|
||||||
|
)
|
||||||
if dst != newdst:
|
if dst != newdst:
|
||||||
log = dump_to_file(
|
log = dump_to_file(
|
||||||
diff(src, dst, "source", "first pass"),
|
diff(src, dst, "source", "first pass"),
|
||||||
@ -3049,16 +3142,19 @@ def can_omit_invisible_parens(line: Line, line_length: int) -> bool:
|
|||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
def get_cache_file(line_length: int) -> Path:
|
def get_cache_file(line_length: int, pyi: bool = False, py36: bool = False) -> Path:
|
||||||
return CACHE_DIR / f"cache.{line_length}.pickle"
|
return (
|
||||||
|
CACHE_DIR
|
||||||
|
/ f"cache.{line_length}{'.pyi' if pyi else ''}{'.py36' if py36 else ''}.pickle"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def read_cache(line_length: int) -> Cache:
|
def read_cache(line_length: int, pyi: bool = False, py36: bool = False) -> Cache:
|
||||||
"""Read the cache if it exists and is well formed.
|
"""Read the cache if it exists and is well formed.
|
||||||
|
|
||||||
If it is not well formed, the call to write_cache later should resolve the issue.
|
If it is not well formed, the call to write_cache later should resolve the issue.
|
||||||
"""
|
"""
|
||||||
cache_file = get_cache_file(line_length)
|
cache_file = get_cache_file(line_length, pyi, py36)
|
||||||
if not cache_file.exists():
|
if not cache_file.exists():
|
||||||
return {}
|
return {}
|
||||||
|
|
||||||
@ -3095,9 +3191,15 @@ def filter_cached(
|
|||||||
return todo, done
|
return todo, done
|
||||||
|
|
||||||
|
|
||||||
def write_cache(cache: Cache, sources: List[Path], line_length: int) -> None:
|
def write_cache(
|
||||||
|
cache: Cache,
|
||||||
|
sources: List[Path],
|
||||||
|
line_length: int,
|
||||||
|
pyi: bool = False,
|
||||||
|
py36: bool = False,
|
||||||
|
) -> None:
|
||||||
"""Update the cache file."""
|
"""Update the cache file."""
|
||||||
cache_file = get_cache_file(line_length)
|
cache_file = get_cache_file(line_length, pyi, py36)
|
||||||
try:
|
try:
|
||||||
if not CACHE_DIR.exists():
|
if not CACHE_DIR.exists():
|
||||||
CACHE_DIR.mkdir(parents=True)
|
CACHE_DIR.mkdir(parents=True)
|
||||||
|
16
tests/force_py36.py
Normal file
16
tests/force_py36.py
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
# The input source must not contain any Py36-specific syntax (e.g. argument type
|
||||||
|
# annotations, trailing comma after *rest) or this test becomes invalid.
|
||||||
|
def long_function_name(argument_one, argument_two, argument_three, argument_four, argument_five, argument_six, *rest): ...
|
||||||
|
# output
|
||||||
|
# The input source must not contain any Py36-specific syntax (e.g. argument type
|
||||||
|
# annotations, trailing comma after *rest) or this test becomes invalid.
|
||||||
|
def long_function_name(
|
||||||
|
argument_one,
|
||||||
|
argument_two,
|
||||||
|
argument_three,
|
||||||
|
argument_four,
|
||||||
|
argument_five,
|
||||||
|
argument_six,
|
||||||
|
*rest,
|
||||||
|
):
|
||||||
|
...
|
6
tests/force_pyi.py
Normal file
6
tests/force_pyi.py
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
def f(): ...
|
||||||
|
|
||||||
|
def g(): ...
|
||||||
|
# output
|
||||||
|
def f(): ...
|
||||||
|
def g(): ...
|
@ -678,6 +678,7 @@ def test_write_cache_write_fail(self) -> None:
|
|||||||
mock.side_effect = OSError
|
mock.side_effect = OSError
|
||||||
black.write_cache({}, [], black.DEFAULT_LINE_LENGTH)
|
black.write_cache({}, [], black.DEFAULT_LINE_LENGTH)
|
||||||
|
|
||||||
|
@event_loop(close=False)
|
||||||
def test_check_diff_use_together(self) -> None:
|
def test_check_diff_use_together(self) -> None:
|
||||||
with cache_dir():
|
with cache_dir():
|
||||||
# Files which will be reformatted.
|
# Files which will be reformatted.
|
||||||
@ -694,7 +695,7 @@ def test_check_diff_use_together(self) -> None:
|
|||||||
result = CliRunner().invoke(
|
result = CliRunner().invoke(
|
||||||
black.main, [str(src1), str(src2), "--diff", "--check"]
|
black.main, [str(src1), str(src2), "--diff", "--check"]
|
||||||
)
|
)
|
||||||
self.assertEqual(result.exit_code, 1)
|
self.assertEqual(result.exit_code, 1, result.output)
|
||||||
|
|
||||||
def test_no_files(self) -> None:
|
def test_no_files(self) -> None:
|
||||||
with cache_dir():
|
with cache_dir():
|
||||||
@ -719,6 +720,104 @@ def test_read_cache_line_lengths(self) -> None:
|
|||||||
two = black.read_cache(2)
|
two = black.read_cache(2)
|
||||||
self.assertNotIn(path, two)
|
self.assertNotIn(path, two)
|
||||||
|
|
||||||
|
def test_single_file_force_pyi(self) -> None:
|
||||||
|
contents, expected = read_data("force_pyi")
|
||||||
|
with cache_dir() as workspace:
|
||||||
|
path = (workspace / "file.py").resolve()
|
||||||
|
with open(path, "w") as fh:
|
||||||
|
fh.write(contents)
|
||||||
|
result = CliRunner().invoke(black.main, [str(path), "--pyi"])
|
||||||
|
self.assertEqual(result.exit_code, 0)
|
||||||
|
with open(path, "r") as fh:
|
||||||
|
actual = fh.read()
|
||||||
|
# verify cache with --pyi is separate
|
||||||
|
pyi_cache = black.read_cache(black.DEFAULT_LINE_LENGTH, pyi=True)
|
||||||
|
self.assertIn(path, pyi_cache)
|
||||||
|
normal_cache = black.read_cache(black.DEFAULT_LINE_LENGTH)
|
||||||
|
self.assertNotIn(path, normal_cache)
|
||||||
|
self.assertEqual(actual, expected)
|
||||||
|
|
||||||
|
@event_loop(close=False)
|
||||||
|
def test_multi_file_force_pyi(self) -> None:
|
||||||
|
contents, expected = read_data("force_pyi")
|
||||||
|
with cache_dir() as workspace:
|
||||||
|
paths = [
|
||||||
|
(workspace / "file1.py").resolve(),
|
||||||
|
(workspace / "file2.py").resolve(),
|
||||||
|
]
|
||||||
|
for path in paths:
|
||||||
|
with open(path, "w") as fh:
|
||||||
|
fh.write(contents)
|
||||||
|
result = CliRunner().invoke(black.main, [str(p) for p in paths] + ["--pyi"])
|
||||||
|
self.assertEqual(result.exit_code, 0)
|
||||||
|
for path in paths:
|
||||||
|
with open(path, "r") as fh:
|
||||||
|
actual = fh.read()
|
||||||
|
self.assertEqual(actual, expected)
|
||||||
|
# verify cache with --pyi is separate
|
||||||
|
pyi_cache = black.read_cache(black.DEFAULT_LINE_LENGTH, pyi=True)
|
||||||
|
normal_cache = black.read_cache(black.DEFAULT_LINE_LENGTH)
|
||||||
|
for path in paths:
|
||||||
|
self.assertIn(path, pyi_cache)
|
||||||
|
self.assertNotIn(path, normal_cache)
|
||||||
|
|
||||||
|
def test_pipe_force_pyi(self) -> None:
|
||||||
|
source, expected = read_data("force_pyi")
|
||||||
|
result = CliRunner().invoke(black.main, ["-", "-q", "--pyi"], input=source)
|
||||||
|
self.assertEqual(result.exit_code, 0)
|
||||||
|
actual = result.output
|
||||||
|
self.assertFormatEqual(actual, expected)
|
||||||
|
|
||||||
|
def test_single_file_force_py36(self) -> None:
|
||||||
|
source, expected = read_data("force_py36")
|
||||||
|
with cache_dir() as workspace:
|
||||||
|
path = (workspace / "file.py").resolve()
|
||||||
|
with open(path, "w") as fh:
|
||||||
|
fh.write(source)
|
||||||
|
result = CliRunner().invoke(black.main, [str(path), "--py36"])
|
||||||
|
self.assertEqual(result.exit_code, 0)
|
||||||
|
with open(path, "r") as fh:
|
||||||
|
actual = fh.read()
|
||||||
|
# verify cache with --py36 is separate
|
||||||
|
py36_cache = black.read_cache(black.DEFAULT_LINE_LENGTH, py36=True)
|
||||||
|
self.assertIn(path, py36_cache)
|
||||||
|
normal_cache = black.read_cache(black.DEFAULT_LINE_LENGTH)
|
||||||
|
self.assertNotIn(path, normal_cache)
|
||||||
|
self.assertEqual(actual, expected)
|
||||||
|
|
||||||
|
@event_loop(close=False)
|
||||||
|
def test_multi_file_force_py36(self) -> None:
|
||||||
|
source, expected = read_data("force_py36")
|
||||||
|
with cache_dir() as workspace:
|
||||||
|
paths = [
|
||||||
|
(workspace / "file1.py").resolve(),
|
||||||
|
(workspace / "file2.py").resolve(),
|
||||||
|
]
|
||||||
|
for path in paths:
|
||||||
|
with open(path, "w") as fh:
|
||||||
|
fh.write(source)
|
||||||
|
result = CliRunner().invoke(
|
||||||
|
black.main, [str(p) for p in paths] + ["--py36"]
|
||||||
|
)
|
||||||
|
self.assertEqual(result.exit_code, 0)
|
||||||
|
for path in paths:
|
||||||
|
with open(path, "r") as fh:
|
||||||
|
actual = fh.read()
|
||||||
|
self.assertEqual(actual, expected)
|
||||||
|
# verify cache with --py36 is separate
|
||||||
|
pyi_cache = black.read_cache(black.DEFAULT_LINE_LENGTH, py36=True)
|
||||||
|
normal_cache = black.read_cache(black.DEFAULT_LINE_LENGTH)
|
||||||
|
for path in paths:
|
||||||
|
self.assertIn(path, pyi_cache)
|
||||||
|
self.assertNotIn(path, normal_cache)
|
||||||
|
|
||||||
|
def test_pipe_force_py36(self) -> None:
|
||||||
|
source, expected = read_data("force_py36")
|
||||||
|
result = CliRunner().invoke(black.main, ["-", "-q", "--py36"], input=source)
|
||||||
|
self.assertEqual(result.exit_code, 0)
|
||||||
|
actual = result.output
|
||||||
|
self.assertFormatEqual(actual, expected)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
unittest.main()
|
unittest.main()
|
||||||
|
Loading…
Reference in New Issue
Block a user