From 1d965dbc71da7ca191481f49ac011eef209cd02e Mon Sep 17 00:00:00 2001 From: greymoth-jp Date: Fri, 26 Jun 2026 04:19:53 +0900 Subject: [PATCH] Fix request_to_curl() corrupting dict cookies with bytes keys/values PR #7603 made the list-cookie branch of request_to_curl() bytes-safe via _cookie_value_to_unicode(), but left the sibling dict-cookie branch using raw f-string interpolation. A dict cookie with bytes keys/values (a supported and common form, e.g. Request(url, cookies={b"k": b"v"})) was rendered as --cookie 'b'k'=b'v'' instead of --cookie 'k=v', producing a broken curl command. Route the dict branch through the same _cookie_value_to_unicode() helper, mirroring the list branch. Add a regression test. Co-Authored-By: Claude Opus 4.8 (1M context) --- scrapy/utils/request.py | 5 ++++- tests/test_utils_request.py | 13 +++++++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/scrapy/utils/request.py b/scrapy/utils/request.py index 398403d90..20f93c1aa 100644 --- a/scrapy/utils/request.py +++ b/scrapy/utils/request.py @@ -204,7 +204,10 @@ def request_to_curl(request: Request) -> str: cookies = "" if request.cookies: if isinstance(request.cookies, dict): - cookie = "; ".join(f"{k}={v}" for k, v in request.cookies.items()) + cookie = "; ".join( + f"{_cookie_value_to_unicode(k)}={_cookie_value_to_unicode(v)}" + for k, v in request.cookies.items() + ) cookies = f"--cookie '{cookie}'" elif isinstance(request.cookies, list): cookie = "; ".join( diff --git a/tests/test_utils_request.py b/tests/test_utils_request.py index e4967d4e7..f9b6a4d81 100644 --- a/tests/test_utils_request.py +++ b/tests/test_utils_request.py @@ -401,6 +401,19 @@ class TestRequestToCurl: ) self._test_request(request_object, expected_curl_command) + def test_cookies_dict_bytes(self): + request_object = Request( + "https://www.httpbin.org/post", + method="POST", + cookies={b"foo": b"bar"}, + 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(self): request_object = Request( "https://www.httpbin.org/post",