Skip to content

Commit

Permalink
Add the -t/--target-version command line option
Browse files Browse the repository at this point in the history
  • Loading branch information
aljazerzen authored and akaihola committed Jan 6, 2023
1 parent 322151f commit e90f95f
Show file tree
Hide file tree
Showing 7 changed files with 182 additions and 40 deletions.
1 change: 1 addition & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ requires = ["setuptools", "wheel"] # PEP 508 specifications.

[tool.black]
skip-string-normalization = false
target-version = ["py311"]

[tool.isort]
profile = "black"
Expand Down
2 changes: 2 additions & 0 deletions src/darker/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -387,6 +387,8 @@ def main( # pylint: disable=too-many-locals,too-many-branches,too-many-statemen
black_config["config"] = args.config
if args.line_length:
black_config["line_length"] = args.line_length
if args.target_version:
black_config["target_version"] = {args.target_version}
if args.skip_string_normalization is not None:
black_config["skip_string_normalization"] = args.skip_string_normalization
if args.skip_magic_trailing_comma is not None:
Expand Down
18 changes: 12 additions & 6 deletions src/darker/black_diff.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@
import logging
import sys
from pathlib import Path
from typing import Collection, Optional, Pattern, Set, Tuple
from typing import Collection, Optional, Pattern, Set, Tuple, Union

# `FileMode as Mode` required to satisfy mypy==0.782. Strange.
from black import FileMode as Mode
Expand All @@ -54,6 +54,7 @@
from black.files import gen_python_files
from black.report import Report

from darker.config import ConfigurationError
from darker.utils import TextDocument

if sys.version_info >= (3, 8):
Expand All @@ -77,7 +78,7 @@ class BlackConfig(TypedDict, total=False):
exclude: Pattern[str]
extend_exclude: Pattern[str]
force_exclude: Pattern[str]
target_version: str
target_version: Union[str, Set[str]]
line_length: int
skip_string_normalization: bool
skip_magic_trailing_comma: bool
Expand Down Expand Up @@ -189,10 +190,15 @@ def run_black(src_contents: TextDocument, black_config: BlackConfig) -> TextDocu
if "line_length" in black_config:
mode["line_length"] = black_config["line_length"]
if "target_version" in black_config:
ver_str = black_config["target_version"]
ver = next((v for v in TargetVersion if v.name.lower() == ver_str), None)
if ver:
mode["target_versions"] = {ver}
if isinstance(black_config["target_version"], set):
target_versions_in = black_config["target_version"]
else:
target_versions_in = {black_config["target_version"]}
all_target_versions = {tgt_v.name.lower(): tgt_v for tgt_v in TargetVersion}
bad_target_versions = target_versions_in - set(all_target_versions)
if bad_target_versions:
raise ConfigurationError(f"Invalid target version(s) {bad_target_versions}")
mode["target_versions"] = {all_target_versions[n] for n in target_versions_in}
if "skip_magic_trailing_comma" in black_config:
mode["magic_trailing_comma"] = not black_config["skip_magic_trailing_comma"]
if "skip_string_normalization" in black_config:
Expand Down
19 changes: 19 additions & 0 deletions src/darker/command_line.py
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,25 @@ def add_arg(help_text: Optional[str], *name_or_flags: str, **kwargs: Any) -> Non
dest="line_length",
metavar="LENGTH",
)
add_arg(
hlp.TARGET_VERSION,
"-t",
"--target-version",
type=str,
dest="target_version",
metavar="VERSION",
choices=[
"py33",
"py34",
"py35",
"py36",
"py37",
"py38",
"py39",
"py310",
"py311",
],
)
add_arg(hlp.WORKERS, "-W", "--workers", type=int, dest="workers", default=1)
# A hidden option for printing command lines option in a format suitable for
# `README.rst`:
Expand Down
1 change: 1 addition & 0 deletions src/darker/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ class DarkerConfig(TypedDict, total=False):
skip_string_normalization: bool
skip_magic_trailing_comma: bool
line_length: int
target_version: str
workers: int


