Skip to content

Commit

Permalink
Merge pull request #299 from twisted/ibodyproducer-files-tuples-length
Browse files Browse the repository at this point in the history
Improve error message for short/long file tuples
  • Loading branch information
twm committed Dec 28, 2020
2 parents 79e1380 + ebe28ff commit e7c56c1
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 0 deletions.
1 change: 1 addition & 0 deletions changelog.d/299.feature.rst
@@ -0,0 +1 @@
treq produces a more helpful exception when passed a tuple of the wrong size in the *files* parameter.
13 changes: 13 additions & 0 deletions src/treq/client.py
Expand Up @@ -394,6 +394,18 @@ def _convert_files(files):
file_name, fobj = val
elif len(val) == 3:
file_name, content_type, fobj = val
else:
# NB: This is TypeError for backward compatibility. This case
# used to fall through to `IBodyProducer`, below, which raised
# TypeError about being unable to coerce None.
raise TypeError(
(
"`files` argument must be a sequence of tuples of"
" (file_name, file_obj) or"
" (file_name, content_type, file_obj),"
" but the {!r} tuple has length {}: {!r}"
).format(param, len(val), val),
)
else:
fobj = val
if hasattr(fobj, "name"):
Expand All @@ -402,6 +414,7 @@ def _convert_files(files):
if not content_type:
content_type = _guess_content_type(file_name)

# XXX: Shouldn't this call self._data_to_body_producer?
yield (param, (file_name, content_type, IBodyProducer(fobj)))


Expand Down
30 changes: 30 additions & 0 deletions src/treq/test/test_client.py
Expand Up @@ -398,6 +398,36 @@ def test_request_named_attachment_and_ctype(self):
boundary=b'heyDavid'),
self.MultiPartProducer.call_args)

def test_request_files_tuple_too_short(self):
"""
The `HTTPClient.request()` *files* argument requires tuples of length
2 or 3. It raises `TypeError` when the tuple is too short.
"""
with self.assertRaises(TypeError) as c:
self.client.request(
"POST",
b"http://example.com/",
files=[("t1", ("foo.txt",))],
)

self.assertIn("'t1' tuple has length 1", str(c.exception))

def test_request_files_tuple_too_long(self):
"""
The `HTTPClient.request()` *files* argument requires tuples of length
2 or 3. It raises `TypeError` when the tuple is too long.
"""
with self.assertRaises(TypeError) as c:
self.client.request(
"POST",
b"http://example.com/",
files=[
("t4", ("foo.txt", "text/plain", BytesIO(b"...\n"), "extra!")),
],
)

self.assertIn("'t4' tuple has length 4", str(c.exception))

@mock.patch('treq.client.uuid.uuid4', mock.Mock(return_value="heyDavid"))
def test_request_mixed_params(self):

Expand Down

0 comments on commit e7c56c1

Please sign in to comment.