Skip to content

Commit ab02630

Browse files
committed
chore: enable lints fully
As there is a significant existing codebase which will eventually be deprecated, there is little benefit to applying formatting and linting rules to the files which are to be deprecated. This commit configures Ruff, Mypy and Black to exclude files in the v2 codebase so that `hatch run lint` can function correctly. As a result, the linting in the CI workflow has also been enabled. An equivalent was already implemented for the pre-commit hooks. Signed-off-by: JP-Ellis <josh@jpellis.me>
1 parent c7c00b7 commit ab02630

15 files changed

+66
-29
lines changed

.github/workflows/test.yml

+13-14
Original file line numberDiff line numberDiff line change
@@ -103,22 +103,21 @@ jobs:
103103
run: >
104104
hatch run example --broker-url=http://pactbroker:pactbroker@localhost:9292
105105
106-
# TODO: Fix lints before enabling this
107-
# lint:
108-
# name: Lint
106+
lint:
107+
name: Lint
109108

110-
# runs-on: ubuntu-latest
109+
runs-on: ubuntu-latest
111110

112-
# steps:
113-
# - uses: actions/checkout@v4
111+
steps:
112+
- uses: actions/checkout@v4
114113

115-
# - name: Set up Python
116-
# uses: actions/setup-python@v4
117-
# with:
118-
# python-version: ${{ env.STABLE_PYTHON_VERSION }}
114+
- name: Set up Python
115+
uses: actions/setup-python@v4
116+
with:
117+
python-version: ${{ env.STABLE_PYTHON_VERSION }}
119118

120-
# - name: Install Hatch
121-
# run: pip install --upgrade hatch
119+
- name: Install Hatch
120+
run: pip install --upgrade hatch
122121

123-
# - name: Lint
124-
# run: hatch run lint
122+
- name: Lint
123+
run: hatch run lint

examples/.ruff.toml

+1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ extend = "../pyproject.toml"
33
ignore = [
44
"S101", # Forbid assert statements
55
"D103", # Require docstring in public function
6+
"D104", # Require docstring in public package
67
]
78

89
[per-file-ignores]

examples/__init__.py

Whitespace-only changes.

examples/conftest.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,14 @@
99
Pact files will be stored. You are encouraged to have a look at these files
1010
after the examples have been run.
1111
"""
12+
1213
from __future__ import annotations
1314

1415
from pathlib import Path
1516
from typing import Any, Generator, Union
1617

1718
import pytest
18-
from testcontainers.compose import DockerCompose
19+
from testcontainers.compose import DockerCompose # type: ignore[import-untyped]
1920
from yarl import URL
2021

2122
EXAMPLE_DIR = Path(__file__).parent.resolve()

examples/src/fastapi.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@
3838

3939

4040
@app.get("/users/{uid}")
41-
async def get_user_by_id(uid: int) -> Dict[str, Any]:
41+
async def get_user_by_id(uid: int) -> JSONResponse:
4242
"""
4343
Fetch a user by their ID.
4444

examples/src/message.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
handler is solely responsible for processing the message, and does not
77
necessarily need to send a response.
88
"""
9+
910
from __future__ import annotations
1011

1112
from pathlib import Path
@@ -59,7 +60,7 @@ def process(self, event: Dict[str, Any]) -> Union[str, None]:
5960
self.validate_event(event)
6061

6162
if event["action"] == "WRITE":
62-
return self.fs.write(event["path"], event.get("contents", ""))
63+
self.fs.write(event["path"], event.get("contents", ""))
6364
if event["action"] == "READ":
6465
return self.fs.read(event["path"])
6566

examples/tests/__init__.py

Whitespace-only changes.

examples/tests/test_00_consumer.py

+3-1
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,11 @@
2121

2222
import pytest
2323
import requests
24-
from examples.src.consumer import User, UserConsumer
2524
from pact import Consumer, Format, Like, Provider
2625
from yarl import URL
2726

27+
from examples.src.consumer import User, UserConsumer
28+
2829
if TYPE_CHECKING:
2930
from pathlib import Path
3031

@@ -138,5 +139,6 @@ def test_get_unknown_user(pact: Pact, user_consumer: UserConsumer) -> None:
138139
with pact:
139140
with pytest.raises(requests.HTTPError) as excinfo:
140141
user_consumer.get_user(123)
142+
assert excinfo.value.response is not None
141143
assert excinfo.value.response.status_code == HTTPStatus.NOT_FOUND
142144
pact.verify()

examples/tests/test_01_provider_fastapi.py

+5-2
Original file line numberDiff line numberDiff line change
@@ -30,11 +30,12 @@
3030

3131
import pytest
3232
import uvicorn
33-
from examples.src.fastapi import app
3433
from pact import Verifier
3534
from pydantic import BaseModel
3635
from yarl import URL
3736

37+
from examples.src.fastapi import app
38+
3839
PROVIDER_URL = URL("http://localhost:8080")
3940

4041

@@ -78,7 +79,9 @@ def run_server() -> None:
7879
lambda cannot be used as the target of a `multiprocessing.Process` as it
7980
cannot be pickled.
8081
"""
81-
uvicorn.run(app, host=PROVIDER_URL.host, port=PROVIDER_URL.port)
82+
host = PROVIDER_URL.host if PROVIDER_URL.host else "localhost"
83+
port = PROVIDER_URL.port if PROVIDER_URL.port else 8080
84+
uvicorn.run(app, host=host, port=port)
8285

