A context manager for managing scope-specific values using a stack-based approach.
Stackholm is a lightweight Python package for handling context data efficiently. It allows storing and retrieving values in a stack-based manner, ensuring values remain scoped to their respective contexts.
- Supports single-threaded, multi-threaded, asynchronous, and ASGI environments.
- Indexed storage for fast lookups.
- Zero-copy data sharing across nested contexts.
- Scopes can be nested within functions or methods, beyond block-level restrictions.
The package is available on PyPI, and can
be installed using any compatible package manager such as pip
:
pip install stackholm
Stackholm requires a storage class to manage context data. Different storage classes are available for various environments.
Use OptimizedListStorage
for single-threaded applications. This class
utilizes indexing for efficient lookups.
import stackholm
# Create a context class using optimized list storage.
storage = stackholm.OptimizedListStorage()
Context = storage.create_context_class()
# Create a context (checkpoint).
with Context():
# Set a value in the current context.
Context.set_checkpoint_value("a", 1)
# Output: 1
print(Context.get_checkpoint_value("a"))
# Create another context/checkpoint nested within the current context.
with Context() as inner_context:
# In this scope, the current context is the `inner_context`.
# The values from upper contexts are accessible in the current context.
# Output: 1
print(Context.get_checkpoint_value("a"))
# Mutates the value of `"a"`, only for the current context.
Context.set_checkpoint_value("a", 2)
# Output: 2
print(Context.get_checkpoint_value("a"))
# Back to the previous context.
# Output: 1
print(Context.get_checkpoint_value("a"))
# The context is closed, and the values are no longer accessible.
# Raises `stackholm.NoContextIsActive` exception.
Context.get_checkpoint_value("a")
Use ThreadLocalStorage
for multi-threaded applications. It extends
OptimizedListStorage
and leverages Python’s built-in threading.local
class to store and retrieve context data.
import stackholm
storage = stackholm.ThreadLocalStorage()
Context = storage.create_context_class()
For more information on threading.local
, refer to the
official documentation.
Use ContextVarStorage
for asynchronous applications. It extends
OptimizedListStorage
and leverages the built-in
contextvars.ContextVar
class to store and retrieve context data.
from contextvars import ContextVar
import stackholm
# Create a `ContextVar` instance for storing the context data.
STORAGE_STATE_VAR: ContextVar[stackholm.State] = ContextVar("STORAGE_STATE_VAR")
# Pass the `ContextVar` instance to the `ContextVarStorage` constructor.
storage = stackholm.ContextVarStorage(STORAGE_STATE_VAR)
Context = storage.create_context_class()
For more information on using ContextVar
with asynchronous applications,
refer to the
official documentation.
Use ASGIRefLocalStorage
for ASGI applications. It extends
OptimizedListStorage
and utilizes ASGI reference local storage for storing
and retrieving context data.
import stackholm
storage = stackholm.ASGIRefLocalStorage()
Context = storage.create_context_class()
Stackholm is used in revy, a re-usable Django application for building revision control systems. It tracks data changes and manages context-related information in a fast and efficient way.
This project is licensed under the MIT License.
See the LICENSE file for more details.