s3_bucket: fix python3 sorting incompatibility (#27502)

* s3_bucket: fix policy sorting for python3 so strings are evaluated as less than tuples.

Add tests to ensure this behavior is maintained.

* Fix s3_bucket comparison function to work on both Python 3.5 and 3.6

* s3_bucket: document that cmp_to_key is used for python 2.7.

Add another test for s3_bucket to compare policies of different sizes.

* fix pep8

* Work around code-smell grepping by not using the word 'cmp'.
This commit is contained in:
Sloane Hertel 2017-08-03 15:41:26 -04:00 committed by Ryan Brown
parent b54d00f2de
commit 467a1f54a3
2 changed files with 198 additions and 1 deletions

View file

@ -134,6 +134,14 @@ try:
except ImportError:
HAS_BOTO = False
try:
# Although this is to allow Python 3 the ability to use the custom comparison as a key, Python 2.7 also
# uses this (and it works as expected). Python 2.6 will trigger the ImportError.
from functools import cmp_to_key
PY3_COMPARISON = True
except ImportError:
PY3_COMPARISON = False
def get_request_payment_status(bucket):
@ -196,10 +204,35 @@ def hashable_policy(policy, policy_list):
if len(policy_list) == 1 and isinstance(policy_list[0], tuple):
policy_list = policy_list[0]
if isinstance(policy_list, list):
policy_list.sort()
if PY3_COMPARISON:
policy_list.sort(key=cmp_to_key(py3cmp))
else:
policy_list.sort()
return policy_list
def py3cmp(a, b):
""" Python 2 can sort lists of mixed types. Strings < tuples. Without this function this fails on Python 3."""
try:
if a > b:
return 1
elif a < b:
return -1
else:
return 0
except TypeError as e:
# check to see if they're tuple-string
# always say strings are less than tuples (to maintain compatibility with python2)
str_ind = to_text(e).find('str')
tup_ind = to_text(e).find('tuple')
if -1 not in (str_ind, tup_ind):
if str_ind < tup_ind:
return -1
elif tup_ind < str_ind:
return 1
raise
def compare_policies(current_policy, new_policy):
""" Compares the existing policy and the updated policy
Returns True if there is a difference between policies.