diff --git a/HISTORY.rst b/HISTORY.rst index cfa9552..386d793 100644 --- a/HISTORY.rst +++ b/HISTORY.rst @@ -3,6 +3,12 @@ History ------- +0.3.1 (2018-04-11) +~~~~~~~~~~~~~~~~~~ + +* Added support for ``*args``, ``**kwargs`` in ``Context.push()``. +* Added ``__dir__`` support. + 0.3.0 (2018-02-16) ~~~~~~~~~~~~~~~~~~ diff --git a/pycontext/__init__.py b/pycontext/__init__.py index fe855d0..f969d82 100644 --- a/pycontext/__init__.py +++ b/pycontext/__init__.py @@ -3,5 +3,5 @@ __author__ = 'Miroslav Shubernetskiy' -__version__ = '0.3.0' +__version__ = '0.3.1' __description__ = 'Python dict with stacked context data' diff --git a/pycontext/context.py b/pycontext/context.py index fac6883..330ca2b 100644 --- a/pycontext/context.py +++ b/pycontext/context.py @@ -142,6 +142,9 @@ def _get_base_context(self): """ return {} + def __dir__(self): + return dir(self.__class__) + list(self.keys()) + def __repr__(self): return repr(list(self.frames)) @@ -428,7 +431,7 @@ def update(self, *args, **kwargs): with self._with_changed_keys(*chain(kwargs.items(), *(i.items() for i in args))): self.frames[0].update(*args, **kwargs) - def push(self, data): + def push(self, *args, **kwargs): """ Push a new scope on the stack. @@ -438,14 +441,20 @@ def push(self, data): :param data: the data dictionary to push on the context stack. """ - if data is self: - raise ValueError( - 'Cannot push context to itself.' - ) - # For simplicity need to normalize the data to dict - # since otherwise data can be another context - # which will cause undesired recursion - data = dict(data) + data = {} + + for i in args: + if i is self: + raise ValueError( + 'Cannot push context to itself.' + ) + + # For simplicity need to normalize the data to dict + # since otherwise data can be another context + # which will cause undesired recursion + data.update(dict(i)) + + data.update(kwargs) with self._with_changed_keys(*data.items()): self.frames.appendleft(data) diff --git a/tests/test_context.py b/tests/test_context.py index 6dcce29..bd8ea39 100644 --- a/tests/test_context.py +++ b/tests/test_context.py @@ -58,6 +58,14 @@ def test_get_base_context(self): '_get_base_context should return empty dict' ) + def test_dir(self): + """ + Test that __dir__ returns all keys + """ + context = Context({'foo': 'foo', 'bar': 'bar'}) + for k in ['foo', 'bar', 'push']: + self.assertIn(k, dir(context)) + def test_repr(self): """ Test that __repr__ returns representation of all frames @@ -402,12 +410,12 @@ def test_update(self): def test_push_pop(self): context = Context({'hello': 'world'}) - context.push({'hello': 'mars'}) + context.push({'hello': 'mars'}, foo='bar') self.context.push(context) inserted = self.context.pop() - self.assertEqual(inserted, {'hello': 'mars'}) + self.assertEqual(inserted, {'hello': 'mars', 'foo': 'bar'}) self.assertIsInstance(inserted, dict) self.assertNotIsInstance(inserted, Context)