Skip to content

Commit

Permalink
Merge pull request #270 from akaihola/black-22
Browse files Browse the repository at this point in the history
Add compatibility with Black >= 22.1
  • Loading branch information
akaihola authored Feb 6, 2022
2 parents 5cd60ee + d6490d2 commit 715e5a2
Show file tree
Hide file tree
Showing 12 changed files with 98 additions and 16 deletions.
7 changes: 6 additions & 1 deletion .github/workflows/python-package.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,11 @@ jobs:
matrix:
os: [ubuntu-latest, windows-latest, macos-latest]
python-version: ['3.6', '3.7', '3.8', '3.9', '3.10']
constraints: ['']
include:
- os: ubuntu-latest
python-version: '3.7'
constraints: '--constraint constraints-oldest.txt'

steps:
- uses: actions/checkout@v2
Expand All @@ -30,7 +35,7 @@ jobs:
- name: Install dependencies
run: |
python -m pip install --upgrade 'pip>=20.3' # strict dependency resolution added in pip 20.3
pip install -e '.[isort,test]'
pip install -e '.[isort,test]' ${{ matrix.constraints }}
- name: Test with pytest
run: |
pytest
1 change: 1 addition & 0 deletions CHANGES.rst
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ Fixed
- ``regex`` module now always available for unit tests
- Compatibility with NixOS. Keep ``$PATH`` intact so Git can be called.
- Updated tests to pass on new Pygments versions
- Compatibility with Black 22.1


1.3.2_ - 2021-10-28
Expand Down
13 changes: 13 additions & 0 deletions constraints-oldest.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# Constraints for pip to pin dependencies to oldest supported versions.
# This is used in a GitHub Workflow matrix job which ensures everything
# still works against oldest supported versions of both the Python
# interpreter and Python ependencies. Keep this up-to-date with minimum
# versions in `setup.cfg`.
black==21.8b0
mypy==0.910
pytest==6.1.0
pytest-flake8==1.0.6
pytest-isort==1.1.0
pytest-kwparametrize==0.0.3
regex==2021.4.4
types-toml==0.1.3
3 changes: 3 additions & 0 deletions mypy.ini
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,9 @@ strict_equality = True
[mypy-darker.argparse_helpers]
disallow_any_explicit = False

[mypy-darker.black_compat]
disallow_any_explicit = False

[mypy-darker.command_line]
disallow_any_explicit = False

Expand Down
4 changes: 4 additions & 0 deletions setup.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,13 @@ package_dir =
=src
packages = find:
install_requires =
# NOTE: remember to keep `constraints-oldest.txt` in sync with these
black>=21.5b1
toml
typing-extensions ; python_version < "3.8"
dataclasses ; python_version < "3.7"
# NOTE: remember to keep `.github/workflows/python-package.yml` in sync
# with the minimum required Python version
python_requires = >=3.6

[options.packages.find]
Expand All @@ -46,6 +49,7 @@ pygments.lexers =
isort =
isort>=5.0.1
test =
# NOTE: remember to keep `constraints-oldest.txt` in sync with these
black>=21.7b1 # to prevent Mypy error about `gen_python_files`, see issue #189
flake8<4
mypy>=0.910
Expand Down
21 changes: 21 additions & 0 deletions src/darker/black_compat.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
"""Functions for maintaining compatibility with multiple Black versions"""

from pathlib import Path
from typing import Any, Sequence, Tuple, cast

from black import find_project_root as black_find_project_root


def find_project_root(srcs: Sequence[str]) -> Path:
"""Hide changed return value type in Black behind this wrapper
:param srcs: Files and directories to find the common root for
:return: Project root path
"""
root = cast(Any, black_find_project_root(tuple(srcs or ["."])))
if isinstance(root, tuple):
# Black >= 22.1
return cast(Tuple[Path], root)[0]
# Black < 22
return cast(Path, root)
3 changes: 2 additions & 1 deletion src/darker/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@
from typing import Iterable, List, cast

import toml
from black import find_project_root

from darker.black_compat import find_project_root

if sys.version_info >= (3, 8):
from typing import TypedDict
Expand Down
3 changes: 1 addition & 2 deletions src/darker/import_sorting.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,7 @@
from pathlib import Path
from typing import Any, Optional

from black import find_project_root

from darker.black_compat import find_project_root
from darker.exceptions import IncompatiblePackageError, MissingPackageError
from darker.utils import TextDocument

