Skip to content

Commit

Permalink
Merge pull request #254 from offbyone/ci-refresh
Browse files Browse the repository at this point in the history
A general CI refresh

- tox-gh fixed to correctly select environments
- switch to ruff / uv for CI speed
  • Loading branch information
offbyone authored Sep 26, 2024
2 parents 946d570 + 3eedf1a commit 432c410
Show file tree
Hide file tree
Showing 18 changed files with 1,826 additions and 104 deletions.
46 changes: 24 additions & 22 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,25 +33,23 @@ jobs:
- "pypy3.9"
exclude:
- os: macos-latest
python-version: pypy3
python-version: pypy3.9

steps:
- uses: actions/checkout@v4
with:
# We want our tags here
fetch-depth: 0
- uses: actions/setup-python@v5
- name: Install the latest version of uv
id: setup-uv
uses: astral-sh/setup-uv@v3
with:
python-version: "${{ matrix.python-version }}"
- name: "Install dependencies"
run: |
python -VV
python -msite
python -m pip install --upgrade pip setuptools wheel
python -m pip install --upgrade coverage[toml] virtualenv tox tox-gh-actions
enable-cache: true

- name: "Run tox targets for ${{ matrix.python-version }}"
run: "python -m tox"
env:
TOX_GH_MAJOR_MINOR: ${{ matrix.python-version }}
run: uvx --with tox-uv --with tox-gh tox

- name: Upload coverage data
uses: actions/upload-artifact@v4
Expand All @@ -67,12 +65,11 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
- name: Install the latest version of uv
id: setup-uv
uses: astral-sh/setup-uv@v3
with:
python-version: "3.12"

- name: Install coverage
run: python -m pip install --upgrade coverage[toml]
enable-cache: true

- name: Download coverage data
uses: actions/download-artifact@v4
Expand All @@ -81,11 +78,12 @@ jobs:
merge-multiple: true

- name: Combine coverage
run: python -m coverage combine
run: |
uvx --with coverage[toml] coverage combine
# ignore-errors is so that we don't gag on missing code in .tox environments
- name: Generate the HTML report
run: python -m coverage html --skip-covered --skip-empty --ignore-errors
run: uvx --with coverage[toml] coverage html --skip-covered --skip-empty --ignore-errors

- name: Upload the HTML report
uses: actions/upload-artifact@v4
Expand All @@ -95,7 +93,7 @@ jobs:

# ignore-errors is so that we don't gag on missing code in .tox environments
- name: Enforce the coverage
run: python -m coverage report --ignore-errors --fail-under 95
run: uvx --with coverage[toml] coverage report --ignore-errors --fail-under 95

package:
name: "Build & verify package"
Expand All @@ -118,10 +116,14 @@ jobs:

steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
- name: Install the latest version of uv
id: setup-uv
uses: astral-sh/setup-uv@v3
with:
python-version: "3.12"
enable-cache: true
- name: "Install in dev mode"
run: "python -m pip install -e .[dev]"
run: |
uv venv
uv pip install -e .[dev]
- name: "Import package"
run: "python -c 'import hamcrest; print(hamcrest.__version__)'"
run: "uv run python -c 'import hamcrest; print(hamcrest.__version__)'"
22 changes: 8 additions & 14 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -15,18 +15,12 @@ repos:
- id: blacken-docs
# args: ["-l100"]

- repo: https://github.com/PyCQA/flake8
rev: 7.1.1
- repo: https://github.com/astral-sh/ruff-pre-commit
# Ruff version.
rev: v0.6.8
hooks:
- id: flake8
exclude: >-
(?x)^(
examples/.*\.py$
| doc/.*\.py$
)
- repo: https://github.com/psf/black
rev: 24.8.0
hooks:
- id: black
# args: ["-l100"]
# Run the linter.
- id: ruff
args: [ --fix ]
# Run the formatter.
- id: ruff-format
3 changes: 2 additions & 1 deletion doc/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@
# All configuration values have a default; values that are commented out
# serve to show the default.

import sys, os
import sys
import os
import alabaster

