"""Finesse datastore tools.
The datastore is intended for objects that should be cached during the execution of the
current Python kernel. Code typically uses this instead of the more bug-prone singleton
pattern (see #260).
"""
_DATASTORE = {}
[docs]def invalidate(key=None):
"""Invalidate the datastore.
Parameters
----------
key : str, optional
The datastore key to invalidate. If None, the whole datastore is invalidated.
"""
if key is None:
_DATASTORE.clear()
else:
del _DATASTORE[key]
[docs]def getfield(key):
"""Get value with key `key`.
Parameters
----------
key : any
The key.
Returns
-------
any
The value.
"""
return _DATASTORE[key]
[docs]def setfield(key, value, overwrite=False):
"""Initialize a field with key `key` and value `value`.
Parameters
----------
key : any
The key. If it already exists in the datastore,
value : any
The value.
Returns
-------
any
The value.
"""
if not overwrite and hasfield(key):
raise ValueError(
f"{repr(key)} already exists in datastore. Set overwrite=True to force."
)
_DATASTORE[key] = value
return getfield(key)
[docs]def hasfield(key):
"""Determine if the datastore key `key` exists.
Parameters
----------
key : any
The singeton class to check.
Returns
-------
bool
True if `key` exists, False otherwise.
"""
return key in _DATASTORE
[docs]def init_singleton(cls, *args, **kwargs):
"""Instantiate `cls` and return the object for the current and future calls.
Parameters
----------
cls : type
The singeton class to retrieve. If `cls` has already been instantiated, the
existing instance is returned and `args` and `kwargs` are ignored.
Other Parameters
----------------
args, kwargs
Positional and keyword arguments to pass to the `cls` call, to use if `cls` is
not yet instantiated.
Returns
-------
object
The instantiated singleton.
"""
if not hasfield(cls):
setfield(cls, cls(*args, **kwargs))
return _DATASTORE[cls]