Skip to main content

Type or key restricted and resettable dictionary

Project description

rsdict

Actions Badge - Python package PyPI version Downloads

rsdict is a restricted and resetable dictionary, a subclass of dict (inherits from built-in dictionary).

>>> from rsdict import rsdict

>>> d = {"foo": 0, "bar": "baz"}
>>> rd = rsdict(d)
>>> rd
rsdict({'foo': 0, 'bar': 'baz'}, frozen=False, fixkey=True, fixtype=True, cast=False)

# fixkey=True: key restriction
>>> rd["newkey"] = 1
AttributeError
# fixtype=True: type restriction
>>> rd["foo"] = "str.value"
TypeError

>>> rd["foo"] = 999
>>> rd == d
False
# reset values to initial
>>> rd.reset()
>>> rd == d
True

Installation

pip install rsdict

Features

  • Type-restrict(able): If activated, every type of value is fixed to its initial type.
  • Key-restrict(able): If activated, cannot add or delete keys.
  • Resettable: to initial value(s).

Arguments

rsdict(items, frozen=False, fixkey=True, fixtype=True, cast=False)

  • items (dict): Initial items (data). Built-in dictionary only. kwargs are not supported.
  • frozen (bool, optional): If True, the instance will be frozen (immutable).
  • fixkey (bool, optional): If True, cannot add or delete keys.
  • fixtype (bool, optional): If True, cannot change type of keys.
  • cast (bool, optional): If False, cast to initial type (if possible). If True, allow only the same type of initial value.

Subclasses

# rsdict(frozen=True) as default
from rsdict import rsdict_frozen as rsdict

# rsdict(fixkey=False, fixtype=False) as default
from rsdict import rsdict_unfix as rsdict

# rsdict(fixkey=True, fixtype=False) as default
from rsdict import rsdict_fixkey as rsdict

# rsdict(fixkey=False, fixtype=True) as default
from rsdict import rsdict_fixtype as rsdict

Additional methods

  • set(key, value): Alias of __setitem__.
  • to_dict() -> dict: Convert to dict instance.
  • reset(key: Optional[Any]) -> None: Reset value to the initial value. If key is None, reset all values.
  • is_changed(key: Optional[Any]) -> bool: If True, the values are changed from initial. If key is not None, check the key only.
  • get_initial(key: Optional[Any]) -> dict | Any: Return initial value(s). If key is None, Return dict of all initial values.

Examples

Create (Initialize)

>>> from rsdict import rsdict

>>> d = dict(
...     name = "John",
...     enable = True,
...     count = 0,
... )
>>> rd = rsdict(d)
>>> rd
rsdict({'name': 'John', 'enable': True, 'count': 0},
        frozen=False, fixkey=True, fixtype=False)

>>> type(rd) is dict
False
>>> isinstance(rd, dict)
True
>>> rd.frozen
False

Get

Same as dict.

>>> rd["count"] == d["count"]
True
>>> rd["xyz"]
KeyError

>>> rd.get("count") == d.get("count")
True
>>> rd.get("xyz")
None

Set

>>> rd["enable"] = False
>>> rd.set("enable", False)
# If frozen, always raise an exception.
>>> rd_frozen = rsdict(d, frozen=True)
>>> rd_frozen["count"] = 2
AttributeError
# If fixtype and not cast, different-type value raise an exception.
>>> rd["count"] = "2"
TypeError

# If fixtype and cast, cast value to initial type.
>>> rd_cast = rsdict(d, cast=True)
>>> rd_cast["count"] = "2"
>>> rd_cast["count"]
2
>>> rd_cast["count"] = "abc"
ValueError

# If not fixtype, anything can be set.
>>> rd_typefree = rsdict(d, fixtype=False)
>>> rd_typefree["count"] = "2"
>>> rd_typefree["count"]
'2'
# If fixkey, setting with a new key raises an exception.
>>> rd["location"] = 9
AttributeError

# If not fixkey, a new key can be set.
>>> rd_keyfree = rsdict(d, fixkey=False)
>>> rd_keyfree["location"] = 9
>>> rd_keyfree["location"]
9

Delete

# If frozen or fixkey, deleting key raises an exception.
>>> del rd["count"]
AttributeError

# Else, delete both current and initial values.
>>> rd_keyfree = rsdict(dict(a=1, b=2, c=3), fixkey=False)
>>> del rd_keyfree["b"]
>>> rd_keyfree.keys()
dict_keys(['a', 'c'])
>>> rd_keyfree.get_initial().keys()
dict_keys(['a', 'c'])

