| 290 | self._v_file._log("CREATE", self._v_pathname) |
| 291 | |
| 292 | def __del__(self) -> None: |
| 293 | # Closed `Node` instances can not be killed and revived. |
| 294 | # Instead, accessing a closed and deleted (from memory, not |
| 295 | # disk) one yields a *new*, open `Node` instance. This is |
| 296 | # because of two reasons: |
| 297 | # |
| 298 | # 1. Predictability. After closing a `Node` and deleting it, |
| 299 | # only one thing can happen when accessing it again: a new, |
| 300 | # open `Node` instance is returned. If closed nodes could be |
| 301 | # revived, one could get either a closed or an open `Node`. |
| 302 | # |
| 303 | # 2. Ease of use. If the user wants to access a closed node |
| 304 | # again, the only condition would be that no references to |
| 305 | # the `Node` instance were left. If closed nodes could be |
| 306 | # revived, the user would also need to force the closed |
| 307 | # `Node` out of memory, which is not a trivial task. |
| 308 | # |
| 309 | |
| 310 | if not self._v_isopen: |
| 311 | return # the node is already closed or not initialized |
| 312 | |
| 313 | self._v__deleting = True |
| 314 | |
| 315 | # If we get here, the `Node` is still open. |
| 316 | try: |
| 317 | node_manager = self._v_file._node_manager |
| 318 | node_manager.drop_node(self, check_unregistered=False) |
| 319 | finally: |
| 320 | # At this point the node can still be open if there is still some |
| 321 | # alive reference around (e.g. if the __del__ method is called |
| 322 | # explicitly by the user). |
| 323 | if self._v_isopen: |
| 324 | self._v__deleting = True |
| 325 | self._f_close() |
| 326 | |
| 327 | def _g_pre_kill_hook(self) -> None: |
| 328 | """Code to be called before killing the node.""" |