From 27688f9667963a7014cebc467692e0ab63b9b04e Mon Sep 17 00:00:00 2001 From: Jamie Lennox Date: Wed, 20 Apr 2022 17:35:33 +1000 Subject: [PATCH] Improvements to Type Hints I found a number of places where the type hints are either incorrect or not specific enough. Improve or fix warnings as reported by my IDE. --- ...ype-Annotation-Fixes-121a274d75791a61.yaml | 4 + requests_mock/adapter.pyi | 16 ++-- requests_mock/exceptions.pyi | 4 +- requests_mock/mocker.pyi | 85 ++++++++++++------- requests_mock/request.pyi | 2 +- requests_mock/response.py | 3 + requests_mock/response.pyi | 22 +++-- tests/test_response.py | 4 +- 8 files changed, 91 insertions(+), 49 deletions(-) create mode 100644 releasenotes/notes/Type-Annotation-Fixes-121a274d75791a61.yaml diff --git a/releasenotes/notes/Type-Annotation-Fixes-121a274d75791a61.yaml b/releasenotes/notes/Type-Annotation-Fixes-121a274d75791a61.yaml new file mode 100644 index 0000000..2532671 --- /dev/null +++ b/releasenotes/notes/Type-Annotation-Fixes-121a274d75791a61.yaml @@ -0,0 +1,4 @@ +--- +fixes: + - | + A series of type hint fixes, most importantly the register_uri return value is not a response but a usable Matcher object. diff --git a/requests_mock/adapter.pyi b/requests_mock/adapter.pyi index 8570cd7..0aa08ce 100644 --- a/requests_mock/adapter.pyi +++ b/requests_mock/adapter.pyi @@ -2,13 +2,14 @@ from http.cookiejar import CookieJar from io import IOBase -from typing import Any, Callable, Dict, List, NewType, Optional, Pattern, Union +from typing import Any, Callable, Dict, List, NewType, Optional, Pattern, Type, Union +from requests import Request, Response from requests.adapters import BaseAdapter from requests.packages.urllib3.response import HTTPResponse +from requests_mock.request import _RequestObjectProxy from requests_mock.response import _Context -from requests_mock import _RequestObjectProxy AnyMatcher = NewType("AnyMatcher", object) @@ -30,7 +31,7 @@ class _RunRealHTTP(Exception): ... class _Matcher(_RequestHistoryTracker): def __init__(self, method: Any, url: Any, responses: Any, complete_qs: Any, request_headers: Any, additional_matcher: Any, real_http: Any, case_sensitive: Any) -> None: ... - def __call__(self, request: Any) -> Any: ... + def __call__(self, request: Request) -> Optional[Response]: ... class Adapter(BaseAdapter, _RequestHistoryTracker): def __init__(self, case_sensitive: bool = ...) -> None: ... @@ -51,8 +52,9 @@ class Adapter(BaseAdapter, _RequestHistoryTracker): content: Union[bytes, Callable[[_RequestObjectProxy, _Context], bytes]] = ..., body: Union[IOBase, Callable[[_RequestObjectProxy, _Context], IOBase]] = ..., raw: HTTPResponse = ..., - exc: Exception = ..., - additional_matcher: Optional[Callable[[_RequestObjectProxy], bool]] = ..., + exc: Union[Exception, Type[Exception]] = ..., + additional_matcher: Callable[[_RequestObjectProxy], bool] = ..., **kwargs: Any - ) -> Any: ... - def add_matcher(self, matcher: Any) -> None: ... + ) -> _Matcher: ... + def add_matcher(self, matcher: Callable[[Request], Optional[Response]]) -> None: ... + def reset(self) -> None: ... \ No newline at end of file diff --git a/requests_mock/exceptions.pyi b/requests_mock/exceptions.pyi index ae11dd0..eb35447 100644 --- a/requests_mock/exceptions.pyi +++ b/requests_mock/exceptions.pyi @@ -2,10 +2,12 @@ from typing import Any +from requests import Request + class MockException(Exception): ... class NoMockAddress(MockException): request: Any = ... - def __init__(self, request: Any) -> None: ... + def __init__(self, request: Request) -> None: ... class InvalidRequest(MockException): ... diff --git a/requests_mock/mocker.pyi b/requests_mock/mocker.pyi index 747dd1c..83bb34b 100644 --- a/requests_mock/mocker.pyi +++ b/requests_mock/mocker.pyi @@ -4,10 +4,10 @@ from http.cookiejar import CookieJar from io import IOBase from typing import Any, Callable, Dict, List, Optional, Pattern, Type, TypeVar, Union -from requests import Response +from requests import Request, Response, Session from requests.packages.urllib3.response import HTTPResponse -from requests_mock.adapter import AnyMatcher +from requests_mock.adapter import AnyMatcher, _Matcher from requests_mock.request import _RequestObjectProxy from requests_mock.response import _Context @@ -24,7 +24,7 @@ class MockerCore: def __init__(self, **kwargs: Any) -> None: ... def start(self) -> None: ... def stop(self) -> None: ... - def add_matcher(self, matcher: Any) -> None: ... + def add_matcher(self, matcher: Callable[[Request], Optional[Response]]) -> None: ... @property def request_history(self) -> List[_RequestObjectProxy]: ... @property @@ -37,6 +37,7 @@ class MockerCore: def call_count(self) -> int: ... def reset(self) -> None: ... def reset_mock(self) -> None: ... + def register_uri( self, method: Union[str, AnyMatcher], @@ -54,9 +55,11 @@ class MockerCore: content: Union[bytes, Callable[[_RequestObjectProxy, _Context], bytes]] = ..., body: Union[IOBase, Callable[[_RequestObjectProxy, _Context], IOBase]] = ..., raw: HTTPResponse = ..., - exc: Exception = ..., - additional_matcher: Optional[Callable[[_RequestObjectProxy], bool]] = ..., - **kwargs: Any) -> Response: ... + exc: Union[Exception, Type[Exception]] = ..., + additional_matcher: Callable[[_RequestObjectProxy], bool] = ..., + **kwargs: Any, + ) -> _Matcher: ... + def request( self, method: Union[str, AnyMatcher], @@ -74,9 +77,11 @@ class MockerCore: content: Union[bytes, Callable[[_RequestObjectProxy, _Context], bytes]] = ..., body: Union[IOBase, Callable[[_RequestObjectProxy, _Context], IOBase]] = ..., raw: HTTPResponse = ..., - exc: Exception = ..., - additional_matcher: Optional[Callable[[_RequestObjectProxy], bool]] = ..., - **kwargs: Any) -> Response: ... + exc: Union[Exception, Type[Exception]] = ..., + additional_matcher: Callable[[_RequestObjectProxy], bool] = ..., + **kwargs: Any, + ) -> _Matcher: ... + def get( self, url: Union[str, Pattern[str], AnyMatcher], @@ -93,9 +98,11 @@ class MockerCore: content: Union[bytes, Callable[[_RequestObjectProxy, _Context], bytes]] = ..., body: Union[IOBase, Callable[[_RequestObjectProxy, _Context], IOBase]] = ..., raw: HTTPResponse = ..., - exc: Exception = ..., - additional_matcher: Optional[Callable[[_RequestObjectProxy], bool]] = ..., - **kwargs: Any) -> Response: ... + exc: Union[Exception, Type[Exception]] = ..., + additional_matcher: Callable[[_RequestObjectProxy], bool] = ..., + **kwargs: Any, + ) -> _Matcher: ... + def head( self, url: Union[str, Pattern[str], AnyMatcher], @@ -112,9 +119,11 @@ class MockerCore: content: Union[bytes, Callable[[_RequestObjectProxy, _Context], bytes]] = ..., body: Union[IOBase, Callable[[_RequestObjectProxy, _Context], IOBase]] = ..., raw: HTTPResponse = ..., - exc: Exception = ..., - additional_matcher: Optional[Callable[[_RequestObjectProxy], bool]] = ..., - **kwargs: Any) -> Response: ... + exc: Union[Exception, Type[Exception]] = ..., + additional_matcher: Callable[[_RequestObjectProxy], bool] = ..., + **kwargs: Any, + ) -> _Matcher: ... + def options( self, url: Union[str, Pattern[str], AnyMatcher], @@ -131,9 +140,11 @@ class MockerCore: content: Union[bytes, Callable[[_RequestObjectProxy, _Context], bytes]] = ..., body: Union[IOBase, Callable[[_RequestObjectProxy, _Context], IOBase]] = ..., raw: HTTPResponse = ..., - exc: Exception = ..., - additional_matcher: Optional[Callable[[_RequestObjectProxy], bool]] = ..., - **kwargs: Any) -> Response: ... + exc: Union[Exception, Type[Exception]] = ..., + additional_matcher: Callable[[_RequestObjectProxy], bool] = ..., + **kwargs: Any, + ) -> _Matcher: ... + def post( self, url: Union[str, Pattern[str], AnyMatcher], @@ -150,9 +161,11 @@ class MockerCore: content: Union[bytes, Callable[[_RequestObjectProxy, _Context], bytes]] = ..., body: Union[IOBase, Callable[[_RequestObjectProxy, _Context], IOBase]] = ..., raw: HTTPResponse = ..., - exc: Exception = ..., - additional_matcher: Optional[Callable[[_RequestObjectProxy], bool]] = ..., - **kwargs: Any) -> Response: ... + exc: Union[Exception, Type[Exception]] = ..., + additional_matcher: Callable[[_RequestObjectProxy], bool] = ..., + **kwargs: Any, + ) -> _Matcher: ... + def put( self, url: Union[str, Pattern[str], AnyMatcher], @@ -169,9 +182,11 @@ class MockerCore: content: Union[bytes, Callable[[_RequestObjectProxy, _Context], bytes]] = ..., body: Union[IOBase, Callable[[_RequestObjectProxy, _Context], IOBase]] = ..., raw: HTTPResponse = ..., - exc: Exception = ..., - additional_matcher: Optional[Callable[[_RequestObjectProxy], bool]] = ..., - **kwargs: Any) -> Response: ... + exc: Union[Exception, Type[Exception]] = ..., + additional_matcher: Callable[[_RequestObjectProxy], bool] = ..., + **kwargs: Any, + ) -> _Matcher: ... + def patch( self, url: Union[str, Pattern[str], AnyMatcher], @@ -188,9 +203,11 @@ class MockerCore: content: Union[bytes, Callable[[_RequestObjectProxy, _Context], bytes]] = ..., body: Union[IOBase, Callable[[_RequestObjectProxy, _Context], IOBase]] = ..., raw: HTTPResponse = ..., - exc: Exception = ..., - additional_matcher: Optional[Callable[[_RequestObjectProxy], bool]] = ..., - **kwargs: Any) -> Response: ... + exc: Union[Exception, Type[Exception]] = ..., + additional_matcher: Callable[[_RequestObjectProxy], bool] = ..., + **kwargs: Any, + ) -> _Matcher: ... + def delete( self, url: Union[str, Pattern[str], AnyMatcher], @@ -207,24 +224,30 @@ class MockerCore: content: Union[bytes, Callable[[_RequestObjectProxy, _Context], bytes]] = ..., body: Union[IOBase, Callable[[_RequestObjectProxy, _Context], IOBase]] = ..., raw: HTTPResponse = ..., - exc: Exception = ..., - additional_matcher: Optional[Callable[[_RequestObjectProxy], bool]] = ..., - **kwargs: Any) -> Response: ... + exc: Union[Exception, Type[Exception]] = ..., + additional_matcher: Callable[[_RequestObjectProxy], bool] = ..., + **kwargs: Any, + ) -> _Matcher: ... _T = TypeVar('_T') class Mocker(MockerCore): TEST_PREFIX: str = ... + real_http: bool = ... + def __init__( self, kw: str = ..., case_sensitive: bool = ..., adapter: Any = ..., - real_http: bool = ...) -> None: ... + session: Optional[Session] = ..., + real_http: bool = ...) -> None: + ... def __enter__(self) -> Any: ... def __exit__(self, type: Any, value: Any, traceback: Any) -> None: ... def __call__(self, obj: Any) -> Any: ... def copy(self) -> Mocker: ... def decorate_callable(self, func: Callable[..., _T]) -> Callable[..., _T]: ... def decorate_class(self, klass: Type[_T]) -> Type[_T]: ... + mock = Mocker diff --git a/requests_mock/request.pyi b/requests_mock/request.pyi index fceb99c..63de19e 100644 --- a/requests_mock/request.pyi +++ b/requests_mock/request.pyi @@ -35,4 +35,4 @@ class _RequestObjectProxy: def text(self) -> str: ... def json(self, **kwargs: Any) -> Any: ... @property - def matcher(self) -> Any: ... + def matcher(self) -> Any: ... \ No newline at end of file diff --git a/requests_mock/response.py b/requests_mock/response.py index 6f04773..4219081 100644 --- a/requests_mock/response.py +++ b/requests_mock/response.py @@ -149,6 +149,9 @@ def create_response(request, **kwargs): returned upon a successful match. :param CookieJar cookies: A cookie jar with cookies to set on the response. + + :returns requests.Response: A response object that can + be returned to requests. """ connection = kwargs.pop('connection', _FakeConnection()) diff --git a/requests_mock/response.pyi b/requests_mock/response.pyi index c979215..575b721 100644 --- a/requests_mock/response.pyi +++ b/requests_mock/response.pyi @@ -1,8 +1,11 @@ # Stubs for requests_mock.response +from typing import Any, Dict, Optional + import six + +from requests import Request, Response from requests.cookies import RequestsCookieJar -from typing import Any class CookieJar(RequestsCookieJar): def set(self, name: Any, value: Any, **kwargs: Any) -> Any: ... @@ -14,15 +17,20 @@ class _FakeConnection: class _IOReader(six.BytesIO): def read(self, *args: Any, **kwargs: Any) -> Any: ... -def create_response(request: Any, **kwargs: Any) -> Any: ... +def create_response(request: Any, **kwargs: Any) -> Response: ... class _Context: - headers: Any = ... - status_code: Any = ... - reason: Any = ... + headers: Dict[str,str] = ... + status_code: int = ... + reason: str = ... cookies: Any = ... - def __init__(self, headers: Any, status_code: Any, reason: Any, cookies: Any) -> None: ... + + def __init__(self, + headers: Dict[str, str], + status_code: int, + reason: str, + cookies: Any) -> None: ... class _MatcherResponse: def __init__(self, **kwargs: Any) -> None: ... - def get_response(self, request: Any) -> Any: ... + def get_response(self, request: Request) -> Response: ... diff --git a/tests/test_response.py b/tests/test_response.py index 066ac31..2dc11c8 100644 --- a/tests/test_response.py +++ b/tests/test_response.py @@ -13,8 +13,8 @@ import pickle import six -from requests_mock import adapter from requests_mock import exceptions +from requests_mock import request from requests_mock import response from . import base @@ -25,7 +25,7 @@ def setUp(self): super(ResponseTests, self).setUp() self.method = 'GET' self.url = 'http://test.url/path' - self.request = adapter._RequestObjectProxy._create(self.method, + self.request = request._RequestObjectProxy._create(self.method, self.url, {})