Loading django/template/context.py +9 −1 Original line number Diff line number Diff line Loading @@ -52,7 +52,13 @@ class BaseContext(object): yield d def push(self, *args, **kwargs): return ContextDict(self, *args, **kwargs) dicts = [] for d in args: if isinstance(d, BaseContext): dicts += d.dicts[1:] else: dicts.append(d) return ContextDict(self, *dicts, **kwargs) def pop(self): if len(self.dicts) == 1: Loading Loading @@ -175,6 +181,8 @@ class Context(BaseContext): "Pushes other_dict to the stack of dictionaries in the Context" if not hasattr(other_dict, '__getitem__'): raise TypeError('other_dict must be a mapping (dictionary-like) object.') if isinstance(other_dict, BaseContext): other_dict = other_dict.dicts[1:].pop() return ContextDict(self, other_dict) Loading tests/template_tests/test_context.py +54 −0 Original line number Diff line number Diff line Loading @@ -43,6 +43,46 @@ class ContextTests(SimpleTestCase): self.assertEqual(c['a'], 3) self.assertEqual(c['a'], 1) def test_push_context_manager_with_context_object(self): c = Context({'a': 1}) with c.push(Context({'a': 3})): self.assertEqual(c['a'], 3) self.assertEqual(c['a'], 1) def test_update_context_manager_with_context_object(self): c = Context({'a': 1}) with c.update(Context({'a': 3})): self.assertEqual(c['a'], 3) self.assertEqual(c['a'], 1) def test_push_proper_layering(self): c = Context({'a': 1}) c.push(Context({'b': 2})) c.push(Context({'c': 3, 'd': {'z': '26'}})) self.assertEqual( c.dicts, [ {'False': False, 'None': None, 'True': True}, {'a': 1}, {'b': 2}, {'c': 3, 'd': {'z': '26'}}, ] ) def test_update_proper_layering(self): c = Context({'a': 1}) c.update(Context({'b': 2})) c.update(Context({'c': 3, 'd': {'z': '26'}})) self.assertEqual( c.dicts, [ {'False': False, 'None': None, 'True': True}, {'a': 1}, {'b': 2}, {'c': 3, 'd': {'z': '26'}}, ] ) def test_setdefault(self): c = Context() Loading Loading @@ -96,6 +136,20 @@ class ContextTests(SimpleTestCase): 'a': 2, 'b': 4, 'c': 8 }) def test_flatten_context_with_context(self): """ Context.push() with a Context argument should work. """ a = Context({'a': 2}) a.push(Context({'z': '8'})) self.assertEqual(a.flatten(), { 'False': False, 'None': None, 'True': True, 'a': 2, 'z': '8', }) def test_context_comparable(self): """ #21765 -- equality comparison should work Loading Loading
django/template/context.py +9 −1 Original line number Diff line number Diff line Loading @@ -52,7 +52,13 @@ class BaseContext(object): yield d def push(self, *args, **kwargs): return ContextDict(self, *args, **kwargs) dicts = [] for d in args: if isinstance(d, BaseContext): dicts += d.dicts[1:] else: dicts.append(d) return ContextDict(self, *dicts, **kwargs) def pop(self): if len(self.dicts) == 1: Loading Loading @@ -175,6 +181,8 @@ class Context(BaseContext): "Pushes other_dict to the stack of dictionaries in the Context" if not hasattr(other_dict, '__getitem__'): raise TypeError('other_dict must be a mapping (dictionary-like) object.') if isinstance(other_dict, BaseContext): other_dict = other_dict.dicts[1:].pop() return ContextDict(self, other_dict) Loading
tests/template_tests/test_context.py +54 −0 Original line number Diff line number Diff line Loading @@ -43,6 +43,46 @@ class ContextTests(SimpleTestCase): self.assertEqual(c['a'], 3) self.assertEqual(c['a'], 1) def test_push_context_manager_with_context_object(self): c = Context({'a': 1}) with c.push(Context({'a': 3})): self.assertEqual(c['a'], 3) self.assertEqual(c['a'], 1) def test_update_context_manager_with_context_object(self): c = Context({'a': 1}) with c.update(Context({'a': 3})): self.assertEqual(c['a'], 3) self.assertEqual(c['a'], 1) def test_push_proper_layering(self): c = Context({'a': 1}) c.push(Context({'b': 2})) c.push(Context({'c': 3, 'd': {'z': '26'}})) self.assertEqual( c.dicts, [ {'False': False, 'None': None, 'True': True}, {'a': 1}, {'b': 2}, {'c': 3, 'd': {'z': '26'}}, ] ) def test_update_proper_layering(self): c = Context({'a': 1}) c.update(Context({'b': 2})) c.update(Context({'c': 3, 'd': {'z': '26'}})) self.assertEqual( c.dicts, [ {'False': False, 'None': None, 'True': True}, {'a': 1}, {'b': 2}, {'c': 3, 'd': {'z': '26'}}, ] ) def test_setdefault(self): c = Context() Loading Loading @@ -96,6 +136,20 @@ class ContextTests(SimpleTestCase): 'a': 2, 'b': 4, 'c': 8 }) def test_flatten_context_with_context(self): """ Context.push() with a Context argument should work. """ a = Context({'a': 2}) a.push(Context({'z': '8'})) self.assertEqual(a.flatten(), { 'False': False, 'None': None, 'True': True, 'a': 2, 'z': '8', }) def test_context_comparable(self): """ #21765 -- equality comparison should work Loading