Expand Down
6 changes: 5 additions & 1 deletion src/darker/help.py
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,10 @@

LINE_LENGTH = "How many characters per line to allow [default: 88]"

TARGET_VERSION = "Python versions that should be supported. [default: py37]"
TARGET_VERSION = (
"[py33|py34|py35|py36|py37|py38|py39|py310|py311]"
" Python versions that should be supported by"
" Black's output. [default: py311]"
)

WORKERS = "How many parallel workers to allow, or `0` for one per core [default: 1]"
175 changes: 142 additions & 33 deletions src/darker/tests/test_command_line.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@

import pytest
import toml
from black import TargetVersion

import darker.help
from darker import black_diff
Expand Down Expand Up @@ -395,6 +396,36 @@ def test_parse_command_line_config_location_specified(
expect_config=("line_length", 99),
expect_modified=("line_length", 99),
),
dict(
argv=["--target-version", "py37", "."],
expect_value=("target_version", "py37"),
expect_config=("target_version", "py37"),
expect_modified=("target_version", "py37"),
),
dict(
argv=["--target-version", "py39", "."],
expect_value=("target_version", "py39"),
expect_config=("target_version", "py39"),
expect_modified=("target_version", "py39"),
),
dict(
argv=["--target-version", "py37", "--target-version", "py39", "."],
expect_value=("target_version", "py39"),
expect_config=("target_version", "py39"),
expect_modified=("target_version", "py39"),
),
dict(
argv=["--target-version", "py39", "--target-version", "py37", "."],
expect_value=("target_version", "py37"),
expect_config=("target_version", "py37"),
expect_modified=("target_version", "py37"),
),
dict(
argv=["--target-version", "py39,py37", "."],
expect_value=SystemExit,
expect_config=None,
expect_modified=None,
),
dict(
# this is accepted as a path, but would later fail if a file or directory with
# that funky name doesn't exist
Expand Down Expand Up @@ -476,11 +507,19 @@ def test_help_with_isort_package(capsys):
dict(options=[], expect=call()),
dict(
options=["-c", "black.cfg"],
expect=call(line_length=81, string_normalization=True),
expect=call(
line_length=81,
string_normalization=True,
target_versions={TargetVersion.PY38},
),
),
dict(
options=["--config", "black.cfg"],
expect=call(line_length=81, string_normalization=True),
expect=call(
line_length=81,
string_normalization=True,
target_versions={TargetVersion.PY38},
),
),
dict(options=["-S"], expect=call(string_normalization=False)),
dict(
Expand All @@ -490,19 +529,64 @@ def test_help_with_isort_package(capsys):
dict(options=["--line-length", "90"], expect=call(line_length=90)),
dict(
options=["-c", "black.cfg", "-S"],
expect=call(line_length=81, string_normalization=False),
expect=call(
line_length=81,
string_normalization=False,
target_versions={TargetVersion.PY38},
),
),
dict(
options=["-c", "black.cfg", "-l", "90"],
expect=call(line_length=90, string_normalization=True),
expect=call(
line_length=90,
string_normalization=True,
target_versions={TargetVersion.PY38},
),
),
dict(
options=["-l", "90", "-S"],
expect=call(line_length=90, string_normalization=False),
),
dict(
options=["-c", "black.cfg", "-l", "90", "-S"],
expect=call(line_length=90, string_normalization=False),
expect=call(
line_length=90,
string_normalization=False,
target_versions={TargetVersion.PY38},
),
),
dict(options=["-t", "py39"], expect=call(target_versions={TargetVersion.PY39})),
dict(
options=["--target-version", "py39"],
expect=call(target_versions={TargetVersion.PY39}),
),
dict(
options=["-c", "black.cfg", "-S"],
expect=call(
line_length=81,
string_normalization=False,
target_versions={TargetVersion.PY38},
),
),
dict(
options=["-c", "black.cfg", "-t", "py39"],
expect=call(
line_length=81,
string_normalization=True,
target_versions={TargetVersion.PY39},
),
),
dict(
options=["-t", "py39", "-S"],
expect=call(string_normalization=False, target_versions={TargetVersion.PY39}),
),
dict(
options=["-c", "black.cfg", "-t", "py39", "-S"],
expect=call(
line_length=81,
string_normalization=False,
target_versions={TargetVersion.PY39},
),
),
)
def test_black_options(monkeypatch, tmpdir, git_repo, options, expect):
Expand All @@ -515,6 +599,7 @@ def test_black_options(monkeypatch, tmpdir, git_repo, options, expect):
[tool.black]
line-length = 81
skip-string-normalization = false
target-version = 'py38'
"""
)
)
Expand Down Expand Up @@ -572,35 +657,49 @@ def test_black_options(monkeypatch, tmpdir, git_repo, options, expect):
options=["--no-skip-string-normalization"],
expect=call(string_normalization=True),
),
dict(
config=[],
options=["--skip-magic-trailing-comma"],
expect=call(magic_trailing_comma=False),
),
dict(
config=["skip_magic_trailing_comma = false"],
options=[],
expect=call(magic_trailing_comma=True),
),
dict(
config=["skip_magic_trailing_comma = true"],
options=[],
expect=call(magic_trailing_comma=False),
),
dict(
config=[],
options=["--target-version", "py39"],
expect=call(target_versions={TargetVersion.PY39}),
),
dict(
config=["target-version = 'py39'"],
options=[],
expect=call(target_versions={TargetVersion.PY39}),
),
dict(
config=["target_version = ['py39']"],
options=[],
expect=call(target_versions={TargetVersion.PY39}),
),
dict(
config=["target-version = 'py38'"],
options=["--target-version", "py39"],
expect=call(target_versions={TargetVersion.PY39}),
),
dict(
config=["target-version = ['py38']"],
options=["-t", "py39"],
expect=call(target_versions={TargetVersion.PY39}),
),
)
def test_black_options_skip_string_normalization(git_repo, config, options, expect):
"""Black string normalization config and cmdline option are combined correctly"""
added_files = git_repo.add(
{"main.py": "foo", "pyproject.toml": joinlines(["[tool.black]"] + config)},
commit="Initial commit",
)
added_files["main.py"].write_bytes(b"bar")
mode_class_mock = Mock(wraps=black_diff.Mode)
# Speed up tests by mocking `format_str` to skip running Black
format_str = Mock(return_value="bar")
with patch.multiple(black_diff, Mode=mode_class_mock, format_str=format_str):

main(options + [str(path) for path in added_files.values()])

assert mode_class_mock.call_args_list == [expect]


@pytest.mark.parametrize(
"config, options, expect",
[
([], [], call()),
([], ["--skip-magic-trailing-comma"], call(magic_trailing_comma=False)),
(["skip_magic_trailing_comma = false"], [], call(magic_trailing_comma=True)),
(["skip_magic_trailing_comma = true"], [], call(magic_trailing_comma=False)),
],
)
def test_black_options_skip_magic_trailing_comma(git_repo, config, options, expect):
"""Black string normalization config and cmdline option are combined correctly"""
def test_black_config_file_and_options(git_repo, config, options, expect):
"""Black configuration file and command line options are combined correctly"""
added_files = git_repo.add(
{"main.py": "foo", "pyproject.toml": joinlines(["[tool.black]"] + config)},
commit="Initial commit",
Expand Down Expand Up @@ -679,6 +778,16 @@ def test_black_options_skip_magic_trailing_comma(git_repo, config, options, expe
{},
),
),
dict(
options=["--target-version", "py39", "a.py"],
expect=(
Path("git_root"),
{Path("a.py")},
Exclusions(black=set(), isort={"**/*"}),
RevisionRange("HEAD", ":WORKTREE:"),
{"target_version": {"py39"}},
),
),
)
def test_options(git_repo, options, expect):
"""The main engine is called with correct parameters based on the command line
Expand Down

0 comments on commit e90f95f

Please sign in to comment.