Source code for yaflux._portable

import types
from typing import Any, Dict, List

from ._base import Base
from ._results import Results


[docs] class Portable(Base): """ A self-contained analysis container that can be unpickled without the original class. Preserves the step metadata and results while dropping the actual implementation. """ def __init__( self, parameters: Any, results: Dict[str, Any], completed_steps: List[str], step_metadata: Dict[str, Dict[str, List[str]]], ): # Initialize Base with parameters super().__init__(parameters) # Override Results with provided data self._results = Results() self._results._data = results # Set completed steps self._completed_steps = set(completed_steps) # Store step metadata self._step_metadata = step_metadata # Create placeholder methods for each original step for step_name, metadata in step_metadata.items(): placeholder = self._create_placeholder(step_name, metadata) setattr(self, step_name, types.MethodType(placeholder, self)) def _create_placeholder(self, name: str, metadata: Dict[str, List[str]]): """Create a placeholder method that raises NotImplementedError.""" def placeholder(self): raise NotImplementedError( f"Step '{name}' is a placeholder. This is a portable snapshot " f"that contains only results and metadata.\n" f"creates: {metadata['creates']}\n" f"requires: {metadata['requires']}" ) return placeholder @property def available_steps(self) -> List[str]: """List of all steps that were available in original analysis.""" return list(self._step_metadata.keys())
[docs] @classmethod def from_analysis(cls, analysis: Base) -> "Portable": """Create a portable version from an existing analysis.""" metadata = {} for name in analysis.available_steps: method = getattr(analysis.__class__, name) metadata[name] = {"creates": method.creates, "requires": method.requires} return cls( parameters=analysis.parameters, results=analysis.results._data, completed_steps=analysis.completed_steps, step_metadata=metadata, )
[docs] @classmethod def load(cls, filepath: str) -> "Portable": """Load a portable analysis from a file. Overrides the base class by explicitly loading as Portable. """ from ._loaders import load_analysis return load_analysis(Portable, filepath)