# If extensions (or modules to document with autodoc) are in another directory,
Expand Down
16 changes: 15 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ dev = [
"flake8",
"black",
"tox",
"tox-asdf",
"tox-uv",
"doc2dash",
]

Expand Down Expand Up @@ -137,6 +137,20 @@ exclude_lines = [
"-> ['\"]?NoReturn['\"]?:",
]

[tool.ruff]
exclude = [
# re-ordering in this can lead to circular imports. No good!
"src/hamcrest/__init__.py",
]
line-length = 100

[tool.ruff.lint]
ignore = [
# We use star imports everywhere in this damn codebase
"F405",
"F403"
]

[tool.black]
line_length = 100

Expand Down
2 changes: 2 additions & 0 deletions src/hamcrest/core/__init__.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
# ruff: noqa: F405, F403

from hamcrest.core.assert_that import assert_that
from hamcrest.core.core import *

Expand Down
6 changes: 2 additions & 4 deletions src/hamcrest/core/assert_that.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,11 @@


@overload
def assert_that(actual_or_assertion: T, matcher: Matcher[T], reason: str = "") -> None:
...
def assert_that(actual_or_assertion: T, matcher: Matcher[T], reason: str = "") -> None: ...


@overload
def assert_that(actual_or_assertion: bool, reason: str = "") -> None:
...
def assert_that(actual_or_assertion: bool, reason: str = "") -> None: ...


def assert_that(actual_or_assertion, matcher=None, reason=""):
Expand Down
15 changes: 5 additions & 10 deletions src/hamcrest/core/core/is_.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,13 +29,11 @@ def describe_to(self, description: Description):


@overload
def _wrap_value_or_type(x: Type) -> Matcher[object]:
...
def _wrap_value_or_type(x: Type) -> Matcher[object]: ...


@overload
def _wrap_value_or_type(x: T) -> Matcher[T]:
...
def _wrap_value_or_type(x: T) -> Matcher[T]: ...


def _wrap_value_or_type(x):
Expand All @@ -46,18 +44,15 @@ def _wrap_value_or_type(x):


@overload
def is_(x: Type) -> Matcher[Any]:
...
def is_(x: Type) -> Matcher[Any]: ...


@overload
def is_(x: Matcher[T]) -> Matcher[T]:
...
def is_(x: Matcher[T]) -> Matcher[T]: ...


@overload
def is_(x: T) -> Matcher[T]:
...
def is_(x: T) -> Matcher[T]: ...


def is_(x):
Expand Down
12 changes: 4 additions & 8 deletions src/hamcrest/core/core/isnot.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,13 +30,11 @@ def describe_mismatch(self, item: T, mismatch_description: Description) -> None:


@overload
def _wrap_value_or_type(x: Type) -> Matcher[object]:
...
def _wrap_value_or_type(x: Type) -> Matcher[object]: ...


@overload
def _wrap_value_or_type(x: T) -> Matcher[T]:
...
def _wrap_value_or_type(x: T) -> Matcher[T]: ...


def _wrap_value_or_type(x):
Expand All @@ -47,13 +45,11 @@ def _wrap_value_or_type(x):


@overload
def is_not(match: Type) -> Matcher[object]:
...
def is_not(match: Type) -> Matcher[object]: ...


@overload
def is_not(match: Union[Matcher[T], T]) -> Matcher[T]:
...
def is_not(match: Union[Matcher[T], T]) -> Matcher[T]: ...


def is_not(match):
Expand Down
1 change: 1 addition & 0 deletions src/hamcrest/library/__init__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
"""Library of Matcher implementations."""

