"""Utility functions."""
import functools
import hashlib
import time
import warnings
from typing import Any, Callable
import libsbml
[docs]class FrozenClass(object):
"""FrozenClass.
After freezing no additional attributes can be added.
"""
[docs] __isfrozen: bool = False
[docs] def __setattr__(self, key: str, value: Any) -> None:
"""Attribute setter."""
if self.__isfrozen and not hasattr(self, key):
raise AttributeError(
f"{self} is a frozen class, no new attributes. But "
f"trying to set `{key} = {value}`."
)
object.__setattr__(self, key, value)
[docs] def _freeze(self) -> None:
self.__isfrozen = True
[docs]def create_hash_id(sbase: libsbml.SBase) -> str:
"""Create hash code."""
# FIXME: issues with assignment rules in pancreas model
# print(f"create_hashcode for sbase: '{sbase}'")
# print(sbase.getId())
if sbase and hasattr(sbase, "getId") and sbase.isSetId():
hash_key = sbase.getId()
else:
# hash the xml_node
xml_node: libsbml.XMLNode = sbase.toXMLNode()
xml_str = xml_node.toString().encode("utf-8")
# print(f"xml_str -> {xml_node} -> {xml_str}" )
hash_key = hashlib.md5(xml_str).hexdigest()
# print(f"-> {hash_key}")
return hash_key # type: ignore
[docs]def timeit(f: Callable) -> Callable:
"""Decorate function with timing information.
:param f: function to time
:return:
"""
def timed(*args: Any, **kwargs: Any) -> Any:
ts = time.time()
result = f(*args, **kwargs)
te = time.time()
print(
"func:%r args:[%r, %r] took: %2.4f sec"
% (f.__name__, args, kwargs, te - ts)
)
return result
return timed
[docs]def deprecated(f: Callable) -> Callable:
"""Decorate function as deprecated.
This is a decorator which can be used to mark functions
as deprecated. It will result in a warning being emitted
when the function is used.
"""
@functools.wraps(f)
def new_func(*args: Any, **kwargs: Any) -> Any:
warnings.warn_explicit(
f"Call to deprecated function {f.__name__}.",
category=DeprecationWarning,
filename=f.func_code.co_filename, # type: ignore
lineno=f.func_code.co_firstlineno + 1, # type: ignore
)
return f(*args, **kwargs)
return new_func