Skip to content

Commit

Permalink
more human readable error message
Browse files Browse the repository at this point in the history
  • Loading branch information
DanielYang59 committed Nov 27, 2024
1 parent 74c4fd2 commit c2d3c20
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 46 deletions.
50 changes: 13 additions & 37 deletions src/monty/collections.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ def __init__(self, *args, **kwargs):
"""Temporarily allow all add/update during initialization."""
original_allow_add = self.allow_add
original_allow_update = self.allow_update

try:
self.allow_add = True
self.allow_update = True
Expand All @@ -80,19 +81,13 @@ def __init__(self, *args, **kwargs):
self.allow_add = original_allow_add
self.allow_update = original_allow_update

# TODO: extract checkers

# Overriding add/update operations
# Override add/update operations
def __setitem__(self, key, value):
"""Forbid adding or updating keys based on allow_add and allow_update."""
if key not in self.data and not self.allow_add:
raise TypeError(
f"Cannot add new key {key!r}, because allow_add is set to False."
)
raise TypeError(f"Cannot add new key {key!r}, because add is disabled.")
elif key in self.data and not self.allow_update:
raise TypeError(
f"Cannot update key {key!r}, because allow_update is set to False."
)
raise TypeError(f"Cannot update key {key!r}, because update is disabled.")

super().__setitem__(key, value)

Expand All @@ -101,11 +96,11 @@ def update(self, *args, **kwargs):
for key in dict(*args, **kwargs):
if key not in self.data and not self.allow_add:
raise TypeError(
f"Cannot add new key {key!r} using update, because allow_add is set to False."
f"Cannot add new key {key!r} using update, because add is disabled."
)
elif key in self.data and not self.allow_update:
raise TypeError(
f"Cannot update key {key!r} using update, because allow_update is set to False."
f"Cannot update key {key!r} using update, because update is disabled."
)

super().update(*args, **kwargs)
Expand All @@ -119,16 +114,16 @@ def setdefault(self, key, default=None):
if key not in self.data:
if not self.allow_add:
raise TypeError(
f"Cannot add new key using setdefault: {key!r}, because allow_add is set to False."
f"Cannot add new key using setdefault: {key!r}, because add is disabled."
)
elif not self.allow_update:
raise TypeError(
f"Cannot update key using setdefault: {key!r}, because allow_update is set to False."
f"Cannot update key using setdefault: {key!r}, because update is disabled."
)

return super().setdefault(key, default)

# Overriding delete operations
# Override delete operations
def __delitem__(self, key):
"""Forbid deleting keys when self.allow_del is False."""
if not self.allow_del:
Expand Down Expand Up @@ -165,31 +160,12 @@ class frozendict(ControlledDict):
allow_update: ClassVar[bool] = False


class Namespace(dict): # TODO: this name is a bit confusing, deprecate it?
class Namespace(ControlledDict): # TODO: this name is a bit confusing, deprecate it?
"""A dictionary that does not permit changing its values."""

def __init__(self, *args, **kwargs) -> None:
"""
Args:
args: Passthrough arguments for standard dict.
kwargs: Passthrough keyword arguments for standard dict.
"""
self.update(*args, **kwargs)

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

dict.__setitem__(self, key, val)

def update(self, *args, **kwargs) -> None:
"""
Args:
args: Passthrough arguments for standard dict.
kwargs: Passthrough keyword arguments for standard dict.
"""
for k, v in dict(*args, **kwargs).items():
self[k] = v
allow_add: ClassVar[bool] = True
allow_del: ClassVar[bool] = True
allow_update: ClassVar[bool] = False


class AttrDict(dict):
Expand Down
18 changes: 9 additions & 9 deletions tests/test_collections.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,13 +43,13 @@ def test_add_disabled(self):
dct = ControlledDict(a=1)
dct.allow_add = False

with pytest.raises(TypeError, match="allow_add is set to False"):
with pytest.raises(TypeError, match="add is disabled"):
dct["b"] = 2

with pytest.raises(TypeError, match="allow_add is set to False"):
with pytest.raises(TypeError, match="add is disabled"):
dct.update(b=2)

with pytest.raises(TypeError, match="allow_add is set to False"):
with pytest.raises(TypeError, match="add is disabled"):
dct.setdefault("c", 2)

def test_update_allowed(self):
Expand All @@ -69,13 +69,13 @@ def test_update_disabled(self):
dct = ControlledDict(a=1)
dct.allow_update = False

with pytest.raises(TypeError, match="allow_update is set to False"):
with pytest.raises(TypeError, match="update is disabled"):
dct["a"] = 2

with pytest.raises(TypeError, match="allow_update is set to False"):
with pytest.raises(TypeError, match="update is disabled"):
dct.update({"a": 3})

with pytest.raises(TypeError, match="allow_update is set to False"):
with pytest.raises(TypeError, match="update is disabled"):
dct.setdefault("a", 4)

def test_del_allowed(self):
Expand Down Expand Up @@ -133,11 +133,11 @@ def test_frozendict():
assert not dct.allow_del

# Test setter
with pytest.raises(TypeError, match="allow_add is set to False"):
with pytest.raises(TypeError, match="add is disabled"):
dct["key"] = "val"

# Test update
with pytest.raises(TypeError, match="allow_add is set to False"):
with pytest.raises(TypeError, match="add is disabled"):
dct.update(key="val")

# Test pop
Expand All @@ -151,7 +151,7 @@ def test_frozendict():

def test_namespace_dict():
dct = Namespace(key="val")
assert isinstance(dct, dict)
assert isinstance(dct, UserDict)
dct["hello"] = "world"
assert dct["key"] == "val"

Expand Down

0 comments on commit c2d3c20

Please sign in to comment.