Skip to content

Commit

Permalink
clean up comments and tests
Browse files Browse the repository at this point in the history
  • Loading branch information
DanielYang59 committed Nov 13, 2024
1 parent 03fc253 commit 9b11922
Show file tree
Hide file tree
Showing 2 changed files with 70 additions and 62 deletions.
35 changes: 17 additions & 18 deletions src/monty/collections.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ def tree() -> collections.defaultdict:
Usage:
x = tree()
x['a']['b']['c'] = 1
x["a"]["b"]["c"] = 1
Returns:
A tree.
Expand All @@ -31,7 +31,7 @@ def tree() -> collections.defaultdict:
class frozendict(dict):
"""
A dictionary that does not permit changes. The naming
violates PEP8 to be consistent with standard Python's "frozenset" naming.
violates PEP 8 to be consistent with standard Python's "frozenset" naming.
"""

def __init__(self, *args, **kwargs) -> None:
Expand All @@ -55,7 +55,7 @@ def update(self, *args, **kwargs) -> None:


class Namespace(dict):
"""A dictionary that does not permit to redefine its keys."""
"""A dictionary that does not permit changing its values."""

def __init__(self, *args, **kwargs) -> None:
"""
Expand All @@ -67,7 +67,7 @@ def __init__(self, *args, **kwargs) -> None:

def __setitem__(self, key: Any, val: Any) -> None:
if key in self:
raise KeyError(f"Cannot overwrite existent key: {key!s}")
raise KeyError(f"Cannot overwrite existing key: {key!s}")

dict.__setitem__(self, key, val)

Expand All @@ -83,14 +83,14 @@ def update(self, *args, **kwargs) -> None:

class AttrDict(dict):
"""
Allows to access dict keys as obj.foo in addition
to the traditional way obj['foo']"
Allows to access values as dct.key in addition
to the traditional way dct["key"]
Examples:
>>> d = AttrDict(foo=1, bar=2)
>>> assert d["foo"] == d.foo
>>> d.bar = "hello"
>>> assert d.bar == "hello"
>>> dct = AttrDict(foo=1, bar=2)
>>> assert dct["foo"] == dct.foo
>>> dct.bar = "hello"
>>> assert dct.bar == "hello"
"""

def __init__(self, *args, **kwargs) -> None:
Expand All @@ -114,9 +114,9 @@ def copy(self) -> Self:
class FrozenAttrDict(frozendict):
"""
A dictionary that:
* does not permit changes.
* Allows to access dict keys as obj.foo in addition
to the traditional way obj['foo']
- Does not permit changes.
- Allows to access values as dct.key in addition
to the traditional way dct["key"]
"""

def __init__(self, *args, **kwargs) -> None:
Expand Down Expand Up @@ -186,7 +186,6 @@ def __getattribute__(self, name: str) -> Any:
try:
return super().__getattribute__(name)
except AttributeError:
# raise
try:
a = self._mongo_dict_[name]
if isinstance(a, collections.abc.Mapping):
Expand Down Expand Up @@ -232,8 +231,8 @@ def dict2namedtuple(*args, **kwargs) -> tuple:
- Don't use this function in code in which memory and performance are
crucial since a dict is needed to instantiate the tuple!
"""
d = collections.OrderedDict(*args)
d.update(**kwargs)
dct = collections.OrderedDict(*args)
dct.update(**kwargs)
return collections.namedtuple(
typename="dict2namedtuple", field_names=list(d.keys())
)(**d)
typename="dict2namedtuple", field_names=list(dct.keys())
)(**dct)
97 changes: 53 additions & 44 deletions tests/test_collections.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,47 +9,56 @@
TEST_DIR = os.path.join(os.path.dirname(__file__), "test_files")


class TestFrozenDict:
def test_frozen_dict(self):
d = frozendict({"hello": "world"})
with pytest.raises(KeyError):
d["k"] == "v"
assert d["hello"] == "world"

def test_namespace_dict(self):
d = Namespace(foo="bar")
d["hello"] = "world"
assert d["foo"] == "bar"
with pytest.raises(KeyError):
d.update({"foo": "spam"})

def test_attr_dict(self):
d = AttrDict(foo=1, bar=2)
assert d.bar == 2
assert d["foo"] == d.foo
d.bar = "hello"
assert d["bar"] == "hello"

def test_frozen_attrdict(self):
d = FrozenAttrDict({"hello": "world", 1: 2})
assert d["hello"] == "world"
assert d.hello == "world"
with pytest.raises(KeyError):
d["updating"] == 2

with pytest.raises(KeyError):
d["foo"] = "bar"
with pytest.raises(KeyError):
d.foo = "bar"
with pytest.raises(KeyError):
d.hello = "new"


class TestTree:
def test_tree(self):
x = tree()
x["a"]["b"]["c"]["d"] = 1
assert "b" in x["a"]
assert "c" not in x["a"]
assert "c" in x["a"]["b"]
assert x["a"]["b"]["c"]["d"] == 1
def test_tree():
x = tree()
x["a"]["b"]["c"]["d"] = 1
assert "b" in x["a"]
assert "c" not in x["a"]
assert "c" in x["a"]["b"]
assert x["a"]["b"]["c"]["d"] == 1


def test_frozendict():
dct = frozendict({"hello": "world"})
assert dct["hello"] == "world"

with pytest.raises(KeyError, match="Cannot overwrite existing key"):
dct["key"] == "val"

with pytest.raises(KeyError, match="Cannot overwrite existing key"):
dct.update(key="value")


def test_namespace_dict():
dct = Namespace(foo="bar")
dct["hello"] = "world"
assert dct["key"] == "val"

with pytest.raises(KeyError, match="Cannot overwrite existing key"):
dct["key"] = "val"
with pytest.raises(KeyError, match="Cannot overwrite existing key"):
dct.update({"key": "val"})


def test_attr_dict():
dct = AttrDict(foo=1, bar=2)
assert dct.bar == 2
assert dct["foo"] is dct.foo
dct.bar = "hello"
assert dct["bar"] == "hello"


def test_frozen_attrdict():
dct = FrozenAttrDict({"hello": "world", 1: 2})
assert dct["hello"] == "world"
assert dct.hello == "world"

# Test adding item
with pytest.raises(KeyError, match="You cannot modify attribute"):
dct["foo"] = "bar"
with pytest.raises(KeyError, match="You cannot modify attribute"):
dct.foo = "bar"

# Test modifying existing item
with pytest.raises(KeyError, match="You cannot modify attribute"):
dct.hello = "new"

0 comments on commit 9b11922

Please sign in to comment.