From 45d88308336a35cefc344cb620c285c45acc5eb6 Mon Sep 17 00:00:00 2001 From: disqualifier Date: Mon, 6 Jul 2026 21:16:08 -0400 Subject: [PATCH] fix: as_curl form-encodes a dict data= body with doseq=True urlencode(data) without doseq rendered a list-valued form field as its urlencoded python repr (x=%5B%271%27...) instead of aiohttp FormData's repeated-pair wire form (x=1&x=2), so a debug curl for a list-valued body replayed a different request than request() sent. add doseq=True to match the wire. preview/debug-only; scalar values and non-dict bodies are byte-unchanged. Signed-off-by: disqualifier --- src/aioweb/preview.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/aioweb/preview.py b/src/aioweb/preview.py index 3435e54..e50db7c 100644 --- a/src/aioweb/preview.py +++ b/src/aioweb/preview.py @@ -36,8 +36,9 @@ class RequestPreview: if self.details["data"] is not None: data = self.details["data"] # aiohttp form-encodes a dict data= body (application/x-www-form-urlencoded); - # render that wire form, not the python repr, so the curl replays identically - rendered = urlencode(data) if isinstance(data, dict) else str(data) + # render that wire form, not the python repr, so the curl replays identically. + # doseq=True mirrors aiohttp's FormData: a list value becomes repeated k=v pairs + rendered = urlencode(data, doseq=True) if isinstance(data, dict) else str(data) parts.append(f"--data {shlex.quote(rendered)}") elif self.details["json"] is not None: # is-not-None: an empty-but-valid body ({} / []) must still render