Skip to content

Commit

Permalink
Fix socket issues (#693)
Browse files Browse the repository at this point in the history
* Revert socket change (#685)
* Added comment why this is the behaviour we have
* Added run on the test to fix coverage
  • Loading branch information
beliaev-maksim committed Nov 14, 2023
1 parent 939562f commit 2d6d039
Show file tree
Hide file tree
Showing 4 changed files with 28 additions and 8 deletions.
1 change: 1 addition & 0 deletions CHANGES
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

* Reverted overloads removal
* Added typing to `Call` attributes.
* Fix socket issues (see #693)


0.24.0
Expand Down
25 changes: 18 additions & 7 deletions responses/__init__.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
import http
import inspect
import json as json_module
import logging
import socket
from functools import partialmethod
from functools import wraps
from http import client
Expand Down Expand Up @@ -535,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,
)

Expand Down
5 changes: 4 additions & 1 deletion responses/tests/test_responses.py
Original file line number Diff line number Diff line change
Expand Up @@ -2054,7 +2054,7 @@ def run():
individual_call: Call = responses.calls[0]
call_slice: List[Call] = responses.calls[1:-1]

assert individual_call.request.url == "http://www.example.com"
assert individual_call.request.url == "http://www.example.com/"

assert call_slice == [
responses.calls[1],
Expand All @@ -2067,6 +2067,9 @@ def run():
"http://www.example.com/1",
]

run()
assert_reset()


def test_response_calls_and_registry_calls_are_equal():
@responses.activate
Expand Down
5 changes: 5 additions & 0 deletions tox.ini
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
[tox]
envlist = py38,py39,py310,py311,mypy,precom

[pytest]
filterwarnings =
error
default::DeprecationWarning

[testenv]
extras = tests
commands =
Expand Down

0 comments on commit 2d6d039

Please sign in to comment.