From cfef12392a52591bf6bbb1d3c5dc57175913a63b Mon Sep 17 00:00:00 2001 From: Syncrain <71864702+syncrain@users.noreply.github.com> Date: Mon, 15 Jun 2026 12:16:30 +0530 Subject: [PATCH] Fix request_to_curl handling of verbose cookies dictionaries (#7603) --- scrapy/utils/request.py | 10 ++++++++- tests/test_utils_request.py | 42 +++++++++++++++++++++++++++++++++++++ 2 files changed, 51 insertions(+), 1 deletion(-) diff --git a/scrapy/utils/request.py b/scrapy/utils/request.py index ffb7fae49..398403d90 100644 --- a/scrapy/utils/request.py +++ b/scrapy/utils/request.py @@ -179,6 +179,12 @@ def _get_method(obj: Any, name: Any) -> Any: raise ValueError(f"Method {name!r} not found in: {obj}") from None +def _cookie_value_to_unicode(value: str | bytes | float) -> str: + if isinstance(value, bytes): + return value.decode() + return str(value) + + def request_to_curl(request: Request) -> str: """ Converts a :class:`~scrapy.Request` object to a curl command. @@ -202,7 +208,9 @@ def request_to_curl(request: Request) -> str: cookies = f"--cookie '{cookie}'" elif isinstance(request.cookies, list): cookie = "; ".join( - f"{next(iter(c.keys()))}={next(iter(c.values()))}" + f"{_cookie_value_to_unicode(c['name'])}={_cookie_value_to_unicode(c['value'])}" + if "name" in c and "value" in c + else f"{next(iter(c.keys()))}={next(iter(c.values()))}" for c in request.cookies ) cookies = f"--cookie '{cookie}'" diff --git a/tests/test_utils_request.py b/tests/test_utils_request.py index 55c46059e..e4967d4e7 100644 --- a/tests/test_utils_request.py +++ b/tests/test_utils_request.py @@ -413,3 +413,45 @@ class TestRequestToCurl: " --data-raw '{\"foo\": \"bar\"}' --cookie 'foo=bar'" ) self._test_request(request_object, expected_curl_command) + + def test_cookies_list_verbose(self): + request_object = Request( + "https://www.httpbin.org/post", + method="POST", + cookies=[ + { + "name": b"foo", + "value": b"bar", + "domain": "example.com", + "path": "/", + "secure": True, + } + ], + body=json.dumps({"foo": "bar"}), + ) + expected_curl_command = ( + "curl -X POST https://www.httpbin.org/post" + " --data-raw '{\"foo\": \"bar\"}' --cookie 'foo=bar'" + ) + self._test_request(request_object, expected_curl_command) + + def test_cookies_list_verbose_non_string_value(self): + request_object = Request( + "https://www.httpbin.org/post", + method="POST", + cookies=[ + { + "name": "foo", + "value": 1, + "domain": "example.com", + "path": "/", + "secure": True, + } + ], + body=json.dumps({"foo": "bar"}), + ) + expected_curl_command = ( + "curl -X POST https://www.httpbin.org/post" + " --data-raw '{\"foo\": \"bar\"}' --cookie 'foo=1'" + ) + self._test_request(request_object, expected_curl_command)