From c16c209fb09b4082b0d28b2f84de8b1693a870cb Mon Sep 17 00:00:00 2001 From: Daniel Toyama Date: Mon, 3 Mar 2025 09:59:48 -0800 Subject: [PATCH] Pass `delete_on_close=False` to `NamedTemporaryFile()`. The behavior of [`NamedTemporaryFile()`](https://docs.python.org/3/library/tempfile.html#tempfile.NamedTemporaryFile) is slightly different on Windows when the file is accessed multiple times in the same context manager. `delete_on_close=False` allows the file to exist until the end of the context manager, which is the behavior we want in all platforms. Unfortunately this argument was only added in Python `3.12`, so we add a switch to support earlier versions. We may remove it in the future once `3.11` is EOL. Please see PR https://github.com/google-deepmind/android_env/pull/265 for details (and thanks to @NingLi670 for opening the original PR). PiperOrigin-RevId: 732961399 --- android_env/components/adb_call_parser.py | 10 +++++++++- android_env/components/adb_call_parser_test.py | 7 ++++++- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/android_env/components/adb_call_parser.py b/android_env/components/adb_call_parser.py index 9e06bff..53efe47 100644 --- a/android_env/components/adb_call_parser.py +++ b/android_env/components/adb_call_parser.py @@ -280,7 +280,15 @@ def _install_apk( ['install', '-r', '-t', '-g', fpath], timeout=timeout ) case 'blob': - with tempfile.NamedTemporaryFile(suffix='.apk') as f: + + # `delete_on_close` was only added in Python 3.12 so we add a switch + # here to still support previous Python versions. + if sys.version_info >= (3, 12): + kwargs = {'suffix': '.apk', 'delete_on_close': False} + else: + kwargs = {'suffix': '.apk'} + + with tempfile.NamedTemporaryFile(**kwargs) as f: fpath = f.name f.write(install_apk.blob.contents) diff --git a/android_env/components/adb_call_parser_test.py b/android_env/components/adb_call_parser_test.py index 30dd893..7b178d7 100644 --- a/android_env/components/adb_call_parser_test.py +++ b/android_env/components/adb_call_parser_test.py @@ -98,8 +98,13 @@ def test_install_apk_from_blob(self, mock_tempfile): ['install', '-r', '-t', '-g', '/my/home/test.apk'], None ) # pytype: disable=attribute-error + expected_tempfile_kwargs = ( + {'suffix': '.apk', 'delete_on_close': False} + if sys.version_info > (3, 12) + else {'suffix': '.apk'} + ) mock_tempfile.assert_has_calls([ - mock.call(suffix='.apk'), # Constructor + mock.call(**expected_tempfile_kwargs), # Constructor mock.call().__enter__(), # Enter context mock.call().__enter__().write(blob_content), # Call write function mock.call().__exit__(None, None, None), # Exit context