Make from_dict extensible
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
This commit is contained in:
parent
936ce1aa54
commit
e75f4c5ad9
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Reference in New Issue