Developer Tools#
System-level utilities used across spey.
The spey.system subpackage groups infrastructure that is not part of
the statistical-model API itself but is needed to operate it:
spey.system.logger— coloured logger setup and acapture_logs()context manager that deduplicates noisy messages emitted from hot loops.spey.system.exceptions— package-specific exception classes (e.g.PluginError,NegativeExpectedYields).spey.system.cache—cache_results(), a thread-safe, mutable-argument-aware decorator with per-instance support.spey.system.webutils— small HTTP helpers for retrieving BibTeX entries and checking for newspeyreleases on PyPI.
Exceptions#
Analysis query exception |
|
If the method is not available for a given backend |
|
Negative expected yields exception |
|
Invalid plugin exception |
|
Unknown cross-section exception |
|
Unknown test statistics exception |
|
Unavailable calculator Exception |
|
Unable to find roots of the function |
|
Unknown computation base |
|
Unavailable combination routine exception |
Logging#
Temporary disable logging implementation |
|
Context manager that captures log records emitted while inside the context and suppresses duplicate messages. |
Caching#
Thread-safe, mutable-argument-aware function result cache.
Provides cache_results(), a decorator that caches function return
values keyed on both positional and keyword arguments. Unlike
functools.lru_cache(), it handles non-hashable inputs (NumPy arrays,
lists, dicts, etc.) by building a deterministic cache key from a deep,
content-based representation of every argument.
Cache key construction#
Each argument is converted to a hashable token via _make_token():
Hashable scalars (
int,float,str, …) -> used directly.numpy.ndarray->(shape, dtype, sha256_digest)tuple built from a SHA-256 hash of the raw buffer so the key captures the full content without retaining a copy of the array bytes.list/tuple-> recursively tokenised element-by-element.dict-> sorted-items tuple of(key_token, value_token)pairs.Anything else -> falls back to
repr().
The final key is a (args_token, sorted_kwargs_token) tuple that is
hashed by a standard Python dict.
Thread safety#
A threading.Lock serialises reads and writes to the internal
cache dict. To prevent thundering-herd duplicate computation, a
sentinel is inserted under the key before the decorated function
runs. A per-key threading.Event is used so that concurrent
callers block efficiently (no busy-wait) until the real result is stored.
Each unique input is computed exactly once even under contention.
Per-instance caching#
When cache_results is applied to an instance method (first parameter
named self), it automatically returns a
_PerInstanceCacheDescriptor. This can also be requested
explicitly via per_instance=True. The descriptor installs a dedicated
cached callable on each instance the first time the method is accessed,
ensuring that two distinct instances of the same class (or of different
subclasses) can never share a cache entry. self is never included in
the cache key and no reference to the instance is held in the cache
dictionary.
For classes that use __slots__ without __dict__, the descriptor
falls back to a descriptor-level mapping keyed by id(obj). If the
instance supports weak references, cleanup is automatic; otherwise the
mapping entry persists for the lifetime of the descriptor (bounded and
equivalent to the prior behaviour).
|
Decorator that caches function results for identical arguments. |
|
Non-data descriptor that provides per-instance caching for instance methods. |