summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMorgan Fainberg <morgan.fainberg@gmail.com>2016-05-27 17:11:53 -0700
committerMorgan Fainberg <morgan.fainberg@gmail.com>2016-05-29 23:08:05 +0000
commit46fcc461b6d50b0be42754ac1801b16002f76c94 (patch)
treef1cbebfe7a2f679f972504f0d9c04b36a8d6925b
parentc313be6e181bd4916e3728d9889d865f011b51c7 (diff)
downloadgear-46fcc461b6d50b0be42754ac1801b16002f76c94.tar.gz
Do not change object size when iterating
In `gear.Server._lostConnection()` the jobs list pulls .values() from `conn.related_jobs`, in `gear.server._removeJob()` it is possible to change the conn.related_jobs dictionary which will cause a `RuntimeError: dictionary changed size during iteration` exception to be raised in python 3 since .values() is an iterator instead of a rendered list() like in python 2. This RuntimeError is eliminated by forcing the python 2 behavior by wrapping the `.values()` call to be wrapped into an explicit list. Change-Id: I730473f3200a427cce774df534f1ff4958866dac
-rw-r--r--gear/__init__.py12
1 files changed, 10 insertions, 2 deletions
diff --git a/gear/__init__.py b/gear/__init__.py
index 7fccc34..c561a86 100644
--- a/gear/__init__.py
+++ b/gear/__init__.py
@@ -797,7 +797,11 @@ class BaseClientServer(object):
self.log.debug("Marking %s as disconnected" % conn)
self.connections_condition.acquire()
try:
- jobs = conn.related_jobs.values()
+ # NOTE(notmorgan): In the loop below it is possible to change the
+ # jobs list on the connection. In python 3 .values() is an iter not
+ # a static list, meaning that a change will break the for loop
+ # as the object being iterated on will have changed in size.
+ jobs = list(conn.related_jobs.values())
if conn in self.active_connections:
self.active_connections.remove(conn)
if conn not in self.inactive_connections:
@@ -2683,7 +2687,11 @@ class Server(BaseClientServer):
self.connections_condition.acquire()
self._unregisterConnection(conn)
try:
- jobs = conn.related_jobs.values()
+ # NOTE(notmorgan): In the loop below it is possible to change the
+ # jobs list on the connection. In python 3 .values() is an iter not
+ # a static list, meaning that a change will break the for loop
+ # as the object being iterated on will have changed in size.
+ jobs = list(conn.related_jobs.values())
if conn in self.active_connections:
self.active_connections.remove(conn)
finally: