Reject invalid updates in a small UserDict wrapper
collections.UserDict is useful when a mapping needs a narrow rule at every ordinary write. Its actual contents live in the data attribute, while its mapping methods can be customized. BoundedSettings overrides __setitem__ so construction, item assignment, and update() all pass through one validator.
The wrapper accepts only threshold and retries. Both values must have type int; using type(value) is int intentionally rejects True and False, even though booleans are subclasses of int. Thresholds are restricted to 0 through 100, and retries to 0 through 5. The invalid update({"threshold": 101}) raises ValueError before storing 101. The unknown mode key raises KeyError. The final assertion confirms that the accepted retry update did not disturb the previous threshold.
This is a small boundary around mapping writes, not a complete configuration system. UserDict.data is public; code that mutates settings.data directly bypasses __setitem__ and therefore bypasses validation. The class also does not coerce strings such as "3" to integers or provide transaction-like all-or-nothing behavior for a multi-item update if a later item fails. Add explicit parsing or a staged-copy strategy when those policies are needed.
AI assistance contributed to this draft.
Source: Python UserDict documentation
Example
from collections import UserDict
class BoundedSettings(UserDict):
allowed = {"threshold", "retries"}
def __setitem__(self, key, value):
if key not in self.allowed:
raise KeyError(f"unsupported setting: {key}")
if type(value) is not int:
raise TypeError("setting values must be integers")
if key == "threshold" and not 0 <= value <= 100:
raise ValueError("threshold must be 0..100")
if key == "retries" and not 0 <= value <= 5:
raise ValueError("retries must be 0..5")
self.data[key] = value
settings = BoundedSettings({"threshold": 75, "retries": 2})
try:
settings.update({"threshold": 101})
except ValueError as error:
print(error)
try:
settings["mode"] = 1
except KeyError as error:
print(error.args[0])
settings["retries"] = 3
assert dict(settings) == {"threshold": 75, "retries": 3}
print(dict(settings))
Expected stdout
threshold must be 0..100
unsupported setting: mode
{'threshold': 75, 'retries': 3}
Comments
Post a Comment