Skip to content

Commit

Permalink
Merge pull request #11 from dshen109/master
Browse files Browse the repository at this point in the history
Namespace Traversal
  • Loading branch information
shakefu committed Jul 3, 2018
2 parents 202dc03 + c9fa456 commit 966e7f4
Show file tree
Hide file tree
Showing 3 changed files with 70 additions and 1 deletion.
2 changes: 1 addition & 1 deletion pytool/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
limitations under the License.
"""
__version__ = '3.8.1'
__version__ = '3.9.0'


from pytool import (
Expand Down
34 changes: 34 additions & 0 deletions pytool/lang.py
Original file line number Diff line number Diff line change
Expand Up @@ -402,6 +402,10 @@ class Namespace(object):
Added dict-like access capability to Namespaces.
.. versionadded:: 3.9.0
Added traversal by key/index arrays for nested Namespaces and lists
"""
def __init__(self, obj=None):
if obj is not None:
Expand Down Expand Up @@ -532,6 +536,36 @@ def copy(self, *args, **kwargs):
__copy__ = copy
__deepcopy__ = copy

def traverse(self, path):
""" Traverse the Namespace and any nested elements by following the
elements in an iterable *path* and return the item found at the end
of *path*.
Traversal is achieved using the __getitem__ method, allowing for
traversal of nested structures such as arrays and dictionaries.
AttributeError is raised if one of the attributes in *path* does
not exist at the expected depth.
:param iterable path: An iterable whose elements specify the keys
to path over.
Example:
ns = Namespace({"foo":
[Namespace({"name": "john"}),
Namespace({"name": "jane"})]})
ns.traverse(["foo", 1, "name"])
... returns ...
"jane"
"""
struct = self
for k in path:
struct = struct[k]
return struct


def _split_keys(obj):
"""
Expand Down
35 changes: 35 additions & 0 deletions test/test_lang.py
Original file line number Diff line number Diff line change
Expand Up @@ -544,3 +544,38 @@ def test_namespace_copy_api_list():
ns2.foo[0].bar.baz = 2

eq_(ns.foo[0].bar.baz, 1)


def test_namespace_traverse():
ns = pytool.lang.Namespace()
ns.foo.bar = "foobar"
val = ns.traverse(["foo", "bar"])

eq_(val, "foobar")


def test_namespace_traverse_list():
ns = pytool.lang.Namespace({"foo":
[pytool.lang.Namespace({"name": "john"}),
pytool.lang.Namespace({"name": "jane"})]})
name = ns.traverse(["foo", 0, "name"])

eq_(name, "john")


def test_namespace_traverse_dict():
ns = pytool.lang.Namespace()
ns.foo = {"first": pytool.lang.Namespace({"color": "red"}),
"second": pytool.lang.Namespace({"color": "blue"})}
val = ns.traverse(["foo", "second", "color"])

eq_(val, "blue")


@raises(AttributeError)
def test_namespace_traverse_failure():
ns = pytool.lang.Namespace()

ns.traverse(["foo"])

eq_(ns.as_dict(), {})

0 comments on commit 966e7f4

Please sign in to comment.