Problem
Similar to previous questions, I would like to create a frozen/immutable dictionary. Specifically, after initialization, the user should get an ValueError
when trying to use the __delitem__
and __setitem__
methods.
Unlike the previous questions, I specifically want it to be a sub-class where the initialization type is constrained to a specific key and value type.
Attempted Solution
My own attempts at accomplishing this with collections.UserDict
failed:
class WorkflowParams(UserDict):
def __init__(self, __dict: Mapping[str, str]) -> None:
super().__init__(__dict=__dict)
def __setitem__(self, key: str, item: str) -> None:
raise AttributeError("WorkflowParams is immutable.")
def __delitem__(self, key: str) -> None:
raise AttributeError("WorkflowParams is immutable.")
When trying to use it:
workflow_parameters = WorkflowParams(
{
"s3-bucket": "my-big-bucket",
"input-val": "1",
}
)
It fails with
Traceback (most recent call last):
File "examples/python_step/python_step.py", line 38, in <module>
workflow_parameters = WorkflowParams(
File "/home/sean/git/scargo/scargo/core.py", line 14, in __init__
super().__init__(__dict=__dict)
File "/home/sean/miniconda3/envs/scargo/lib/python3.8/collections/__init__.py", line 1001, in __init__
self.update(kwargs)
File "/home/sean/miniconda3/envs/scargo/lib/python3.8/_collections_abc.py", line 832, in update
self[key] = other[key]
File "/home/sean/git/scargo/scargo/core.py", line 17, in __setitem__
raise AttributeError("WorkflowParams is immutable.")
AttributeError: WorkflowParams is immutable.
Because of how __init__()
resolves methods.
Disqualified Alternatives
Because of my need for a subclass, the commonly suggested solution of using MappingProxyType
doesn't meet my requirements.
Additionally, I'm suspicious of answers which recommend subclassing dict
, since this seems to cause some unintended behaviour.