Coverage for wasmtime/_managed.py: 89%
38 statements
« prev ^ index » next coverage.py v7.6.12, created at 2025-02-20 16:25 +0000
« 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
4T = TypeVar('T')
6class Managed(Generic[T]):
7 """
8 Abstract base class for types which contain an owned pointer in the C FFI
9 layer.
11 Not exported directly from this package.
12 """
13 __ptr: Optional[T]
15 @abstractmethod
16 def _delete(self, ptr: T) -> None:
17 """
18 Runs the FFI destructor for the `ptr` specified.
20 Must be implemented by classes that inherit from this class.
21 """
22 pass
24 def _set_ptr(self, ptr: T) -> None:
25 if hasattr(self, '__ptr'):
26 raise ValueError('already initialized')
27 self.__ptr = ptr
29 def close(self) -> None:
30 """
31 Closes this object, or deallocates it. Further usage of this object
32 will raise a `ValueError`.
33 """
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
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
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 """
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')
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')
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
75 def __enter__(self) -> Any:
76 """
77 Entry part of the contextlib protocol to enable using this object with
78 `with`.
80 Returns `self` to bind to use within a `with` block.
81 """
82 return self
84 def __exit__(self, *exc: Any) -> None:
85 """
86 Exit part of the contextlib protocol to call `close`.
87 """
88 self.close()
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()