summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBen Nemec <bnemec@redhat.com>2017-10-10 20:40:34 +0000
committerBen Nemec <bnemec@redhat.com>2017-10-11 21:46:02 +0000
commite75f4c5ad91962e272d65daa770e00f70f931ecb (patch)
treed1310f4f1f131cce7a140e24d5f3acbdb4b2ddc3
parent936ce1aa54a1034f6c09e2baa588c96416322265 (diff)
Make from_dict extensible2.19.2
Some of our consumers define additional members on the context class that they want included in to_dict and from_dict. While it is possible to do this today via overrides of those functions, the from_dict implementation in particular is a little non-obvious. This has led to bugs when the base class's to_dict behavior changes. This change moves the logic around extending the keys recognized by from_dict into from_dict itself and allows consumers to simply provide a list of those keys by overriding a class member. Change-Id: Ib143f8a5c129dbf6711800c4d87c8830a8aa3365 Related-Bug: 1721432
Notes
Notes (review): Verified+1: Jenkins Code-Review+2: ChangBo Guo(gcb) <glongwave@gmail.com> Code-Review+2: Doug Hellmann <doug@doughellmann.com> Workflow+1: Doug Hellmann <doug@doughellmann.com> Verified+2: Zuul Submitted-by: Zuul Submitted-at: Tue, 17 Oct 2017 15:59:43 +0000 Reviewed-on: https://review.openstack.org/511026 Project: openstack/oslo.context Branch: refs/heads/master
-rw-r--r--oslo_context/context.py5
-rw-r--r--oslo_context/tests/test_context.py25
2 files changed, 30 insertions, 0 deletions
diff --git a/oslo_context/context.py b/oslo_context/context.py
index 06f981e..24ded43 100644
--- a/oslo_context/context.py
+++ b/oslo_context/context.py
@@ -180,6 +180,9 @@ class RequestContext(object):
180 """ 180 """
181 181
182 user_idt_format = u'{user} {tenant} {domain} {user_domain} {p_domain}' 182 user_idt_format = u'{user} {tenant} {domain} {user_domain} {p_domain}'
183 # Can be overridden in subclasses to specify extra keys that should be
184 # read when constructing a context using from_dict.
185 FROM_DICT_EXTRA_KEYS = []
183 186
184 @_renamed_kwarg('user', 'user_id') 187 @_renamed_kwarg('user', 'user_id')
185 @_renamed_kwarg('tenant', 'project_id') 188 @_renamed_kwarg('tenant', 'project_id')
@@ -391,6 +394,8 @@ class RequestContext(object):
391 values.get('project_domain_name')) 394 values.get('project_domain_name'))
392 kwargs.setdefault('is_admin_project', 395 kwargs.setdefault('is_admin_project',
393 values.get('is_admin_project', True)) 396 values.get('is_admin_project', True))
397 for key in cls.FROM_DICT_EXTRA_KEYS:
398 kwargs.setdefault(key, values.get(key))
394 return cls(**kwargs) 399 return cls(**kwargs)
395 400
396 @classmethod 401 @classmethod
diff --git a/oslo_context/tests/test_context.py b/oslo_context/tests/test_context.py
index 8595975..f81f4f0 100644
--- a/oslo_context/tests/test_context.py
+++ b/oslo_context/tests/test_context.py
@@ -54,6 +54,24 @@ class Object(object):
54 pass 54 pass
55 55
56 56
57class TestContext(context.RequestContext):
58 """A test context with additional members
59
60 This is representative of how at least some of our consumers use the
61 RequestContext class in their projects.
62 """
63 FROM_DICT_EXTRA_KEYS = ['foo']
64
65 def __init__(self, foo=None, **kwargs):
66 super(TestContext, self).__init__(**kwargs)
67 self.foo = foo
68
69 def to_dict(self):
70 d = super(TestContext, self).to_dict()
71 d['foo'] = self.foo
72 return d
73
74
57class ContextTest(test_base.BaseTestCase): 75class ContextTest(test_base.BaseTestCase):
58 76
59 def setUp(self): 77 def setUp(self):
@@ -182,6 +200,13 @@ class ContextTest(test_base.BaseTestCase):
182 self.assertFalse(ctx.is_admin) 200 self.assertFalse(ctx.is_admin)
183 self.assertTrue(ctx.read_only) 201 self.assertTrue(ctx.read_only)
184 202
203 def test_from_dict_extended(self):
204 initial = TestContext(foo='bar')
205 dct = initial.to_dict()
206 final = TestContext.from_dict(dct)
207 self.assertEqual('bar', final.foo)
208 self.assertEqual(dct, final.to_dict())
209
185 def test_is_user_context(self): 210 def test_is_user_context(self):
186 self.assertFalse(context.is_user_context(None)) 211 self.assertFalse(context.is_user_context(None))
187 ctx = context.RequestContext(is_admin=True) 212 ctx = context.RequestContext(is_admin=True)