Expand Down
12 changes: 9 additions & 3 deletions src/darker/tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
from typing import Dict, Optional

import pytest
from black import find_project_root
from black import find_project_root as black_find_project_root

from darker.git import _git_check_output_lines

Expand Down Expand Up @@ -97,5 +97,11 @@ def git_repo(tmp_path, monkeypatch):

@pytest.fixture
def find_project_root_cache_clear():
"""Clear LRU caching in :func:`black.find_project_root` before each test"""
find_project_root.cache_clear()
"""Clear LRU caching in :func:`black.find_project_root` before each test
NOTE: We use `darker.black_compat.find_project_root` to wrap Black's original
function since its signature has changed along the way. However, clearing the cache
needs to be done on the original of course.
"""
black_find_project_root.cache_clear()
25 changes: 22 additions & 3 deletions src/darker/tests/test_black_diff.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
"""Unit tests for `darker.black_diff`"""

import re
from dataclasses import dataclass, field
from pathlib import Path
from unittest.mock import ANY, patch

Expand All @@ -17,6 +18,20 @@
from darker.utils import TextDocument


@dataclass
class RegexEquality:
"""Compare equality to either `re.Pattern` or `regex.Pattern`"""

pattern: str
flags: int = field(default=re.UNICODE)

def __eq__(self, other):
return (
other.pattern == self.pattern
and other.flags & 0x1FF == re.compile(self.pattern).flags | self.flags
)


@pytest.mark.kwparametrize(
dict(
config_path=None, config_lines=["line-length = 79"], expect={"line_length": 79}
Expand Down Expand Up @@ -46,15 +61,19 @@
dict(config_lines=[r"include = '\.pyi$'"], expect={}),
dict(
config_lines=[r"exclude = '\.pyx$'"],
expect={"exclude": re.compile("\\.pyx$")},
expect={"exclude": RegexEquality("\\.pyx$")},
),
dict(
config_lines=["extend-exclude = '''", r"^/setup\.py", r"|^/dummy\.py", "'''"],
expect={"extend_exclude": re.compile("(?x)^/setup\\.py\n|^/dummy\\.py\n")},
expect={
"extend_exclude": RegexEquality(
"(?x)^/setup\\.py\n|^/dummy\\.py\n", re.VERBOSE
)
},
),
dict(
config_lines=["force-exclude = '''", r"^/setup\.py", r"|\.pyc$", "'''"],
expect={"force_exclude": re.compile("(?x)^/setup\\.py\n|\\.pyc$\n")},
expect={"force_exclude": RegexEquality("(?x)^/setup\\.py\n|\\.pyc$\n")},
),
config_path=None,
)
Expand Down
13 changes: 10 additions & 3 deletions src/darker/tests/test_import_sorting.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
"""Tests for :mod:`darker.import_sorting`"""

# pylint: disable=unused-argument

from importlib import reload
from pathlib import Path
from textwrap import dedent

import pytest
from black import find_project_root

import darker.import_sorting
from darker.tests.helpers import isort_present
Expand Down Expand Up @@ -76,9 +77,15 @@ def test_apply_isort(encoding, newline):
),
),
)
def test_isort_config(monkeypatch, tmpdir, line_length, settings_file, expect):
def test_isort_config(
monkeypatch,
tmpdir,
find_project_root_cache_clear,
line_length,
settings_file,
expect,
):
"""``apply_isort()`` parses ``pyproject.toml``correctly"""
find_project_root.cache_clear()
monkeypatch.chdir(tmpdir)
(tmpdir / "pyproject.toml").write(
dedent(
Expand Down
9 changes: 6 additions & 3 deletions src/darker/tests/test_main.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
from unittest.mock import call, patch

import pytest
from black import find_project_root

import darker.__main__
import darker.import_sorting
Expand All @@ -38,9 +37,13 @@ def test_isort_option_without_isort(git_repo, caplog):


@pytest.fixture
def run_isort(git_repo, monkeypatch, caplog, request):
find_project_root.cache_clear()
def run_isort(git_repo, monkeypatch, caplog, request, find_project_root_cache_clear):
"""Fixture for running Darker with requested arguments and a patched `isort`
Provides an `run_isort.isort_code` mock object which allows checking whether and how
the `isort.code()` function was called.
"""
monkeypatch.chdir(git_repo.root)
paths = git_repo.add({"test1.py": "original"}, commit="Initial commit")
paths["test1.py"].write_bytes(b"changed")
Expand Down

0 comments on commit 715e5a2

Please sign in to comment.