Coverage for src/shephex/experiment/result.py: 100%

43 statements  

« prev     ^ index     » next       coverage.py v7.6.1, created at 2025-06-20 14:13 +0200

1from dataclasses import dataclass 

2from pathlib import Path 

3from typing import Any, Literal, Union 

4 

5import dill 

6 

7 

8class ExperimentError(Exception): 

9 def __init__(self, message: str) -> None: 

10 self.message = message 

11 super().__init__(self.message) 

12 

13 

14@dataclass 

15class ExperimentResult: 

16 result: Union[Any, ExperimentError] 

17 status: Literal['completed', 'failed'] 

18 name: str = 'result' 

19 extension: str = 'pkl' 

20 info: Any = None 

21 

22 def __post_init__(self) -> None: 

23 if self.status not in ['completed', 'failed']: 

24 raise ValueError(f'Invalid status: {self.status}') 

25 

26 @staticmethod 

27 def get_path( 

28 directory: Union[Path, str], name: str = 'result', extension: str = 'pkl' 

29 ) -> Path: 

30 path = Path(directory) / f'{name}.{extension}' 

31 return path 

32 

33 def dump(self, directory: Union[str, Path]) -> None: 

34 path = self.get_path(directory, self.name, self.extension) 

35 with open(path, 'wb') as f: 

36 dill.dump(self, f) 

37 return 

38 

39 @classmethod 

40 def load( 

41 cls, directory: Union[Path, str], name: str = 'result', extension: str = 'pkl' 

42 ) -> 'ExperimentResult': 

43 path = cls.get_path(directory, name, extension) 

44 with open(path, 'rb') as f: 

45 result = dill.load(f) 

46 return result 

47 

48 

49class FutureResult(ExperimentResult): 

50 

51 def __init__( 

52 self, name: str = 'future', extension: str = 'pkl', info: Any = None 

53 ) -> None: 

54 super().__init__(None, 'pending', name, extension, info) 

55 

56 def __post_init__(self) -> None: 

57 pass 

58 

59 

60 

61class DryResult(ExperimentResult): 

62 def __init__( 

63 self, name: str = 'dry', extension: str = 'pkl', info: Any = None 

64 ) -> None: 

65 super().__init__(None, 'dry', name, extension, info) 

66 

67 def __post_init__(self) -> None: 

68 pass