Skip to content

Commit

Permalink
chore: fix ruff lints
Browse files Browse the repository at this point in the history
Due to an upstream bug in `ruff`, all Python files were inadvertently
ignored instead of just the `v2` code. As a result, lint errors have
been accummulating.

Signed-off-by: JP-Ellis <josh@jpellis.me>
  • Loading branch information
JP-Ellis committed Nov 6, 2023
1 parent 7b9b1d3 commit d1724bf
Show file tree
Hide file tree
Showing 7 changed files with 110 additions and 76 deletions.
29 changes: 19 additions & 10 deletions pact/v3/ffi.py
Original file line number Diff line number Diff line change
Expand Up @@ -90,8 +90,9 @@
from ._ffi import ffi, lib # type: ignore[import]

if TYPE_CHECKING:
import cffi
from pathlib import Path

import cffi
from typing_extensions import Self

# The follow types are classes defined in the Rust code. Ultimately, a Python
Expand Down Expand Up @@ -814,6 +815,8 @@ class OwnedString(str):
in most cases.
"""

__slots__ = ("_ptr", "_string")

def __new__(cls, ptr: cffi.FFI.CData) -> Self:
"""
Create a new Owned String.
Expand Down Expand Up @@ -3000,7 +3003,7 @@ def pact_message_iter_next(iter: PactMessageIterator) -> Message:
ptr = lib.pactffi_pact_message_iter_next(iter._ptr)
if ptr == ffi.NULL:
raise StopIteration
raise NotImplementedError()
raise NotImplementedError
return Message(ptr)


Expand All @@ -3014,7 +3017,7 @@ def pact_sync_message_iter_next(iter: PactSyncMessageIterator) -> SynchronousMes
ptr = lib.pactffi_pact_sync_message_iter_next(iter._ptr)
if ptr == ffi.NULL:
raise StopIteration
raise NotImplementedError()
raise NotImplementedError
return SynchronousMessage(ptr)


Expand All @@ -3038,7 +3041,7 @@ def pact_sync_http_iter_next(iter: PactSyncHttpIterator) -> SynchronousHttp:
ptr = lib.pactffi_pact_sync_http_iter_next(iter._ptr)
if ptr == ffi.NULL:
raise StopIteration
raise NotImplementedError()
raise NotImplementedError
return SynchronousHttp(ptr)


Expand All @@ -3062,7 +3065,7 @@ def pact_interaction_iter_next(iter: PactInteractionIterator) -> PactInteraction
ptr = lib.pactffi_pact_interaction_iter_next(iter._ptr)
if ptr == ffi.NULL:
raise StopIteration
raise NotImplementedError()
raise NotImplementedError
return PactInteraction(ptr)