Reset

# Check whether the values are changed from initial.
>>> rd.is_changed()
False
# (Change some values.)
>>> rd["enable"] = False
>>> rd["count"] = 5
>>> rd.is_changed()
True

# Reset with a key.
>>> rd.reset("count")
>>> rd["count"]
0
>>> rd.is_changed()
True

# Reset all values.
>>> rd.reset()
>>> rd.is_changed()
False

Copy

# Create a new rsdict with different optional arguments.
# If reset, copy initial values only.
>>> rd["name"] = "Mike"
>>> rd2 = rd.copy(reset=True)
>>> rd2 == rd.get_initial()
True

# If frozen and not reset, copy current values as new initial values.
>>> rd3 = rd.copy(frozen=True)
>>> rd3
rsdict({'name': 'Mike', 'enable': True, 'count': 0},
    frozen=True, fixkey=True, fixtype=False, cast=False)
>>> rd3 == rd
True
>>> rd3.get_initial() == rd.get_initial()
False

Compare

>>> rd1 = rsdict({"key1": 10, "key2": "abc"})
>>> rd2 = rsdict({"key1": 20, "key2": "abc"})
# Change current value.
>>> rd2["key1"] = 10

# Current values are equal.
>>> rd1 == rd2
True

# Initial values are not equal.
>>> rd1.get_initial() == rd2.get_initial()
False

# If compare with dict, use current values.
>>> d2 = rd2.to_dict()
>>> rd2 == d2

Union

(Python3.9 or later)

>>> rd = rsdict({"key1": 10, "key2": "abc"}, fixkey=False)
>>> d = {"key2": 20, "key3": False}

# Return: dict
>>> rd | d
{'key1': 10, 'key2': 20, 'key3': False}
>>> d | rd
{'key2': 'abc', 'key3': False, 'key1': 10}

>>> rd |= d
>>> rd
rsdict({'key1': 10, 'key2': 20, 'key3': False},
    frozen=False, fixkey=False, fixtype=True, cast=False)
# Add initial values of new keys only.
>>> rd.get_initial()
{'key1': 10, 'key2': 'abc', 'key3': False}

Note

>>> d = dict(a=[1])
>>> rd = rsdict(d)
>>> rd["a"].append(2)
>>> rd
rsdict({'a': [1, 2]}, frozen=False, fixkey=True, fixtype=True, cast=False)
>>> d
{'a': [1, 2]}
>>> rd.get_initial()
{'a': [1]}

Performance

rsdict is slower than dict due to its additional checking.

Image: https://github.com/kihiyuki/python-rsdict/blob/main/docs/img/speed.png

Changelog

-> CHANGELOG.md

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

rsdict-0.1.8.tar.gz (9.6 kB view details)

Uploaded Source

Built Distribution

rsdict-0.1.8-py3-none-any.whl (8.1 kB view details)

Uploaded Python 3

File details

Details for the file rsdict-0.1.8.tar.gz.

File metadata

  • Download URL: rsdict-0.1.8.tar.gz
  • Upload date:
  • Size: 9.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.7.1 importlib_metadata/4.10.1 pkginfo/1.8.2 requests/2.27.1 requests-toolbelt/0.9.1 tqdm/4.62.3 CPython/3.9.10

File hashes

Hashes for rsdict-0.1.8.tar.gz
Algorithm Hash digest
SHA256 d2990fc787da362c913508492bb3ddff66c683c4a725a3c28022242a8d79c797
MD5 531ac769ea3c9d93efe8a046449fd2ca
BLAKE2b-256 0b67ecd3489b3daf011d4f82ed7331e1b66ccbbadefeefb203ce1ac541dadd4a

See more details on using hashes here.

File details

Details for the file rsdict-0.1.8-py3-none-any.whl.

File metadata

  • Download URL: rsdict-0.1.8-py3-none-any.whl
  • Upload date:
  • Size: 8.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.7.1 importlib_metadata/4.10.1 pkginfo/1.8.2 requests/2.27.1 requests-toolbelt/0.9.1 tqdm/4.62.3 CPython/3.9.10

File hashes

Hashes for rsdict-0.1.8-py3-none-any.whl
Algorithm Hash digest
SHA256 746c12d16ac7015bd4f9c3817f4d858811b9f5ed5c55c2783c68fce4328401e2
MD5 c0d7574a027740b5057a6ffc210ef412
BLAKE2b-256 787b17022e37a08bcfa95bb0a5508881796d65befbf28c9f0bbfa59fd9013539

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page