Release the file lock. The lock is only completely released when the lock counter reaches 0. The lock file itself may be deleted automatically, the behavior is platform-specific. :param force: If true, the lock counter is ignored and the lock is released in every case.
(self, force: bool = False)
| 1097 | self._transition_lock.release() |
| 1098 | |
| 1099 | def release(self, force: bool = False) -> None: # ruff:ignore[boolean-type-hint-positional-argument, boolean-default-value-positional-argument] # public API: positional bool kept for backwards compatibility |
| 1100 | """ |
| 1101 | Release the file lock. The lock is only completely released when the lock counter reaches 0. The lock file |
| 1102 | itself may be deleted automatically, the behavior is platform-specific. |
| 1103 | |
| 1104 | :param force: If true, the lock counter is ignored and the lock is released in every case. |
| 1105 | |
| 1106 | """ |
| 1107 | # A shared instance releases under the same gate its acquisition ran through, so a thread entering the lock |
| 1108 | # never observes a partially torn-down owner. |
| 1109 | serialize = self._serialize_transitions and not self._is_thread_local |
| 1110 | with self._transition_lock if serialize else contextlib.nullcontext(): |
| 1111 | if self._creator_pid != os.getpid() or not self.is_locked: |
| 1112 | return |
| 1113 | if not force and self._context.lock_counter > 1: |
| 1114 | self._context.lock_counter -= 1 |
| 1115 | return |
| 1116 | |
| 1117 | lock_id, lock_filename = id(self), self.lock_file |
| 1118 | _LOGGER.debug("Attempting to release lock %s on %s", lock_id, lock_filename) |
| 1119 | try: |
| 1120 | self._release_with_fork_tracking() |
| 1121 | except BaseException: |
| 1122 | # A failure after the OS unlock (during close or unlink) still released the lock: the backend cleared |
| 1123 | # its descriptor, so commit the counter and registry to released even as the cleanup error propagates. |
| 1124 | # A failure that left the lock held keeps the counter so a later release can retry the OS unlock. |
| 1125 | if not self.is_locked: |
| 1126 | self._commit_release() |
| 1127 | raise |
| 1128 | self._commit_release() |
| 1129 | _LOGGER.debug("Lock %s released on %s", lock_id, lock_filename) |
| 1130 | |
| 1131 | def _raise_if_inherited(self) -> None: |
| 1132 | if self._creator_pid != os.getpid(): # pragma: forked child |