11from json import dumps as json_dumps
22from json import loads as json_loads
3- from typing import Any , Callable , Dict , List , Optional , Tuple , Union
3+ from typing import (
4+ Any ,
5+ Awaitable ,
6+ Callable ,
7+ Dict ,
8+ Generic ,
9+ List ,
10+ Optional ,
11+ Tuple ,
12+ TypeVar ,
13+ Union ,
14+ cast ,
15+ )
416from unittest .mock import Mock
517from urllib .parse import urljoin
618
1123from ninja .responses import NinjaJSONEncoder
1224from ninja .responses import Response as HttpResponse
1325
26+ ResponseT = TypeVar ("ResponseT" )
27+
1428
1529def build_absolute_uri (location : Optional [str ] = None ) -> str :
1630 base = "http://testlocation/"
@@ -23,7 +37,7 @@ def build_absolute_uri(location: Optional[str] = None) -> str:
2337
2438# TODO: this should be changed
2539# maybe add here urlconf object and add urls from here
26- class NinjaClientBase :
40+ class NinjaClientBase ( Generic [ ResponseT ]) :
2741 __test__ = False # <- skip pytest
2842
2943 def __init__ (
@@ -38,7 +52,7 @@ def __init__(
3852
3953 def get (
4054 self , path : str , data : Optional [Dict ] = None , ** request_params : Any
41- ) -> "NinjaResponse" :
55+ ) -> ResponseT :
4256 return self .request ("GET" , path , data , ** request_params )
4357
4458 def post (
@@ -47,7 +61,7 @@ def post(
4761 data : Optional [Dict ] = None ,
4862 json : Any = None ,
4963 ** request_params : Any ,
50- ) -> "NinjaResponse" :
64+ ) -> ResponseT :
5165 return self .request ("POST" , path , data , json , ** request_params )
5266
5367 def patch (
@@ -56,7 +70,7 @@ def patch(
5670 data : Optional [Dict ] = None ,
5771 json : Any = None ,
5872 ** request_params : Any ,
59- ) -> "NinjaResponse" :
73+ ) -> ResponseT :
6074 return self .request ("PATCH" , path , data , json , ** request_params )
6175
6276 def put (
@@ -65,7 +79,7 @@ def put(
6579 data : Optional [Dict ] = None ,
6680 json : Any = None ,
6781 ** request_params : Any ,
68- ) -> "NinjaResponse" :
82+ ) -> ResponseT :
6983 return self .request ("PUT" , path , data , json , ** request_params )
7084
7185 def delete (
@@ -74,7 +88,7 @@ def delete(
7488 data : Optional [Dict ] = None ,
7589 json : Any = None ,
7690 ** request_params : Any ,
77- ) -> "NinjaResponse" :
91+ ) -> ResponseT :
7892 return self .request ("DELETE" , path , data , json , ** request_params )
7993
8094 def request (
@@ -84,7 +98,7 @@ def request(
8498 data : Optional [Dict ] = None ,
8599 json : Any = None ,
86100 ** request_params : Any ,
87- ) -> "NinjaResponse" :
101+ ) -> ResponseT :
88102 if json is not None :
89103 request_params ["body" ] = json_dumps (json , cls = NinjaJSONEncoder )
90104 if data is None :
@@ -186,12 +200,12 @@ def _build_request(
186200 return request
187201
188202
189- class TestClient (NinjaClientBase ):
203+ class TestClient (NinjaClientBase [ "NinjaResponse" ] ):
190204 def _call (self , func : Callable , request : Mock , kwargs : Dict ) -> "NinjaResponse" :
191205 return NinjaResponse (func (request , ** kwargs ))
192206
193207
194- class TestAsyncClient (NinjaClientBase ):
208+ class TestAsyncClient (NinjaClientBase [ Awaitable [ "NinjaResponse" ]] ):
195209 async def _call (
196210 self , func : Callable , request : Mock , kwargs : Dict
197211 ) -> "NinjaResponse" :
@@ -206,7 +220,7 @@ def __init__(self, http_response: Union[HttpResponse, StreamingHttpResponse]):
206220 if self .streaming :
207221 self .content = b"" .join (http_response .streaming_content ) # type: ignore
208222 else :
209- self .content = http_response .content
223+ self .content = cast ( HttpResponse , http_response ) .content
210224 self ._data = None
211225
212226 def json (self ) -> Any :
0 commit comments