Expand Down Expand Up @@ -5693,7 +5696,7 @@ def pact_handle_get_sync_message_iter(pact: PactHandle) -> PactSyncMessageIterat
('\0') bytes.
"""
return PactSyncMessageIterator(
lib.pactffi_pact_handle_get_sync_message_iter(pact._ref)
lib.pactffi_pact_handle_get_sync_message_iter(pact._ref),
)


Expand Down Expand Up @@ -5929,6 +5932,9 @@ def pact_handle_write_file(
This function should be called if all the consumer tests have passed.
Args:
pact:
Handle to a Pact model.
directory:
The directory to write the file to. If `None`, the current working
directory is used.
Expand All @@ -5947,9 +5953,9 @@ def pact_handle_write_file(
return
if ret == 1:
msg = f"The function panicked while writing {pact} to {directory}."
elif ret == 2:
elif ret == 2: # noqa: PLR2004
msg = f"The pact file was not able to be written for {pact}."
elif ret == 3:
elif ret == 3: # noqa: PLR2004
msg = f"The pact for {pact} was not found."
else:
msg = f"Unknown error writing {pact} to {directory}."
Expand Down Expand Up @@ -6616,6 +6622,9 @@ def using_plugin(
`pactffi_using_plugin`](https://docs.rs/pact_ffi/0.4.9/pact_ffi/?search=pactffi_using_plugin)
Args:
pact:
Handle to a Pact model.
plugin_name:
Name of the plugin to use.
Expand All @@ -6632,9 +6641,9 @@ def using_plugin(
return
if ret == 1:
msg = f"A general panic was caught: {get_error_message()}"
elif ret == 2:
elif ret == 2: # noqa: PLR2004
msg = f"Failed to load the plugin {plugin_name}."
elif ret == 3:
elif ret == 3: # noqa: PLR2004
msg = f"The Pact handle {pact} is invalid."
else:
msg = f"There was an unknown error loading the plugin {plugin_name}."
Expand Down
46 changes: 28 additions & 18 deletions pact/v3/pact.py
Original file line number Diff line number Diff line change
Expand Up @@ -1108,6 +1108,13 @@ def serve(
transport_config:
Configuration for the transport. This is specific to the
transport being used and should be a JSON string.
raises: Whether to raise an exception if there are mismatches
between the Pact and the server. If set to `False`, then the
mismatches must be handled manually.
Returns:
A [`PactServer`][pact.v3.pact.PactServer] instance.
"""
return PactServer(
self._handle,
Expand Down Expand Up @@ -1139,21 +1146,23 @@ def messages(self) -> pact.v3.ffi.PactMessageIterator:
return pact.v3.ffi.pact_handle_get_message_iter(self._handle)

@overload
def interactions(self, type: Literal["HTTP"]) -> pact.v3.ffi.PactSyncHttpIterator:
def interactions(self, kind: Literal["HTTP"]) -> pact.v3.ffi.PactSyncHttpIterator:
...

@overload
def interactions(
self, type: Literal["Sync"]
self,
kind: Literal["Sync"],
) -> pact.v3.ffi.PactSyncMessageIterator:
...

@overload
def interactions(self, type: Literal["Async"]) -> pact.v3.ffi.PactMessageIterator:
def interactions(self, kind: Literal["Async"]) -> pact.v3.ffi.PactMessageIterator:
...

def interactions(
self, type: str = "HTTP"
self,
kind: str = "HTTP",
) -> (
pact.v3.ffi.PactSyncHttpIterator
| pact.v3.ffi.PactSyncMessageIterator
Expand All @@ -1162,30 +1171,26 @@ def interactions(
"""
Return an iterator over the Pact's interactions.
The type is used to specify the kind of interactions that will be
iterated over. If `"All"` is specified (the default), then all
interactions will be iterated over.
The kind is used to specify the type of interactions that will be
iterated over.
"""
# TODO: The FFI does not have a way to iterate over all interactions, unless
# you have a pointer to the pact. See
# pact-foundation/pact-reference#333.
# if type == "All":
# return pact.v3.ffi.pact_model_interaction_iterator(self._handle)
if type == "HTTP":
# TODO(JP-Ellis): Add an iterator for `All` interactions.
# https://github.com/pact-foundation/pact-python/issues/451
if kind == "HTTP":
return pact.v3.ffi.pact_handle_get_sync_http_iter(self._handle)
if type == "Sync":
if kind == "Sync":
return pact.v3.ffi.pact_handle_get_sync_message_iter(self._handle)
if type == "Async":
if kind == "Async":
return pact.v3.ffi.pact_handle_get_message_iter(self._handle)
msg = f"Unknown interaction type: {type}"
msg = f"Unknown interaction type: {kind}"
raise ValueError(msg)

def write_file(
self,
directory: Path | str = Path.cwd(),
directory: Path | str | None = None,
*,
overwrite: bool = False,
):
) -> None:
"""
Write out the pact to a file.
Expand All @@ -1204,6 +1209,8 @@ def write_file(
exists. Otherwise, the contents of the file will be merged with
the existing file.
"""
if directory is None:
directory = Path.cwd()
pact.v3.ffi.pact_handle_write_file(
self._handle,
directory,
Expand Down Expand Up @@ -1259,6 +1266,9 @@ def __init__( # noqa: PLR0913
transport_config:
Configuration for the transport. This is specific to the
transport being used and should be a JSON string.
raises: Whether or not to raise an exception if the server is not
matched upon exit.
"""
self._host = host
self._port = port
Expand Down
39 changes: 38 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -175,9 +175,46 @@ ignore = [
"D212", # Multi-line docstring summary must start at the first line
"ANN101", # `self` must be typed
"ANN102", # `cls` must be typed
"FIX002", # Forbid TODO in comments
]

extend-exclude = ["tests/*.py", "pact/*.py"]
# TODO: Remove the explicity extend-exclude once astral-sh/ruff#6262 is fixed.
# https://github.com/pact-foundation/pact-python/issues/458
extend-exclude = [
# "pact/*.py",
# "pact/cli/*.py",
# "tests/*.py",
# "tests/cli/*.py",
"pact/__init__.py",
"pact/__version__.py",
"pact/broker.py",
"pact/cli/*.py",
"pact/constants.py",
"pact/consumer.py",
"pact/http_proxy.py",
"pact/matchers.py",
"pact/message_consumer.py",
"pact/message_pact.py",
"pact/message_provider.py",
"pact/pact.py",
"pact/provider.py",
"pact/verifier.py",
"pact/verify_wrapper.py",
"tests/__init__.py",
"tests/cli/*.py",
"tests/conftest.py",
"tests/test_broker.py",
"tests/test_constants.py",
"tests/test_consumer.py",
"tests/test_http_proxy.py",
"tests/test_matchers.py",
"tests/test_message_consumer.py",
"tests/test_message_pact.py",
"tests/test_message_provider.py",
"tests/test_pact.py",
"tests/test_verifier.py",
"tests/test_verify_wrapper.py",
]

[tool.ruff.pyupgrade]
keep-runtime-typing = true
Expand Down
3 changes: 3 additions & 0 deletions tests/v3/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
"""
Pact Python v3 tests.
"""
2 changes: 1 addition & 1 deletion tests/v3/test_ffi.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,5 +65,5 @@ def test_owned_string() -> None:
(
"-----END CERTIFICATE-----\n",
"-----END CERTIFICATE-----\r\n",
)
),
)
50 changes: 12 additions & 38 deletions tests/v3/test_http_interaction.py
Original file line number Diff line number Diff line change
Expand Up @@ -105,11 +105,7 @@ async def test_with_header_request(
)
with pact.serve() as srv:
async with aiohttp.ClientSession(srv.url) as session:
async with session.request(
"GET",
"/",
headers=headers,
) as resp:
async with session.request("GET", "/", headers=headers) as resp:
assert resp.status == 200


Expand All @@ -134,10 +130,7 @@ async def test_with_header_response(
)
with pact.serve() as srv:
async with aiohttp.ClientSession(srv.url) as session:
async with session.request(
"GET",
"/",
) as resp:
async with session.request("GET", "/") as resp:
assert resp.status == 200
response_headers = [(h.lower(), v) for h, v in resp.headers.items()]
for header, value in headers:
Expand Down Expand Up @@ -182,11 +175,7 @@ async def test_set_header_request(
)
with pact.serve() as srv:
async with aiohttp.ClientSession(srv.url) as session:
async with session.request(
"GET",
"/",
headers=headers,
) as resp:
async with session.request("GET", "/", headers=headers) as resp:
assert resp.status == 200


Expand All @@ -205,11 +194,7 @@ async def test_set_header_request_repeat(
)
with pact.serve() as srv:
async with aiohttp.ClientSession(srv.url) as session:
async with session.request(
"GET",
"/",
headers=headers,
) as resp:
async with session.request("GET", "/", headers=headers) as resp:
assert resp.status == 500


Expand All @@ -233,10 +218,7 @@ async def test_set_header_response(
)
with pact.serve() as srv:
async with aiohttp.ClientSession(srv.url) as session:
async with session.request(
"GET",
"/",
) as resp:
async with session.request("GET", "/") as resp:
assert resp.status == 200
response_headers = [(h.lower(), v) for h, v in resp.headers.items()]
for header, value in headers:
Expand All @@ -258,11 +240,7 @@ async def test_set_header_response_repeat(
)
with pact.serve() as srv:
async with aiohttp.ClientSession(srv.url) as session:
async with session.request(
"GET",
"/",
headers=headers,
) as resp:
async with session.request("GET", "/", headers=headers) as resp:
assert resp.status == 200
response_headers = [(h.lower(), v) for h, v in resp.headers.items()]
assert ("x-test", "2") in response_headers
Expand Down Expand Up @@ -309,10 +287,7 @@ async def test_with_query_parameter_request(
with pact.serve() as srv:
async with aiohttp.ClientSession(srv.url) as session:
url = srv.url.with_query(query)
async with session.request(
"GET",
url.path_qs,
) as resp:
async with session.request("GET", url.path_qs) as resp:
assert resp.status == 200


Expand All @@ -327,10 +302,7 @@ async def test_with_query_parameter_dict(pact: Pact) -> None:
with pact.serve() as srv:
async with aiohttp.ClientSession(srv.url) as session:
url = srv.url.with_query({"test": "true", "foo": "bar"})
async with session.request(
"GET",
url.path_qs,
) as resp:
async with session.request("GET", url.path_qs) as resp:
assert resp.status == 200


Expand Down Expand Up @@ -508,12 +480,14 @@ async def test_multipart_file_request(pact: Pact, temp_dir: Path) -> None:
with pact.serve() as srv, aiohttp.MultipartWriter() as mpwriter:
mpwriter.append(
fpy.open("rb"),
# TODO: Remove type ignore once aio-libs/aiohttp#7741 is resolved
# TODO(JP-Ellis): Remove type ignore once aio-libs/aiohttp#7741 is resolved
# https://github.com/pact-foundation/pact-python/issues/450
{"Content-Type": "text/x-python"}, # type: ignore[arg-type]
)
mpwriter.append(
fpng.open("rb"),
# TODO: Remove type ignore once aio-libs/aiohttp#7741 is resolved
# TODO(JP-Ellis): Remove type ignore once aio-libs/aiohttp#7741 is resolved
# https://github.com/pact-foundation/pact-python/issues/450
{"Content-Type": "image/png"}, # type: ignore[arg-type]
)

Expand Down
Loading

0 comments on commit d1724bf

Please sign in to comment.