Coverage for wasmtime/_managed.py: 89%

38 statements  

« prev     ^ index     » next       coverage.py v7.6.12, created at 2025-02-20 16:25 +0000

1from abc import abstractmethod 

2from typing import TypeVar, Generic, Any, Optional 

3 

4T = TypeVar('T') 

5 

6class Managed(Generic[T]): 

7 """ 

8 Abstract base class for types which contain an owned pointer in the C FFI 

9 layer. 

10 

11 Not exported directly from this package. 

12 """ 

13 __ptr: Optional[T] 

14 

15 @abstractmethod 

16 def _delete(self, ptr: T) -> None: 

17 """ 

18 Runs the FFI destructor for the `ptr` specified. 

19 

20 Must be implemented by classes that inherit from this class. 

21 """ 

22 pass 

23 

24 def _set_ptr(self, ptr: T) -> None: 

25 if hasattr(self, '__ptr'): 

26 raise ValueError('already initialized') 

27 self.__ptr = ptr 

28 

29 def close(self) -> None: 

30 """ 

31 Closes this object, or deallocates it. Further usage of this object 

32 will raise a `ValueError`. 

33 """ 

34 

35 # Get the pointer's value but don't worry if it was never set. 

36 try: 

37 ptr = self.__ptr 

38 except AttributeError: 

39 return 

40 

41 # If it wasn't previously deallocated then do so here, otherwise ignore 

42 # this repeated call to `close` 

43 if ptr is not None: 

44 self._delete(ptr) 

45 self.__ptr = None 

46 

47 def ptr(self) -> T: 

48 """ 

49 Returns the underlying pointer for this FFI object, or a `ValueError` 

50 if it's already been closed. 

51 """ 

52 

53 # Fail with a `ValueError` if the pointer was never set 

54 try: 

55 ptr = self.__ptr 

56 except AttributeError: 

57 raise ValueError('never initialized') 

58 

59 # Check to see if this object is already deallocated, and if so raise 

60 # a specific exception 

61 if ptr is not None: 

62 return ptr 

63 else: 

64 raise ValueError('already closed') 

65 

66 def _consume(self) -> T: 

67 """ 

68 Internal method to take ownership of the internal pointer without 

69 destroying it. 

70 """ 

71 ret = self.ptr() 

72 self.__ptr = None 

73 return ret 

74 

75 def __enter__(self) -> Any: 

76 """ 

77 Entry part of the contextlib protocol to enable using this object with 

78 `with`. 

79 

80 Returns `self` to bind to use within a `with` block. 

81 """ 

82 return self 

83 

84 def __exit__(self, *exc: Any) -> None: 

85 """ 

86 Exit part of the contextlib protocol to call `close`. 

87 """ 

88 self.close() 

89 

90 def __del__(self) -> None: 

91 """ 

92 Automatic destruction of the internal FFI object if it's still alive by 

93 this point. 

94 """ 

95 self.close()