Skip to content

Commit

Permalink
add list of tuples functionality to AWSRequest params attribute (#2679)
Browse files Browse the repository at this point in the history
  • Loading branch information
dlm6693 authored May 20, 2022
1 parent f4ed130 commit 3a778dc
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 4 deletions.
8 changes: 5 additions & 3 deletions botocore/auth.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import json
import logging
import time
from collections.abc import Mapping
from email.utils import formatdate
from hashlib import sha1, sha256
from operator import itemgetter
Expand Down Expand Up @@ -245,10 +246,11 @@ def canonical_query_string(self, request):
def _canonical_query_string_params(self, params):
# [(key, value), (key2, value2)]
key_val_pairs = []
for key in params:
value = str(params[key])
if isinstance(params, Mapping):
params = params.items()
for key, value in params:
key_val_pairs.append(
(quote(key, safe='-_.~'), quote(value, safe='-_.~'))
(quote(key, safe='-_.~'), quote(str(value), safe='-_.~'))
)
sorted_key_vals = []
# Sort by the URI-encoded key names, and in the case of
Expand Down
7 changes: 6 additions & 1 deletion botocore/awsrequest.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
# language governing permissions and limitations under the License.
import functools
import logging
from collections.abc import Mapping

import urllib3.util
from urllib3.connection import HTTPConnection, VerifiedHTTPSConnection
Expand Down Expand Up @@ -367,7 +368,11 @@ def _prepare_url(self, original):
if original.params:
url_parts = urlparse(url)
delim = '&' if url_parts.query else '?'
params = urlencode(list(original.params.items()), doseq=True)
if isinstance(original.params, Mapping):
params_to_encode = list(original.params.items())
else:
params_to_encode = original.params
params = urlencode(params_to_encode, doseq=True)
url = delim.join((url, params))
return url

Expand Down
36 changes: 36 additions & 0 deletions tests/unit/test_awsrequest.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
import socket
import tempfile

import pytest
from urllib3.connectionpool import HTTPConnectionPool, HTTPSConnectionPool

from botocore.awsrequest import (
Expand Down Expand Up @@ -268,6 +269,41 @@ def seek(self, where):
self.assertTrue(looks_like_file.seek_called)


@pytest.mark.parametrize(
"test_input,expected_output",
[
([('foo', None)], 'http://example.com/?foo=None'),
([(None, None)], 'http://example.com/?None=None'),
(
[('foo', 'bar'), ('foo', 'baz'), ('fizz', 'buzz')],
'http://example.com/?foo=bar&foo=baz&fizz=buzz'
),
([('foo', 'bar'), ('foo', None)], 'http://example.com/?foo=bar&foo=None'),
([('foo', 'bar')], 'http://example.com/?foo=bar'),
(
[('foo', 'bar'), ('foo', 'bar'), ('fizz', 'buzz')],
'http://example.com/?foo=bar&foo=bar&fizz=buzz'
),
([('', 'bar')], 'http://example.com/?=bar'),
([(1, 'bar')], 'http://example.com/?1=bar'),
]
)
def test_can_use_list_tuples_for_params(test_input, expected_output):
request = AWSRequest(
url='http://example.com/', params=test_input
)
prepared_request = request.prepare()
assert prepared_request.url == expected_output


def test_empty_list_tuples_value_error_for_params():
request = AWSRequest(
url='http://example.com/', params=[()]
)
with pytest.raises(ValueError):
request.prepare()


class TestAWSResponse(unittest.TestCase):
def setUp(self):
self.response = AWSResponse('http://url.com', 200, HeadersDict(), None)
Expand Down

0 comments on commit 3a778dc

Please sign in to comment.