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)
downloadoslo-context-e75f4c5ad91962e272d65daa770e00f70f931ecb.tar.gz
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
-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):
"""
user_idt_format = u'{user} {tenant} {domain} {user_domain} {p_domain}'
+ # Can be overridden in subclasses to specify extra keys that should be
+ # read when constructing a context using from_dict.
+ FROM_DICT_EXTRA_KEYS = []
@_renamed_kwarg('user', 'user_id')
@_renamed_kwarg('tenant', 'project_id')
@@ -391,6 +394,8 @@ class RequestContext(object):
values.get('project_domain_name'))
kwargs.setdefault('is_admin_project',
values.get('is_admin_project', True))
+ for key in cls.FROM_DICT_EXTRA_KEYS:
+ kwargs.setdefault(key, values.get(key))
return cls(**kwargs)
@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):
pass
+class TestContext(context.RequestContext):
+ """A test context with additional members
+
+ This is representative of how at least some of our consumers use the
+ RequestContext class in their projects.
+ """
+ FROM_DICT_EXTRA_KEYS = ['foo']
+
+ def __init__(self, foo=None, **kwargs):
+ super(TestContext, self).__init__(**kwargs)
+ self.foo = foo
+
+ def to_dict(self):
+ d = super(TestContext, self).to_dict()
+ d['foo'] = self.foo
+ return d
+
+
class ContextTest(test_base.BaseTestCase):
def setUp(self):
@@ -182,6 +200,13 @@ class ContextTest(test_base.BaseTestCase):
self.assertFalse(ctx.is_admin)
self.assertTrue(ctx.read_only)
+ def test_from_dict_extended(self):
+ initial = TestContext(foo='bar')
+ dct = initial.to_dict()
+ final = TestContext.from_dict(dct)
+ self.assertEqual('bar', final.foo)
+ self.assertEqual(dct, final.to_dict())
+
def test_is_user_context(self):
self.assertFalse(context.is_user_context(None))
ctx = context.RequestContext(is_admin=True)