Skip to content

Commit 6a13161

Browse files
authored
Merge pull request #692 from caphrim007/bugfix-more-python-3-fixes
Adds some more python 2 to 3 fixes
2 parents cef1533 + cc74bee commit 6a13161

2 files changed

Lines changed: 41 additions & 24 deletions

File tree

f5/bigip/resource.py

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,9 @@
101101
from f5.sdk_exception import F5SDKError
102102
from f5.sdk_exception import UnsupportedMethod
103103
from requests.exceptions import HTTPError
104+
from six import iteritems
105+
from six import iterkeys
106+
from six import itervalues
104107

105108

106109
class MissingRequiredCommandParameter(F5SDKError):
@@ -195,7 +198,7 @@ def _missing_required_parameters(rqset, **kwargs):
195198
196199
::returns list
197200
"""
198-
key_set = set(kwargs.keys())
201+
key_set = set(list(iterkeys(kwargs)))
199202
required_minus_received = rqset - key_set
200203
if required_minus_received != set():
201204
return list(required_minus_received)
@@ -307,7 +310,7 @@ def _check_exclusive_parameters(self, **kwargs):
307310
:raises ExclusiveAttributesPresent
308311
"""
309312
if len(self._meta_data['exclusive_attributes']) > 0:
310-
attr_set = set(kwargs.keys())
313+
attr_set = set(list(iterkeys(kwargs)))
311314
ex_set = set(self._meta_data['exclusive_attributes'][0])
312315
common_set = attr_set.intersection(ex_set)
313316
if len(common_set) > 1:
@@ -479,9 +482,17 @@ def _update(self, **kwargs):
479482
# because these are subCollections and _meta_data and
480483
# other non-BIG-IP® attrs are not removed from the subCollections
481484
# See issue #146 for details
482-
for key, value in self.__dict__.items():
485+
tmp = dict()
486+
for key, value in iteritems(self.__dict__):
487+
# In Python2 versions we were changing a dictionary in place,
488+
# but this cannot be done with an iterator as an error is raised.
489+
# So instead we create a temporary holder for the modified dict
490+
# and then re-assign it afterwards.
483491
if isinstance(value, Collection):
484-
self.__dict__.pop(key, '')
492+
pass
493+
else:
494+
tmp[key] = value
495+
self.__dict__ = tmp
485496
data_dict = self.to_dict()
486497

487498
# Remove any read-only attributes from our data_dict before we update
@@ -773,7 +784,7 @@ def _activate_URI(self, selfLinkuri):
773784

774785
# attrs local alias
775786
attribute_reg = self._meta_data.get('attribute_registry', {})
776-
attrs = attribute_reg.values()
787+
attrs = list(itervalues(attribute_reg))
777788
attrs.append(Stats)
778789

779790
(scheme, domain, path, qarg, frag) = urlparse.urlsplit(selfLinkuri)

f5/bigip/test/test_resource.py

Lines changed: 25 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -81,22 +81,22 @@ def test_Resource__local_update_IncompatibleKeys():
8181
r = Resource(mock.MagicMock())
8282
with pytest.raises(DeviceProvidesIncompatibleKey) as DPIKIO:
8383
r._local_update({"_meta_data": "foo"})
84-
assert DPIKIO.value.message ==\
84+
assert str(DPIKIO.value) ==\
8585
"Response contains key '_meta_data' which is incompatible"\
8686
" with this API!!\n Response json: {'_meta_data': 'foo'}"
8787
with pytest.raises(DeviceProvidesIncompatibleKey) as DPIKIO:
8888
r._local_update({"__MANGLENAME": "foo"})
89-
assert DPIKIO.value.message ==\
89+
assert str(DPIKIO.value) ==\
9090
"Device provided '__MANGLENAME' which is disallowed,"\
9191
" it mangles into a Python non-public attribute."
9292
with pytest.raises(DeviceProvidesIncompatibleKey) as DPIKIO:
9393
r._local_update({"for": "foo"})
94-
assert DPIKIO.value.message ==\
94+
assert str(DPIKIO.value) ==\
9595
"Device provided 'for' which is disallowed because"\
9696
" it's a Python keyword."
9797
with pytest.raises(DeviceProvidesIncompatibleKey) as DPIKIO:
9898
r._local_update({"%abcd": "foo"})
99-
assert DPIKIO.value.message ==\
99+
assert str(DPIKIO.value) ==\
100100
"Device provided '%abcd' which is disallowed because"\
101101
" it's not a valid Python 2.7 identifier."
102102

@@ -132,19 +132,26 @@ def test_missing_required_creation_parameter(self):
132132
r._meta_data['required_creation_parameters'] = set(['NONEMPTY'])
133133
with pytest.raises(MissingRequiredCreationParameter) as MRCPEIO:
134134
r.create(partition="Common", name='CreateTest')
135-
assert MRCPEIO.value.message ==\
135+
assert str(MRCPEIO.value) ==\
136136
"Missing required params: ['NONEMPTY']"
137137

