From cde15346dda50392e0c5b70729c4fefe79b709e3 Mon Sep 17 00:00:00 2001 From: Claude Date: Thu, 5 Mar 2026 23:58:48 +0000 Subject: [PATCH] fix: prevent pytest hanging by avoiding threading.Lock in Process.__del__ During interpreter shutdown, Python tears down module globals including the threading module. When Process.__del__ called cleanup() which called ProcessManager.unregister_process(), it tried to acquire a threading.Lock. This caused an infinite process-restart loop, making pytest tests/ hang indefinitely after test completion. The fix replaces the full cleanup() call in __del__ with lightweight inline cleanup that only kills subprocesses and closes file descriptors, skipping the lock-dependent ProcessManager.unregister_process() call. The atexit handler already handles bulk process cleanup at exit. https://claude.ai/code/session_017pnDqUB249KbWHseNGTS16 --- wifite/util/process.py | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/wifite/util/process.py b/wifite/util/process.py index d64bb1c8c..bc29e29c4 100755 --- a/wifite/util/process.py +++ b/wifite/util/process.py @@ -212,8 +212,33 @@ def __exit__(self, exc_type, exc_val, exc_tb): self.cleanup() def __del__(self): + # During interpreter shutdown, module globals (including threading) + # may already be torn down. Acquiring a threading.Lock in that state + # can trigger an infinite-restart loop, so we only do lightweight + # cleanup here and skip ProcessManager.unregister_process entirely + # (the atexit handler already handles bulk cleanup). try: - self.cleanup() + if getattr(self, '_cleaned_up', True): + return + # Best-effort: kill still-running subprocesses and close FDs + if hasattr(self, 'pid') and self.pid: + try: + if self.pid.poll() is None: + self.pid.kill() + self.pid.wait() + except Exception: + pass + for stream in (self.pid.stdin, self.pid.stdout, self.pid.stderr): + if stream: + try: + stream.close() + except Exception: + pass + for fh in getattr(self, '_devnull_handles', []): + try: + fh.close() + except Exception: + pass except Exception: pass