You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@qpid.apache.org by kp...@apache.org on 2020/08/12 19:50:40 UTC

[qpid-proton] branch python-check-property-keys updated: PROTON-2237: Fix for dictionary keys changed during iteration error, deeper test for key conversions

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-unsubscribe@qpid.apache.org
For additional commands, e-mail: commits-help@qpid.apache.org