Skip to content

Commit 432c410

Browse files
authored
Merge pull request #254 from offbyone/ci-refresh
A general CI refresh - tox-gh fixed to correctly select environments - switch to ruff / uv for CI speed
2 parents 946d570 + 3eedf1a commit 432c410

File tree

18 files changed

+1826
-104
lines changed

18 files changed

+1826
-104
lines changed

.github/workflows/main.yml

Lines changed: 24 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -33,25 +33,23 @@ jobs:
3333
- "pypy3.9"
3434
exclude:
3535
- os: macos-latest
36-
python-version: pypy3
36+
python-version: pypy3.9
3737

3838
steps:
3939
- uses: actions/checkout@v4
4040
with:
4141
# We want our tags here
4242
fetch-depth: 0
43-
- uses: actions/setup-python@v5
43+
- name: Install the latest version of uv
44+
id: setup-uv
45+
uses: astral-sh/setup-uv@v3
4446
with:
45-
python-version: "${{ matrix.python-version }}"
46-
- name: "Install dependencies"
47-
run: |
48-
python -VV
49-
python -msite
50-
python -m pip install --upgrade pip setuptools wheel
51-
python -m pip install --upgrade coverage[toml] virtualenv tox tox-gh-actions
47+
enable-cache: true
5248

5349
- name: "Run tox targets for ${{ matrix.python-version }}"
54-
run: "python -m tox"
50+
env:
51+
TOX_GH_MAJOR_MINOR: ${{ matrix.python-version }}
52+
run: uvx --with tox-uv --with tox-gh tox
5553

5654
- name: Upload coverage data
5755
uses: actions/upload-artifact@v4
@@ -67,12 +65,11 @@ jobs:
6765
runs-on: ubuntu-latest
6866
steps:
6967
- uses: actions/checkout@v4
70-
- uses: actions/setup-python@v5
68+
- name: Install the latest version of uv
69+
id: setup-uv
70+
uses: astral-sh/setup-uv@v3
7171
with:
72-
python-version: "3.12"
73-
74-
- name: Install coverage
75-
run: python -m pip install --upgrade coverage[toml]
72+
enable-cache: true
7673

7774
- name: Download coverage data
7875
uses: actions/download-artifact@v4
@@ -81,11 +78,12 @@ jobs:
8178
merge-multiple: true
8279

8380
- name: Combine coverage
84-
run: python -m coverage combine
81+
run: |
82+
uvx --with coverage[toml] coverage combine
8583
8684
# ignore-errors is so that we don't gag on missing code in .tox environments
8785
- name: Generate the HTML report
88-
run: python -m coverage html --skip-covered --skip-empty --ignore-errors
86+
run: uvx --with coverage[toml] coverage html --skip-covered --skip-empty --ignore-errors
8987

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

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

10098
package:
10199
name: "Build & verify package"
@@ -118,10 +116,14 @@ jobs:
118116

119117
steps:
120118
- uses: actions/checkout@v4
121-
- uses: actions/setup-python@v5
119+
- name: Install the latest version of uv
120+
id: setup-uv
121+
uses: astral-sh/setup-uv@v3
122122
with:
123-
python-version: "3.12"
123+
enable-cache: true
124124
- name: "Install in dev mode"
125-
run: "python -m pip install -e .[dev]"
125+
run: |
126+
uv venv
127+
uv pip install -e .[dev]
126128
- name: "Import package"
127-
run: "python -c 'import hamcrest; print(hamcrest.__version__)'"
129+
run: "uv run python -c 'import hamcrest; print(hamcrest.__version__)'"

.pre-commit-config.yaml

Lines changed: 8 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -15,18 +15,12 @@ repos:
1515
- id: blacken-docs
1616
# args: ["-l100"]
1717

18-
- repo: https://github.com/PyCQA/flake8
19-
rev: 7.1.1
18+
- repo: https://github.com/astral-sh/ruff-pre-commit
19+
# Ruff version.
20+
rev: v0.6.8
2021
hooks:
21-
- id: flake8
22-
exclude: >-
23-
(?x)^(
24-
examples/.*\.py$
25-
| doc/.*\.py$
26-
)
27-
28-
- repo: https://github.com/psf/black
29-
rev: 24.8.0
30-
hooks:
31-
- id: black
32-
# args: ["-l100"]
22+
# Run the linter.
23+
- id: ruff
24+
args: [ --fix ]
25+
# Run the formatter.
26+
- id: ruff-format

