This is an automated email from the ASF dual-hosted git repository. kpvdr pushed a commit to branch python-check-property-keys in repository https://gitbox.apache.org/repos/asf/qpid-proton.git
The following commit(s) were added to refs/heads/python-check-property-keys by this push: new 3b916e1 PROTON-2237: Fix for dictionary keys changed during iteration error, deeper test for key conversions 3b916e1 is described below commit 3b916e1213ec865a7056c7dc38dd85c1dc36cb60 Author: Kim van der Riet <kp...@apache.org> AuthorDate: Wed Aug 12 15:48:39 2020 -0400 PROTON-2237: Fix for dictionary keys changed during iteration error, deeper test for key conversions --- python/proton/_message.py | 10 ++++++++-- python/tests/proton_tests/message.py | 4 ++++ 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/python/proton/_message.py b/python/proton/_message.py index cdaaf2f..4780c14 100644 --- a/python/proton/_message.py +++ b/python/proton/_message.py @@ -89,21 +89,27 @@ class Message(object): return err def _check_property_keys(self): + # In Py3, we cannot make changes to the dict while iterating, so we + # must save and make the changes afterwards + changed_keys = [] for k in self.properties.keys(): # Check for string types. (py2: unicode, py3: str via type hack above) # or string subclasses. Exclude string subclasses symbol and char. if isinstance(k, unicode) and not (type(k) is symbol or type(k) is char): # Convert string subclasses to string if not type(k) is unicode: - self.properties[unicode(k)] = self.properties.pop(k) + changed_keys.append((k, unicode(k))) continue # If key is binary then change to string. Exclude bytes subclass decimal128. # Mostly for py2 users who encode strings without using the u'' prefix # but py3 bytes() type will be converted also elif isinstance(k, bytes) and not (type(k) is decimal128): - self.properties[k.decode('utf-8')] = self.properties.pop(k) + changed_keys.append((k, k.decode('utf-8'))) else: raise MessageException('Application property key is not string type: key=%s %s' % (str(k), type(k))) + # Make the key changes + for old_key, new_key in changed_keys: + self.properties[new_key] = self.properties.pop(old_key) def _pre_encode(self): inst = Data(pn_message_instructions(self._msg)) diff --git a/python/tests/proton_tests/message.py b/python/tests/proton_tests/message.py index 4363168..e3afdd8 100644 --- a/python/tests/proton_tests/message.py +++ b/python/tests/proton_tests/message.py @@ -140,6 +140,8 @@ class CodecTest(Test): msg2.decode(data) assert msg2.properties == self.msg.properties + for k in msg2.properties: + assert type(k) is unicode, 'non-string key %s %s' % (k, type(k)) def testBinaryPropertyKey(self): self.msg.properties = {'abc': 123, b'def': 456} @@ -149,6 +151,8 @@ class CodecTest(Test): msg2.decode(data) assert msg2.properties == self.msg.properties + for k in msg2.properties: + assert type(k) is unicode, 'non-string key %s %s' % (k, type(k)) def _testNonStringPropertyKey(self, k): self.msg.properties = {k: 'abc'} --------------------------------------------------------------------- To unsubscribe, e-mail: commits-unsubscr...@qpid.apache.org For additional commands, e-mail: commits-h...@qpid.apache.org