Repository: hikari-py/hikari
Pull request #1493 (2023-02-05 23:35:42)

Fix `URLEncodedFormBuilder` treating fields as files
### Checklist
<!-- Make sure to tick all the following boxes by putting an `x` in between (like this `[x]`) -->
- [x] I have run `nox` and all the pipelines have passed.
- [x] I have made unittests according to the code I have added/modified/deleted.

Closes #1491


Patch:
diff --git a/hikari/impl/rest.py b/hikari/impl/rest.py
index 6123645a..3d380ecb 100644
--- a/hikari/impl/rest.py
+++ b/hikari/impl/rest.py
@@ -777,7 +777,7 @@ async def _perform_request(
             if form_builder:
                 raise ValueError("Can only provide one of 'json' or 'form_builder', not both")
 
-            data = data_binding.JSONPayload(json, json_dumps=self._dumps)
+            data = data_binding.JSONPayload(json, dumps=self._dumps)
 
         url = compiled_route.create_url(self._rest_url)
 
diff --git a/hikari/internal/data_binding.py b/hikari/internal/data_binding.py
index 49ec7969..7107bdd1 100644
--- a/hikari/internal/data_binding.py
+++ b/hikari/internal/data_binding.py
@@ -95,6 +95,7 @@
 
 _APPLICATION_OCTET_STREAM: typing.Final[str] = "application/octet-stream"
 _JSON_CONTENT_TYPE: typing.Final[str] = "application/json"
+_BINARY: typing.Final[str] = "binary"
 _UTF_8: typing.Final[str] = "utf-8"
 
 default_json_dumps: JSONEncoder
@@ -124,9 +125,7 @@ def default_json_dumps(obj: typing.Union[JSONArray, JSONObject]) -> bytes:
 class JSONPayload(aiohttp.BytesPayload):
     """A JSON payload to use in an aiohttp request."""
 
-    def __init__(
-        self, value: typing.Any, dumps: JSONEncoder = default_json_dumps, *args: typing.Any, **kwargs: typing.Any
-    ) -> None:
+    def __init__(self, value: typing.Any, dumps: JSONEncoder = default_json_dumps) -> None:
         super().__init__(dumps(value), content_type=_JSON_CONTENT_TYPE, encoding=_UTF_8)
 
 
@@ -154,7 +153,7 @@ async def build(
         form = aiohttp.FormData()
 
         for field in self._fields:
-            form.add_field(field[0], field[1], content_type=field[2])
+            form.add_field(field[0], field[1], content_type=field[2], content_transfer_encoding=_BINARY)
 
         for name, resource in self._resources:
             stream = await stack.enter_async_context(resource.stream(executor=executor))


Test patch:
diff --git a/tests/hikari/impl/test_rest.py b/tests/hikari/impl/test_rest.py
index ea29e27d..8117b210 100644
--- a/tests/hikari/impl/test_rest.py
+++ b/tests/hikari/impl/test_rest.py
@@ -1736,7 +1736,7 @@ async def test_perform_request_builds_json_when_passed(self, rest_client, exit_e
             with pytest.raises(exit_exception):
                 await rest_client._perform_request(route, json={"some": "data"})
 
-        json_payload.assert_called_once_with({"some": "data"}, json_dumps=rest_client._dumps)
+        json_payload.assert_called_once_with({"some": "data"}, dumps=rest_client._dumps)
         _, kwargs = rest_client._client_session.request.call_args_list[0]
         assert kwargs["data"] is json_payload.return_value
 
diff --git a/tests/hikari/internal/test_data_binding.py b/tests/hikari/internal/test_data_binding.py
index 572947ea..d4144891 100644
--- a/tests/hikari/internal/test_data_binding.py
+++ b/tests/hikari/internal/test_data_binding.py
@@ -75,8 +75,8 @@ async def test_build(self, form_builder):
         )
         mock_form_class.return_value.add_field.assert_has_calls(
             [
-                mock.call("test_name", "test_data", content_type="mimetype"),
-                mock.call("test_name2", "test_data2", content_type="mimetype2"),
+                mock.call("test_name", "test_data", content_type="mimetype", content_transfer_encoding="binary"),
+                mock.call("test_name2", "test_data2", content_type="mimetype2", content_transfer_encoding="binary"),
                 mock.call("aye", stream1, filename="testing1", content_type="text"),
                 mock.call("lmao", stream2, filename="testing2", content_type="application/octet-stream"),
             ]