From 4d05acad99f546fafd38d6bf2add9bf92eab8748 Mon Sep 17 00:00:00 2001 From: Cyril Roelandt Date: Mon, 16 Dec 2013 11:39:59 +0100 Subject: [PATCH] Prevent dictionary size from changing while iterating over its items In Python 3, dict.items() returns 'a dict_item'. Iterating over it while deleting some of the dictionary elements is forbidden. We have to iterate over a list to avoid getting this error: RuntimeError: dictionary changed size during iteration Change-Id: I43401e6eb9a31148fda4677644bf99e1b739d0dd --- keystoneclient/base.py | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/keystoneclient/base.py b/keystoneclient/base.py index df88f0998..49b0565e1 100644 --- a/keystoneclient/base.py +++ b/keystoneclient/base.py @@ -51,23 +51,21 @@ def getid(obj): def filter_kwargs(f): @functools.wraps(f) def func(*args, **kwargs): - for key, ref in kwargs.items(): + new_kwargs = {} + for key, ref in six.iteritems(kwargs): if ref is None: # drop null values - del kwargs[key] continue id_value = getid(ref) - if id_value == ref: - continue + if id_value != ref: + # If an object with an id was passed, then use the id, e.g: + # user: user(id=1) becomes user_id: 1 + key = '%s_id' % key - # if an object with an id was passed remove the object - # from params and replace it with just the id. - # e.g user: User(id=1) becomes user_id: 1 - del kwargs[key] - kwargs['%s_id' % key] = id_value + new_kwargs[key] = id_value - return f(*args, **kwargs) + return f(*args, **new_kwargs) return func