Skip to content

Commit 5a0d3d8

Browse files
committed
chore: fix compatibility with 3.9, 3.10
The `typing.Self` annotation was only introduced in Python 3.11, and therefore we have to rely on the typing extensions for versions 3.9 and 3.10. There are also issues with TypeAliases and the use of the `|` operator. Signed-off-by: JP-Ellis <josh@jpellis.me>
1 parent 3c4359b commit 5a0d3d8

File tree

4 files changed

+16
-11
lines changed

4 files changed

+16
-11
lines changed

src/pact/v3/_server.py

+3-1
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,11 @@
2828
from collections.abc import Callable
2929
from http.server import SimpleHTTPRequestHandler, ThreadingHTTPServer
3030
from threading import Thread
31-
from typing import TYPE_CHECKING, Any, Generic, Self, TypeVar
31+
from typing import TYPE_CHECKING, Any, Generic, TypeVar
3232
from urllib.parse import urlparse
3333

34+
from typing_extensions import Self
35+
3436
from pact import __version__
3537
from pact.v3._util import find_free_port
3638

src/pact/v3/types.py

+8-8
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
from __future__ import annotations
1010

1111
from collections.abc import Callable
12-
from typing import Any, TypedDict
12+
from typing import Any, Optional, TypedDict, Union
1313

1414
from typing_extensions import TypeAlias
1515
from yarl import URL
@@ -57,7 +57,7 @@ class Message(TypedDict):
5757
"""
5858

5959

60-
MessageProducerFull: TypeAlias = Callable[[str, dict[str, Any] | None], Message]
60+
MessageProducerFull: TypeAlias = Callable[[str, Optional[dict[str, Any]]], Message]
6161
"""
6262
Full message producer signature.
6363
@@ -69,7 +69,7 @@ class Message(TypedDict):
6969
The function must return a `bytes` object.
7070
"""
7171

72-
MessageProducerNoName: TypeAlias = Callable[[dict[str, Any] | None], Message]
72+
MessageProducerNoName: TypeAlias = Callable[[Optional[dict[str, Any]]], Message]
7373
"""
7474
Message producer signature without the name.
7575
@@ -83,7 +83,7 @@ class Message(TypedDict):
8383
functions.
8484
"""
8585

86-
StateHandlerFull: TypeAlias = Callable[[str, str, dict[str, Any] | None], None]
86+
StateHandlerFull: TypeAlias = Callable[[str, str, Optional[dict[str, Any]]], None]
8787
"""
8888
Full state handler signature.
8989
@@ -93,7 +93,7 @@ class Message(TypedDict):
9393
2. The action (either `setup` or `teardown`), as a string.
9494
3. A dictionary of parameters, or `None` if no parameters are provided.
9595
"""
96-
StateHandlerNoAction: TypeAlias = Callable[[str, dict[str, Any] | None], None]
96+
StateHandlerNoAction: TypeAlias = Callable[[str, Optional[dict[str, Any]]], None]
9797
"""
9898
State handler signature without the action.
9999
@@ -102,7 +102,7 @@ class Message(TypedDict):
102102
1. The state name, as a string.
103103
2. A dictionary of parameters, or `None` if no parameters are provided.
104104
"""
105-
StateHandlerNoState: TypeAlias = Callable[[str, dict[str, Any] | None], None]
105+
StateHandlerNoState: TypeAlias = Callable[[str, Optional[dict[str, Any]]], None]
106106
"""
107107
State handler signature without the state.
108108
@@ -114,7 +114,7 @@ class Message(TypedDict):
114114
This function must be provided as part of a dictionary mapping state names to
115115
functions.
116116
"""
117-
StateHandlerNoActionNoState: TypeAlias = Callable[[dict[str, Any] | None], None]
117+
StateHandlerNoActionNoState: TypeAlias = Callable[[Optional[dict[str, Any]]], None]
118118
"""
119119
State handler signature without the state or action.
120120
@@ -125,7 +125,7 @@ class Message(TypedDict):
125125
This function must be provided as part of a dictionary mapping state names to
126126
functions.
127127
"""
128-
StateHandlerUrl: TypeAlias = str | URL
128+
StateHandlerUrl: TypeAlias = Union[str, URL]
129129
"""
130130
State handler URL signature.
131131

src/pact/v3/verifier.py

+3-1
Original file line numberDiff line numberDiff line change
@@ -573,7 +573,9 @@ def state_handler(
573573
providing one or more handler functions; and it must be set to
574574
a boolean if providing a URL.
575575
"""
576-
if isinstance(handler, StateHandlerUrl):
576+
# A tuple is required instead of `StateHandlerUrl` for support for
577+
# Python 3.9. This should be changed to `StateHandlerUrl` in the future.
578+
if isinstance(handler, (str, URL)):
577579
if body is None:
578580
msg = "The `body` parameter must be a boolean when providing a URL"
579581
raise ValueError(msg)

tests/v3/compatibility_suite/util/provider.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -26,13 +26,14 @@
2626
from http.server import SimpleHTTPRequestHandler, ThreadingHTTPServer
2727
from io import BytesIO
2828
from threading import Thread
29-
from typing import TYPE_CHECKING, Any, ClassVar, Self, TypedDict
29+
from typing import TYPE_CHECKING, Any, ClassVar, TypedDict
3030
from unittest.mock import MagicMock
3131

3232
import pytest
3333
import requests
3434
from multidict import CIMultiDict
3535
from pytest_bdd import given, parsers, then, when
36+
from typing_extensions import Self
3637
from yarl import URL
3738

3839
import pact.constants # type: ignore[import-untyped]

0 commit comments

Comments
 (0)