https://github.com/python/cpython/commit/ff286a3d943e703ec92a4466b315b190b62dcd2a commit: ff286a3d943e703ec92a4466b315b190b62dcd2a branch: 3.13 author: Miss Islington (bot) <31488909+miss-isling...@users.noreply.github.com> committer: freakboy3742 <russ...@keith-magee.com> date: 2025-03-19T08:30:59+08:00 summary:
[3.13] gh-124666: Improve thread cleanup in test_android (GH-131427) (#131433) Ensures that failures in test setup don't result in dangling threads. (cherry picked from commit 01b5abbc53b2a9ee8d85e0518c98efce27dbd061) Co-authored-by: Malcolm Smith <sm...@chaquo.com> files: M Lib/test/test_android.py diff --git a/Lib/test/test_android.py b/Lib/test/test_android.py index 076190f7572045..b583328a253890 100644 --- a/Lib/test/test_android.py +++ b/Lib/test/test_android.py @@ -42,31 +42,41 @@ def logcat_thread(): for line in self.logcat_process.stdout: self.logcat_queue.put(line.rstrip("\n")) self.logcat_process.stdout.close() + self.logcat_thread = Thread(target=logcat_thread) self.logcat_thread.start() - from ctypes import CDLL, c_char_p, c_int - android_log_write = getattr(CDLL("liblog.so"), "__android_log_write") - android_log_write.argtypes = (c_int, c_char_p, c_char_p) - ANDROID_LOG_INFO = 4 - - # Separate tests using a marker line with a different tag. - tag, message = "python.test", f"{self.id()} {time()}" - android_log_write( - ANDROID_LOG_INFO, tag.encode("UTF-8"), message.encode("UTF-8")) - self.assert_log("I", tag, message, skip=True, timeout=5) + try: + from ctypes import CDLL, c_char_p, c_int + android_log_write = getattr(CDLL("liblog.so"), "__android_log_write") + android_log_write.argtypes = (c_int, c_char_p, c_char_p) + ANDROID_LOG_INFO = 4 + + # Separate tests using a marker line with a different tag. + tag, message = "python.test", f"{self.id()} {time()}" + android_log_write( + ANDROID_LOG_INFO, tag.encode("UTF-8"), message.encode("UTF-8")) + self.assert_log("I", tag, message, skip=True) + except: + # If setUp throws an exception, tearDown is not automatically + # called. Avoid leaving a dangling thread which would keep the + # Python process alive indefinitely. + self.tearDown() + raise def assert_logs(self, level, tag, expected, **kwargs): for line in expected: self.assert_log(level, tag, line, **kwargs) - def assert_log(self, level, tag, expected, *, skip=False, timeout=0.5): - deadline = time() + timeout + def assert_log(self, level, tag, expected, *, skip=False): + deadline = time() + LOOPBACK_TIMEOUT while True: try: line = self.logcat_queue.get(timeout=(deadline - time())) except queue.Empty: - self.fail(f"line not found: {expected!r}") + raise self.failureException( + f"line not found: {expected!r}" + ) from None if match := re.fullmatch(fr"(.)/{tag}: (.*)", line): try: self.assertEqual(level, match[1]) @@ -81,6 +91,9 @@ def tearDown(self): self.logcat_process.wait(LOOPBACK_TIMEOUT) self.logcat_thread.join(LOOPBACK_TIMEOUT) + # Avoid an irrelevant warning about threading._dangling. + self.logcat_thread = None + @contextmanager def unbuffered(self, stream): stream.reconfigure(write_through=True) _______________________________________________ Python-checkins mailing list -- python-checkins@python.org To unsubscribe send an email to python-checkins-le...@python.org https://mail.python.org/mailman3/lists/python-checkins.python.org/ Member address: arch...@mail-archive.com