paperap.models.abstract.meta module
Provide context management for model status transitions.
The module implements a context manager that safely handles model status changes during operations like saving or updating. It ensures proper status transitions and resource locking to maintain data integrity throughout the lifecycle of model operations.
Examples
Basic usage to temporarily change a model’s status:
>>> with StatusContext(model, ModelStatus.UPDATING):
... # Perform operations that require the model to be in UPDATING status
... model.update_field("value")
Using StatusContext in a model method:
>>> def save(self):
... with StatusContext(self, ModelStatus.SAVING):
... # Perform save operation
... self._save_to_api()
- class paperap.models.abstract.meta.StatusContext(model, new_status)[source]
Bases:
object
Manage model status changes safely with proper resource locking.
Provides a mechanism to temporarily change the status of a model while ensuring the previous status is restored upon completion. Handles acquisition and release of save locks to prevent concurrent modifications that could lead to data inconsistency.
When used as a context manager, StatusContext will: 1. Optionally acquire a save lock if the new status is SAVING 2. Store the model’s current status 3. Set the model’s status to the new status 4. Execute the context body 5. Restore the original status when exiting 6. Release any acquired locks
- model
The model whose status is being managed.
- Type:
BaseModel
- new_status
The status to set within the context.
- Type:
ModelStatus
- previous_status
The status before entering the context.
- Type:
ModelStatus | None
Examples
Using StatusContext in a model method:
>>> class SomeModel(BaseModel): ... def perform_update(self): ... with StatusContext(self, ModelStatus.UPDATING): ... # Perform an update operation ... self._update_remote_data()
Using StatusContext with error handling:
>>> try: ... with StatusContext(model, ModelStatus.SAVING): ... # Attempt to save the model ... model._save_to_api() ... except APIError: ... # The model's status will be restored even if an error occurs ... print("Failed to save model")
- Parameters:
model (
BaseModel
)new_status (
ModelStatus
)
- property model: BaseModel
Get the model associated with this context.
- Returns:
The model whose status is being managed.
- Return type:
- property new_status: ModelStatus
Get the status that will be set within this context.
- Returns:
The status to set within the context.
- Return type:
- property previous_status: ModelStatus | None
Get the status that was set before entering this context.
- Returns:
The previous status, or None if not yet entered.
- Return type:
ModelStatus | None
- __init__(model, new_status)[source]
Initialize the StatusContext with a model and target status.
- Parameters:
model (
BaseModel
) – The model whose status will be temporarily changed.new_status (
ModelStatus
) – The status to set while in this context.
- save_lock()[source]
Acquire the save lock for the model.
Acquires the model’s save lock to ensure that no other operations can modify the model while the status is being updated. The lock is implemented as a threading.RLock to allow reentrant locking from the same thread. :rtype:
None
Note
This method sets the internal _save_lock_acquired flag to True when successful, which is used to determine if unlock is needed later.
- save_unlock()[source]
Release the save lock for the model.
Releases the model’s save lock if it was acquired by this context manager, allowing other operations to modify the model. The lock is only released if it was previously acquired by this specific StatusContext instance. :rtype:
None
Note
This method checks the internal _save_lock_acquired flag to ensure it only releases locks that it has acquired.
- __enter__()[source]
Enter the context, updating the model’s status.
Performs the following operations: 1. Acquires the save lock if the new status is ModelStatus.SAVING 2. Stores the model’s current status for later restoration 3. Sets the model’s status to the new status :rtype:
None
Note
This method intentionally returns None instead of self to prevent direct access to the context manager, ensuring proper status reversion.
- __exit__(exc_type, exc_value, traceback)[source]
Exit the context, restoring the model’s previous status.
Performs the following cleanup operations: 1. Restores the model’s status to its previous value 2. Sets status to ModelStatus.ERROR if no previous status was recorded 3. Releases the save lock if it was acquired
Ensures proper cleanup even if an exception occurred within the context.
- Parameters:
exc_type (
type[BaseException] | None
) – The exception type, if any.exc_value (
BaseException | None
) – The exception value, if any.traceback (
Iterable[Any]
) – The traceback information, if any.
- Return type:
Note
This method does not suppress exceptions; they will propagate normally.
Examples
Handling exceptions while using StatusContext:
>>> try: ... with StatusContext(model, ModelStatus.PROCESSING): ... raise ValueError("Something went wrong") ... except ValueError: ... # The model's status will be restored before this exception handler runs ... print("Error occurred, but model status was properly restored")