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)