diff --git a/src/niquests/models.py b/src/niquests/models.py index 348affafae..f15106c4e2 100644 --- a/src/niquests/models.py +++ b/src/niquests/models.py @@ -742,9 +742,12 @@ def _encode_params( result = [] for k, vs in to_key_val_list(data): iterable_vs: typing.Iterable[str | bytes] - if isinstance(vs, (str, bytes, int, float, bool)): - # not officially supported, but some people maybe passing ints, float or bool. - if isinstance(vs, (str, bytes)) is False: + if isinstance(vs, (str, bytes, int, float, bool)) or not hasattr( + vs, "__iter__" + ): + # not officially supported, but some people maybe passing ints, float, bool, + # or other string serializable classes. + if not isinstance(vs, (str, bytes)): iterable_vs = [str(vs)] else: iterable_vs = [vs] diff --git a/tests/test_requests.py b/tests/test_requests.py index ec58550fe2..a957a254c8 100644 --- a/tests/test_requests.py +++ b/tests/test_requests.py @@ -2540,6 +2540,28 @@ def test_json_encodes_as_bytes(): assert isinstance(p.body, bytes) +def test_data_ecodes_noniterables(): + class Class: + pass + + class ClassStringable: + def __str__(self): + return "šŸ”„arbClassStringablešŸ”„" + + body = { + "string": "string", + "float": 0.01, + "int": 100, + "bool": True, + "None": None, + "plain_class": Class(), + "stringable_class": ClassStringable(), + } + p = PreparedRequest() + p.prepare(method="post", url="https://www.example.com/", data=body) + assert isinstance(p.body, str) + + def test_requests_are_updated_each_time(httpbin): session = RedirectSession([303, 307]) prep = niquests.Request("POST", httpbin("post")).prepare()