# ruff: noqa: F405, F403
from hamcrest.core import *
from hamcrest.library.collection import *
from hamcrest.library.integration import *
Expand Down
1 change: 1 addition & 0 deletions src/hamcrest/library/collection/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""Matchers of collections."""

from .is_empty import empty
from .isdict_containing import has_entry
from .isdict_containingentries import has_entries
Expand Down
9 changes: 3 additions & 6 deletions src/hamcrest/library/collection/isdict_containingentries.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,20 +73,17 @@ def describe_to(self, description: Description) -> None:

# Keyword argument form
@overload
def has_entries(**keys_valuematchers: Union[Matcher[V], V]) -> Matcher[Mapping[str, V]]:
...
def has_entries(**keys_valuematchers: Union[Matcher[V], V]) -> Matcher[Mapping[str, V]]: ...


# Key to matcher dict form
@overload
def has_entries(keys_valuematchers: Mapping[K, Union[Matcher[V], V]]) -> Matcher[Mapping[K, V]]:
...
def has_entries(keys_valuematchers: Mapping[K, Union[Matcher[V], V]]) -> Matcher[Mapping[K, V]]: ...


# Alternating key/matcher form
@overload
def has_entries(*keys_valuematchers: Any) -> Matcher[Mapping[Any, Any]]:
...
def has_entries(*keys_valuematchers: Any) -> Matcher[Mapping[Any, Any]]: ...


def has_entries(*keys_valuematchers, **kv_args):
Expand Down
6 changes: 2 additions & 4 deletions src/hamcrest/library/number/iscloseto.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,13 +62,11 @@ def describe_to(self, description: Description) -> None:


@overload
def close_to(value: float, delta: float) -> Matcher[float]:
...
def close_to(value: float, delta: float) -> Matcher[float]: ...


@overload
def close_to(value: Decimal, delta: Decimal) -> Matcher[Decimal]:
...
def close_to(value: Decimal, delta: Decimal) -> Matcher[Decimal]: ...


def close_to(value, delta):
Expand Down
9 changes: 3 additions & 6 deletions src/hamcrest/library/object/hasproperty.py
Original file line number Diff line number Diff line change
Expand Up @@ -94,20 +94,17 @@ def has_property(name: str, match: Union[None, Matcher[V], V] = None) -> Matcher

# Keyword argument form
@overload
def has_properties(**keys_valuematchers: Union[Matcher[V], V]) -> Matcher[Any]:
...
def has_properties(**keys_valuematchers: Union[Matcher[V], V]) -> Matcher[Any]: ...


# Name to matcher dict form
@overload
def has_properties(keys_valuematchers: Mapping[str, Union[Matcher[V], V]]) -> Matcher[Any]:
...
def has_properties(keys_valuematchers: Mapping[str, Union[Matcher[V], V]]) -> Matcher[Any]: ...


# Alternating name/matcher form
@overload
def has_properties(*keys_valuematchers: Any) -> Matcher[Any]:
...
def has_properties(*keys_valuematchers: Any) -> Matcher[Any]: ...


def has_properties(*keys_valuematchers, **kv_args):
Expand Down
3 changes: 1 addition & 2 deletions src/hamcrest/library/text/substringmatcher.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,5 +20,4 @@ def describe_to(self, description: Description) -> None:
).append_description_of(self.substring)

@abstractmethod
def relationship(self):
...
def relationship(self): ...
2 changes: 1 addition & 1 deletion tests/hamcrest_unit_test/assert_that_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ def testAssertionErrorShouldIncludeOptionalReason(self):

def testAssertionUnicodeEncodesProperly(self):
expected = "EXPECTED"
actual = u("\xdcnic\N{Latin Small Letter O with diaeresis}de")
actual = u("\xdcnic\N{LATIN SMALL LETTER O WITH DIAERESIS}de")

with self.assertRaises(AssertionError):
assert_that(actual, equal_to(expected), "REASON")
Expand Down
4 changes: 2 additions & 2 deletions tests/hamcrest_unit_test/base_description_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,8 @@ def test_append_text_delegates(desc):
("unicode-py3", "'unicode-py3'"),
(b"bytes-py3", "<b'bytes-py3'>"),
pytest.param(
"\U0001F4A9",
"'{0}'".format("\U0001F4A9"),
"\U0001f4a9",
"'{0}'".format("\U0001f4a9"),
marks=pytest.mark.skipif(
platform.python_implementation() == "PyPy",
reason="Inexplicable failure on PyPy. Not super important, I hope!",
Expand Down
Loading

0 comments on commit 432c410

Please sign in to comment.