Browse Source

Intermediate changes

robot-piglet 1 year ago
parent
commit
e92c0cb46c

+ 1 - 1
contrib/python/responses/py3/.dist-info/METADATA

@@ -1,6 +1,6 @@
 Metadata-Version: 2.1
 Name: responses
-Version: 0.24.0
+Version: 0.24.1
 Summary: A utility library for mocking out the `requests` Python library.
 Home-page: https://github.com/getsentry/responses
 Author: David Cramer

+ 56 - 11
contrib/python/responses/py3/responses/__init__.py

@@ -1,9 +1,6 @@
-import http
 import inspect
 import json as json_module
 import logging
-import socket
-from collections import namedtuple
 from functools import partialmethod
 from functools import wraps
 from http import client
@@ -18,12 +15,14 @@ from typing import Iterable
 from typing import Iterator
 from typing import List
 from typing import Mapping
+from typing import NamedTuple
 from typing import Optional
 from typing import Sequence
 from typing import Sized
 from typing import Tuple
 from typing import Type
 from typing import Union
+from typing import overload
 from warnings import warn
 
 import yaml
@@ -96,7 +95,11 @@ if TYPE_CHECKING:  # pragma: no cover
     ]
 
 
-Call = namedtuple("Call", ["request", "response"])
+class Call(NamedTuple):
+    request: "PreparedRequest"
+    response: "_Body"
+
+
 _real_send = HTTPAdapter.send
 _UNSET = object()
 
@@ -241,6 +244,14 @@ class CallList(Sequence[Any], Sized):
     def __len__(self) -> int:
         return len(self._calls)
 
+    @overload
+    def __getitem__(self, idx: int) -> Call:
+        ...
+
+    @overload
+    def __getitem__(self, idx: slice) -> List[Call]:
+        ...
+
     def __getitem__(self, idx: Union[int, slice]) -> Union[Call, List[Call]]:
         return self._calls[idx]
 
@@ -392,6 +403,9 @@ class BaseResponse:
         self._calls: CallList = CallList()
         self.passthrough = passthrough
 
+        self.status: int = 200
+        self.body: "_Body" = ""
+
     def __eq__(self, other: Any) -> bool:
         if not isinstance(other, BaseResponse):
             return False
@@ -519,25 +533,38 @@ def _form_response(
     headers: Optional[Mapping[str, str]],
     status: int,
 ) -> HTTPResponse:
-    dummy_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
-    orig_response = http.client.HTTPResponse(sock=dummy_socket)
     """
+    Function to generate `urllib3.response.HTTPResponse` object.
+
     The cookie handling functionality of the `requests` library relies on the response object
     having an original response object with the headers stored in the `msg` attribute.
     Instead of supplying a file-like object of type `HTTPMessage` for the headers, we provide
     the headers directly. This approach eliminates the need to parse the headers into a file-like
     object and then rely on the library to unparse it back. These additional conversions can
     introduce potential errors.
-    Therefore, we intentionally ignore type checking for this assignment.
     """
-    orig_response.msg = headers  # type: ignore[assignment]
 
+    data = BytesIO()
+    data.close()
+
+    """
+    The type `urllib3.response.HTTPResponse` is incorrect; we should
+    use `http.client.HTTPResponse` instead. However, changing this requires opening
+    a real socket to imitate the object. This may not be desired, as some users may
+    want to completely restrict network access in their tests.
+    See https://github.com/getsentry/responses/issues/691
+    """
+    orig_response = HTTPResponse(
+        body=data,  # required to avoid "ValueError: Unable to determine whether fp is closed."
+        msg=headers,  # type: ignore[arg-type]
+        preload_content=False,
+    )
     return HTTPResponse(
         status=status,
         reason=client.responses.get(status, None),
         body=body,
         headers=headers,
-        original_response=orig_response,
+        original_response=orig_response,  # type: ignore[arg-type]  # See comment above
         preload_content=False,
     )
 
@@ -556,6 +583,8 @@ class Response(BaseResponse):
         auto_calculate_content_length: bool = False,
         **kwargs: Any,
     ) -> None:
+        super().__init__(method, url, **kwargs)
+
         # if we were passed a `json` argument,
         # override the body and content_type
         if json is not None:
@@ -583,7 +612,6 @@ class Response(BaseResponse):
         self.stream: Optional[bool] = stream
         self.content_type: str = content_type  # type: ignore[assignment]
         self.auto_calculate_content_length: bool = auto_calculate_content_length
-        super().__init__(method, url, **kwargs)
 
     def get_response(self, request: "PreparedRequest") -> HTTPResponse:
         if self.body and isinstance(self.body, Exception):
@@ -628,6 +656,8 @@ class CallbackResponse(BaseResponse):
         content_type: Optional[str] = "text/plain",
         **kwargs: Any,
     ) -> None:
+        super().__init__(method, url, **kwargs)
+
         self.callback = callback
 
         if stream is not None:
@@ -637,7 +667,6 @@ class CallbackResponse(BaseResponse):
             )
         self.stream: Optional[bool] = stream
         self.content_type: Optional[str] = content_type
-        super().__init__(method, url, **kwargs)
 
     def get_response(self, request: "PreparedRequest") -> HTTPResponse:
         headers = self.get_headers()
@@ -957,6 +986,22 @@ class RequestsMock:
             self.reset()
         return success
 
+    @overload
+    def activate(self, func: "_F" = ...) -> "_F":
+        """Overload for scenario when 'responses.activate' is used."""
+
+    @overload
+    def activate(  # type: ignore[misc]
+        self,
+        *,
+        registry: Type[Any] = ...,
+        assert_all_requests_are_fired: bool = ...,
+    ) -> Callable[["_F"], "_F"]:
+        """Overload for scenario when
+        'responses.activate(registry=, assert_all_requests_are_fired=True)' is used.
+        See https://github.com/getsentry/responses/pull/469 for more details
+        """
+
     def activate(
         self,
         func: Optional["_F"] = None,

+ 2 - 2
contrib/python/responses/py3/responses/_recorder.py

@@ -50,8 +50,8 @@ def _dump(
                     "response": {
                         "method": rsp.method,
                         "url": rsp.url,
-                        "body": rsp.body,  # type: ignore[attr-defined]
-                        "status": rsp.status,  # type: ignore[attr-defined]
+                        "body": rsp.body,
+                        "status": rsp.status,
                         "headers": rsp.headers,
                         "content_type": rsp.content_type,
                         "auto_calculate_content_length": content_length,

+ 2 - 1
contrib/python/responses/py3/responses/matchers.py

@@ -7,6 +7,7 @@ from typing import Callable
 from typing import Dict
 from typing import List
 from typing import Optional
+from typing import Pattern
 from typing import Tuple
 from typing import Union
 from urllib.parse import parse_qsl
@@ -391,7 +392,7 @@ def multipart_matcher(
 
 
 def header_matcher(
-    headers: Dict[str, str], strict_match: bool = False
+    headers: Dict[str, Union[str, Pattern[str]]], strict_match: bool = False
 ) -> Callable[..., Any]:
     """
     Matcher to match 'headers' argument in request using the responses library.

+ 1 - 1
contrib/python/responses/py3/ya.make

@@ -2,7 +2,7 @@
 
 PY3_LIBRARY()
 
-VERSION(0.24.0)
+VERSION(0.24.1)
 
 LICENSE(Apache-2.0)