138138
def test_KindTypeMismatch(self):
139+
expected_result = (
140+
"For instances of type ''Virtual'' the "
141+
"corresponding kind must be ''tm:ltm:virtual:virtualstate'' "
142+
"but creation returned "
143+
"JSON with kind: 'tm:'"
144+
)
139145
r = Virtual(mock.MagicMock())
146+
140147
r._meta_data['bigip']._meta_data['icr_session'].post.return_value =\
141-
MockResponse({u"kind": u"tm:"})
142-
with pytest.raises(KindTypeMismatch) as KTMmEIO:
148+
MockResponse({"kind": "tm:"})
149+
150+
with pytest.raises(KindTypeMismatch) as error:
143151
r.create(partition="Common", name="test_create")
144-
assert KTMmEIO.value.message ==\
145-
"For instances of type ''Virtual'' the corresponding kind must "\
146-
"be ''tm:ltm:virtual:virtualstate'' but creation returned "\
147-
"JSON with kind: u'tm:'"
152+
153+
result = error.value.args[0]
154+
assert result == expected_result
148155

149156
def test_success(self, fake_vs):
150157
x = fake_vs.create(partition="Common", name="test_create")
@@ -217,7 +224,7 @@ def test__create_with_Collision():
217224
r._meta_data['uri'] = 'URI'
218225
with pytest.raises(URICreationCollision) as UCCEIO:
219226
r.create(uri='URI')
220-
assert UCCEIO.value.message ==\
227+
assert str(UCCEIO.value) ==\
221228
"There was an attempt to assign a new uri to this resource,"\
222229
" the _meta_data['uri'] is URI and it should not be changed."
223230

@@ -235,7 +242,7 @@ def test__check_generation_with_mismatch(self):
235242
r.generation = 1
236243
with pytest.raises(GenerationMismatch) as GMEIO:
237244
r.update(a=u"b", force=False)
238-
assert GMEIO.value.message ==\
245+
assert str(GMEIO.value) ==\
239246
'The generation of the object on the BigIP (0)'\
240247
' does not match the current object(1)'
241248

@@ -267,7 +274,6 @@ def test_Collection_removal(self):
267274
r.update(a=u"b")
268275
submitted = r._meta_data['bigip']. \
269276
_meta_data['icr_session'].put.call_args[1]['json']
270-
271277
assert 'contained' not in submitted
272278

273279
def test_read_only_removal(self):
@@ -366,7 +372,7 @@ def test_read_only_validate(self):
366372
r.generation = 0
367373
with pytest.raises(AttemptedMutationOfReadOnly) as AMOROEIO:
368374
r.modify(READONLY=True)
369-
assert "READONLY" in AMOROEIO.value.message
375+
assert "READONLY" in str(AMOROEIO.value)
370376

371377
def test_reduce_boolean_removes_enabled(self, fake_rsrc):
372378
fake_rsrc.modify(enabled=False)
@@ -425,7 +431,7 @@ def test_invalid_force(self):
425431
r._meta_data['bigip']._meta_data = {'icr_session': mock_session}
426432
with pytest.raises(InvalidForceType) as IFTEIO:
427433
r.delete(force='true')
428-
assert IFTEIO.value.message == 'force parameter must be type bool'
434+
assert str(IFTEIO.value) == 'force parameter must be type bool'
429435

430436

431437
class Element(Resource):
@@ -469,7 +475,7 @@ def test_unregistered_kind(self):
469475
c.generation = 0
470476
with pytest.raises(UnregisteredKind) as UKEIO:
471477
c.get_collection()
472-
assert UKEIO.value.message ==\
478+
assert str(UKEIO.value) ==\
473479
"'tm:' is not registered!"
474480

475481

@@ -479,15 +485,15 @@ def test_missing_required_params(self):
479485
r._meta_data['required_load_parameters'] = set(['IMPOSSIBLE'])
480486
with pytest.raises(MissingRequiredReadParameter) as MRREIO:
481487
r.load(partition='Common', name='test_load')
482-
assert MRREIO.value.message ==\
488+
assert str(MRREIO.value) ==\
483489
"Missing required params: ['IMPOSSIBLE']"
484490

485491
def test_requests_params_collision(self):
486492
r = Resource(mock.MagicMock())
487493
with pytest.raises(RequestParamKwargCollision) as RPKCEIO:
488494
r.load(partition='Common', name='test_load',
489495
requests_params={'partition': 'ERROR'})
490-
assert RPKCEIO.value.message ==\
496+
assert str(RPKCEIO.value) ==\
491497
"Requests Parameter 'partition' collides with a load parameter"\
492498
" of the same name."
493499

0 commit comments

Comments
 (0)