doc/conf.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,8 @@
1111
# All configuration values have a default; values that are commented out
1212
# serve to show the default.
1313

14-
import sys, os
14+
import sys
15+
import os
1516
import alabaster
1617

1718
# If extensions (or modules to document with autodoc) are in another directory,

pyproject.toml

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ dev = [
7272
"flake8",
7373
"black",
7474
"tox",
75-
"tox-asdf",
75+
"tox-uv",
7676
"doc2dash",
7777
]
7878

@@ -137,6 +137,20 @@ exclude_lines = [
137137
"-> ['\"]?NoReturn['\"]?:",
138138
]
139139

140+
[tool.ruff]
141+
exclude = [
142+
# re-ordering in this can lead to circular imports. No good!
143+
"src/hamcrest/__init__.py",
144+
]
145+
line-length = 100
146+
147+
[tool.ruff.lint]
148+
ignore = [
149+
# We use star imports everywhere in this damn codebase
150+
"F405",
151+
"F403"
152+
]
153+
140154
[tool.black]
141155
line_length = 100
142156

src/hamcrest/core/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
# ruff: noqa: F405, F403
2+
13
from hamcrest.core.assert_that import assert_that
24
from hamcrest.core.core import *
35

src/hamcrest/core/assert_that.py

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,11 @@
1616

1717

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

2221

2322
@overload
24-
def assert_that(actual_or_assertion: bool, reason: str = "") -> None:
25-
...
23+
def assert_that(actual_or_assertion: bool, reason: str = "") -> None: ...
2624

2725

2826
def assert_that(actual_or_assertion, matcher=None, reason=""):

src/hamcrest/core/core/is_.py

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -29,13 +29,11 @@ def describe_to(self, description: Description):
2929

3030

3131
@overload
32-
def _wrap_value_or_type(x: Type) -> Matcher[object]:
33-
...
32+
def _wrap_value_or_type(x: Type) -> Matcher[object]: ...
3433

3534

3635
@overload
37-
def _wrap_value_or_type(x: T) -> Matcher[T]:
38-
...
36+
def _wrap_value_or_type(x: T) -> Matcher[T]: ...
3937

4038

4139
def _wrap_value_or_type(x):
@@ -46,18 +44,15 @@ def _wrap_value_or_type(x):
4644

4745

4846
@overload
49-
def is_(x: Type) -> Matcher[Any]:
50-
...
47+
def is_(x: Type) -> Matcher[Any]: ...
5148

5249

5350
@overload
54-
def is_(x: Matcher[T]) -> Matcher[T]:
55-
...
51+
def is_(x: Matcher[T]) -> Matcher[T]: ...
5652

5753

5854
@overload
59-
def is_(x: T) -> Matcher[T]:
60-
...
55+
def is_(x: T) -> Matcher[T]: ...
6156

6257

6358
def is_(x):

src/hamcrest/core/core/isnot.py

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -30,13 +30,11 @@ def describe_mismatch(self, item: T, mismatch_description: Description) -> None:
3030

3131

3232
@overload
33-
def _wrap_value_or_type(x: Type) -> Matcher[object]:
34-
...
33+
def _wrap_value_or_type(x: Type) -> Matcher[object]: ...
3534

3635

3736
@overload
38-
def _wrap_value_or_type(x: T) -> Matcher[T]:
39-
...
37+
def _wrap_value_or_type(x: T) -> Matcher[T]: ...
4038

4139

4240
def _wrap_value_or_type(x):
@@ -47,13 +45,11 @@ def _wrap_value_or_type(x):
4745

4846

4947
@overload
50-
def is_not(match: Type) -> Matcher[object]:
51-
...
48+
def is_not(match: Type) -> Matcher[object]: ...
5249

5350

5451
@overload
55-
def is_not(match: Union[Matcher[T], T]) -> Matcher[T]:
56-
...
52+
def is_not(match: Union[Matcher[T], T]) -> Matcher[T]: ...
5753

5854

5955
def is_not(match):

src/hamcrest/library/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
"""Library of Matcher implementations."""
22

