diff --git a/.github/workflows/flake8.yml b/.github/workflows/flake8.yml index f689082d1..06499c211 100644 --- a/.github/workflows/flake8.yml +++ b/.github/workflows/flake8.yml @@ -9,6 +9,9 @@ jobs: steps: - uses: actions/checkout@v4 + - uses: actions/setup-python@v5 + with: + python-version: 3.x - uses: TrueBrain/actions-flake8@v2 with: plugins: > diff --git a/.github/workflows/help-in-readme.yml b/.github/workflows/help-in-readme.yml index 69551ec64..2b70097fc 100644 --- a/.github/workflows/help-in-readme.yml +++ b/.github/workflows/help-in-readme.yml @@ -6,6 +6,7 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - - run: pip install '.[flynt,isort]' + - name: Install uv + uses: astral-sh/setup-uv@v3 - name: Verify that README contains output of darker --help - run: darker --verify-readme + run: uvx --from '.[flynt,isort]' darker --verify-readme diff --git a/.github/workflows/isort.yml b/.github/workflows/isort.yml index 32c156289..49fcf95a7 100644 --- a/.github/workflows/isort.yml +++ b/.github/workflows/isort.yml @@ -10,8 +10,10 @@ jobs: steps: - uses: actions/checkout@v4 - uses: actions/setup-python@v5 + with: + python-version: 3.x - run: pip install 'isort>=5.0.1' - - uses: wearerequired/lint-action@v2.3.0 + - uses: akaihola/lint-action@master with: github_token: ${{ secrets.GITHUB_TOKEN }} isort: true diff --git a/.github/workflows/mypy.yml b/.github/workflows/mypy.yml index 8545afa59..dd60081f6 100644 --- a/.github/workflows/mypy.yml +++ b/.github/workflows/mypy.yml @@ -9,9 +9,13 @@ jobs: steps: - uses: actions/checkout@v4 + - name: Install uv + uses: astral-sh/setup-uv@v3 - uses: actions/setup-python@v5 + with: + python-version: 3.x - run: | - pip install -U \ + uv pip install --system -U \ black \ git+https://github.com/akaihola/darkgraylib.git@main \ flynt \ diff --git a/.github/workflows/pylint.yml b/.github/workflows/pylint.yml index 72f53dcd1..7005eb088 100644 --- a/.github/workflows/pylint.yml +++ b/.github/workflows/pylint.yml @@ -9,10 +9,14 @@ jobs: steps: - uses: actions/checkout@v4 + - name: Install uv + uses: astral-sh/setup-uv@v3 - uses: actions/setup-python@v5 + with: + python-version: 3.x - name: Install dependencies for running Pylint run: | - pip install -U \ + uv pip install --system -U \ black \ git+https://github.com/akaihola/darkgraylib.git@main \ defusedxml \ @@ -23,8 +27,9 @@ jobs: requests \ requests-cache \ ruamel.yaml \ + setuptools \ toml - pip list + uv pip list --system - uses: wearerequired/lint-action@v2.3.0 with: github_token: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/python-package.yml b/.github/workflows/python-package.yml index 7e6a25c6f..96e4cd6e5 100644 --- a/.github/workflows/python-package.yml +++ b/.github/workflows/python-package.yml @@ -20,11 +20,11 @@ jobs: wheel-path: ${{ steps.get-darker-version.outputs.wheel-path }} steps: - uses: actions/checkout@v4 + - name: Install uv + uses: astral-sh/setup-uv@v3 - uses: actions/setup-python@v5 - - name: Install wheel - run: python -m pip install wheel - name: Build wheel distribution - run: python setup.py bdist_wheel + run: uv build --wheel - name: Upload wheel for other jobs uses: actions/upload-artifact@v4 with: @@ -146,12 +146,12 @@ jobs: - build-wheel steps: - uses: actions/checkout@v4 + - name: Install uv + uses: astral-sh/setup-uv@v3 - uses: actions/setup-python@v5 - - name: Install twine - run: python -m pip install twine - name: Download wheel uploaded by the build-wheel job uses: actions/download-artifact@v4.1.7 - name: Build source distribution - run: python setup.py sdist + run: uv build --sdist - name: Validate distributions - run: twine check dist/* + run: uvx twine check dist/* diff --git a/.github/workflows/pyupgrade.yml b/.github/workflows/pyupgrade.yml index 0273248ec..22af5bbdf 100644 --- a/.github/workflows/pyupgrade.yml +++ b/.github/workflows/pyupgrade.yml @@ -9,12 +9,13 @@ jobs: steps: - uses: actions/checkout@v4 + - name: Install uv + uses: astral-sh/setup-uv@v3 - uses: actions/setup-python@v5 - - run: pip install pyupgrade - name: Ensure modern Python style using pyupgrade # This script is written in a Linux / macos / windows portable way run: | - python -c " + uvx --from pyupgrade python -c " import sys from pyupgrade._main import main from glob import glob diff --git a/.github/workflows/safety.yml b/.github/workflows/safety.yml index 4aab1bfd4..1d4d567c0 100644 --- a/.github/workflows/safety.yml +++ b/.github/workflows/safety.yml @@ -9,9 +9,9 @@ jobs: steps: - uses: actions/checkout@v4 + - name: Install uv + uses: astral-sh/setup-uv@v3 - uses: actions/setup-python@v5 - - run: pip install -U pip-tools - - run: pip-compile setup.cfg - - run: pip install -U safety + - run: uvx --from pip-tools pip-compile setup.cfg - name: Check dependencies for known security vulnerabilities using Safety - run: safety check --file requirements.txt + run: uvx safety check --file requirements.txt diff --git a/.github/workflows/test-bump-version.yml b/.github/workflows/test-bump-version.yml index 4cf90af6b..d02b0af4e 100644 --- a/.github/workflows/test-bump-version.yml +++ b/.github/workflows/test-bump-version.yml @@ -9,6 +9,8 @@ jobs: steps: - uses: actions/checkout@v4 + - name: Install uv + uses: astral-sh/setup-uv@v3 - uses: actions/setup-python@v5 - name: Make sure that `darkgray_bump_version` still finds all version strings @@ -20,9 +22,7 @@ jobs: # This is used to update the call for reviewing pull requests # in `README.rst`. run: | - pip install \ - https://github.com/akaihola/darkgray-dev-tools/archive/refs/heads/main.zip - darkgray_bump_version \ + uvx --from=darkgray-dev-tools darkgray_bump_version \ --minor \ --dry-run \ --token=${{ secrets.GITHUB_TOKEN }} diff --git a/src/darker/black_diff.py b/src/darker/black_diff.py index b9c106648..a47db055e 100644 --- a/src/darker/black_diff.py +++ b/src/darker/black_diff.py @@ -32,10 +32,12 @@ based on whether reformats touch user-edited lines """ + +from __future__ import annotations + import inspect import logging -from pathlib import Path -from typing import Collection, Optional, Pattern, Set, Tuple, TypedDict, Union +from typing import TYPE_CHECKING, Collection, Pattern, TypedDict # `FileMode as Mode` required to satisfy mypy==0.782. Strange. from black import FileMode as Mode @@ -56,6 +58,9 @@ from darkgraylib.config import ConfigurationError from darkgraylib.utils import TextDocument +if TYPE_CHECKING: + from pathlib import Path + __all__ = ["BlackConfig", "Mode", "run_black"] logger = logging.getLogger(__name__) @@ -69,10 +74,10 @@ class BlackConfig(TypedDict, total=False): """Type definition for Black configuration dictionaries""" config: str - exclude: Pattern[str] - extend_exclude: Pattern[str] - force_exclude: Pattern[str] - target_version: Union[str, Set[str]] + exclude: Pattern[str] | None + extend_exclude: Pattern[str] | None + force_exclude: Pattern[str] | None + target_version: str | set[str] line_length: int skip_string_normalization: bool skip_magic_trailing_comma: bool @@ -82,7 +87,7 @@ class BlackConfig(TypedDict, total=False): class BlackModeAttributes(TypedDict, total=False): """Type definition for items accepted by ``black.Mode``""" - target_versions: Set[TargetVersion] + target_versions: set[TargetVersion] line_length: int string_normalization: bool is_pyi: bool @@ -90,7 +95,7 @@ class BlackModeAttributes(TypedDict, total=False): preview: bool -def read_black_config(src: Tuple[str, ...], value: Optional[str]) -> BlackConfig: +def read_black_config(src: tuple[str, ...], value: str | None) -> BlackConfig: """Read the black configuration from ``pyproject.toml`` :param src: The source code files and directories to be processed by Darker @@ -136,7 +141,7 @@ def filter_python_files( paths: Collection[Path], # pylint: disable=unsubscriptable-object root: Path, black_config: BlackConfig, -) -> Set[Path]: +) -> set[Path]: """Get Python files and explicitly listed files not excluded by Black's config :param paths: Relative file/directory paths from CWD to Python sources @@ -164,7 +169,7 @@ def filter_python_files( directories, root, include=DEFAULT_INCLUDE_RE, - exclude=black_config.get("exclude", DEFAULT_EXCLUDE_RE), + exclude=black_config.get("exclude") or DEFAULT_EXCLUDE_RE, extend_exclude=black_config.get("extend_exclude"), force_exclude=black_config.get("force_exclude"), report=Report(),