8386

8487
@pytest.fixture(scope="module")

examples/tests/test_01_provider_flask.py

+3-3
Original file line numberDiff line numberDiff line change
@@ -22,19 +22,19 @@
2222
section of the Pact documentation.
2323
"""
2424

25-
2625
from __future__ import annotations
2726

2827
from multiprocessing import Process
2928
from typing import Any, Dict, Generator, Union
3029
from unittest.mock import MagicMock
3130

3231
import pytest
33-
from examples.src.flask import app
3432
from flask import request
3533
from pact import Verifier
3634
from yarl import URL
3735

36+
from examples.src.flask import app
37+
3838
PROVIDER_URL = URL("http://localhost:8080")
3939

4040

@@ -58,7 +58,7 @@ async def mock_pact_provider_states() -> Dict[str, Union[str, None]]:
5858
"user 123 doesn't exist": mock_user_123_doesnt_exist,
5959
"user 123 exists": mock_user_123_exists,
6060
}
61-
return {"result": mapping[request.json["state"]]()}
61+
return {"result": mapping[request.json["state"]]()} # type: ignore[index]
6262

6363

6464
def run_server() -> None:

examples/tests/test_02_message_consumer.py

+7-3
Original file line numberDiff line numberDiff line change
@@ -35,9 +35,10 @@
3535
from unittest.mock import MagicMock
3636

3737
import pytest
38-
from examples.src.message import Handler
3938
from pact import MessageConsumer, MessagePact, Provider
4039

40+
from examples.src.message import Handler
41+
4142
if TYPE_CHECKING:
4243
from pathlib import Path
4344

@@ -116,7 +117,10 @@ def test_write_file(pact: MessagePact, handler: Handler) -> None:
116117
)
117118

118119
result = handler.process(msg)
119-
handler.fs.write.assert_called_once_with("test.txt", "Hello world!")
120+
handler.fs.write.assert_called_once_with( # type: ignore[attr-defined]
121+
"test.txt",
122+
"Hello world!",
123+
)
120124
assert result is None
121125

122126

@@ -130,5 +134,5 @@ def test_read_file(pact: MessagePact, handler: Handler) -> None:
130134
)
131135

132136
result = handler.process(msg)
133-
handler.fs.read.assert_called_once_with("test.txt")
137+
handler.fs.read.assert_called_once_with("test.txt") # type: ignore[attr-defined]
134138
assert result == "Hello world!"

pyproject.toml

+20
Original file line numberDiff line numberDiff line change
@@ -176,8 +176,28 @@ ignore = [
176176
"ANN102", # `cls` must be typed
177177
]
178178

179+
extend-exclude = [
180+
"tests/*.py",
181+
"pact/*.py",
182+
]
183+
179184
[tool.ruff.pyupgrade]
180185
keep-runtime-typing = true
181186

182187
[tool.ruff.pydocstyle]
183188
convention = "google"
189+
190+
################################################################################
191+
## Black Configuration
192+
################################################################################
193+
194+
[tool.black]
195+
target-version = ["py38"]
196+
extend-exclude = '^/(pact|tests)/(?!v3).+\.py$'
197+
198+
################################################################################
199+
## Mypy Configuration
200+
################################################################################
201+
202+
[tool.mypy]
203+
exclude = '^(pact|tests)/(?!v3).+\.py$'

tests/__init__.py

Whitespace-only changes.

tests/v3/__init__.py

Whitespace-only changes.

tests/v3/test_http_interaction.py

+9-3
Original file line numberDiff line numberDiff line change
@@ -407,7 +407,11 @@ def test_with_body_invalid(pact: Pact) -> None:
407407
pact.upon_receiving("")
408408
.with_request("GET", "/")
409409
.will_respond_with(200)
410-
.with_body(json.dumps({"request": True}), "application/json", "Invalid")
410+
.with_body(
411+
json.dumps({"request": True}),
412+
"application/json",
413+
"Invalid", # type: ignore[arg-type]
414+
)
411415
)
412416

413417

@@ -504,11 +508,13 @@ async def test_multipart_file_request(pact: Pact, temp_dir: Path) -> None:
504508
with pact.serve() as srv, aiohttp.MultipartWriter() as mpwriter:
505509
mpwriter.append(
506510
fpy.open("rb"),
507-
{"Content-Type": "text/x-python"},
511+
# TODO: Remove type ignore once aio-libs/aiohttp#7741 is resolved
512+
{"Content-Type": "text/x-python"}, # type: ignore[arg-type]
508513
)
509514
mpwriter.append(
510515
fpng.open("rb"),
511-
{"Content-Type": "image/png"},
516+
# TODO: Remove type ignore once aio-libs/aiohttp#7741 is resolved
517+
{"Content-Type": "image/png"}, # type: ignore[arg-type]
512518
)
513519

514520
async with aiohttp.ClientSession(srv.url) as session, session.post(

0 commit comments

Comments
 (0)