3+
# ruff: noqa: F405, F403
34
from hamcrest.core import *
45
from hamcrest.library.collection import *
56
from hamcrest.library.integration import *

src/hamcrest/library/collection/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
"""Matchers of collections."""
2+
23
from .is_empty import empty
34
from .isdict_containing import has_entry
45
from .isdict_containingentries import has_entries

src/hamcrest/library/collection/isdict_containingentries.py

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -73,20 +73,17 @@ def describe_to(self, description: Description) -> None:
7373

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

7978

8079
# Key to matcher dict form
8180
@overload
82-
def has_entries(keys_valuematchers: Mapping[K, Union[Matcher[V], V]]) -> Matcher[Mapping[K, V]]:
83-
...
81+
def has_entries(keys_valuematchers: Mapping[K, Union[Matcher[V], V]]) -> Matcher[Mapping[K, V]]: ...
8482

8583

8684
# Alternating key/matcher form
8785
@overload
88-
def has_entries(*keys_valuematchers: Any) -> Matcher[Mapping[Any, Any]]:
89-
...
86+
def has_entries(*keys_valuematchers: Any) -> Matcher[Mapping[Any, Any]]: ...
9087

9188

9289
def has_entries(*keys_valuematchers, **kv_args):

src/hamcrest/library/number/iscloseto.py

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -62,13 +62,11 @@ def describe_to(self, description: Description) -> None:
6262

6363

6464
@overload
65-
def close_to(value: float, delta: float) -> Matcher[float]:
66-
...
65+
def close_to(value: float, delta: float) -> Matcher[float]: ...
6766

6867

6968
@overload
70-
def close_to(value: Decimal, delta: Decimal) -> Matcher[Decimal]:
71-
...
69+
def close_to(value: Decimal, delta: Decimal) -> Matcher[Decimal]: ...
7270

7371

7472
def close_to(value, delta):

src/hamcrest/library/object/hasproperty.py

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -94,20 +94,17 @@ def has_property(name: str, match: Union[None, Matcher[V], V] = None) -> Matcher
9494

9595
# Keyword argument form
9696
@overload
97-
def has_properties(**keys_valuematchers: Union[Matcher[V], V]) -> Matcher[Any]:
98-
...
97+
def has_properties(**keys_valuematchers: Union[Matcher[V], V]) -> Matcher[Any]: ...
9998

10099

101100
# Name to matcher dict form
102101
@overload
103-
def has_properties(keys_valuematchers: Mapping[str, Union[Matcher[V], V]]) -> Matcher[Any]:
104-
...
102+
def has_properties(keys_valuematchers: Mapping[str, Union[Matcher[V], V]]) -> Matcher[Any]: ...
105103

106104

107105
# Alternating name/matcher form
108106
@overload
109-
def has_properties(*keys_valuematchers: Any) -> Matcher[Any]:
110-
...
107+
def has_properties(*keys_valuematchers: Any) -> Matcher[Any]: ...
111108

112109

113110
def has_properties(*keys_valuematchers, **kv_args):

src/hamcrest/library/text/substringmatcher.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,5 +20,4 @@ def describe_to(self, description: Description) -> None:
2020
).append_description_of(self.substring)
2121

2222
@abstractmethod
23-
def relationship(self):
24-
...
23+
def relationship(self): ...

tests/hamcrest_unit_test/assert_that_test.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ def testAssertionErrorShouldIncludeOptionalReason(self):
4343

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

4848
with self.assertRaises(AssertionError):
4949
assert_that(actual, equal_to(expected), "REASON")

tests/hamcrest_unit_test/base_description_test.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,8 @@ def test_append_text_delegates(desc):
4242
("unicode-py3", "'unicode-py3'"),
4343
(b"bytes-py3", "<b'bytes-py3'>"),
4444
pytest.param(
45-
"\U0001F4A9",
46-
"'{0}'".format("\U0001F4A9"),
45+
"\U0001f4a9",
46+
"'{0}'".format("\U0001f4a9"),
4747
marks=pytest.mark.skipif(
4848
platform.python_implementation() == "PyPy",
4949
reason="Inexplicable failure on PyPy. Not super important, I hope!",

0 commit comments

Comments
 (0)