17db96d56Sopenharmony_ci# tempfile.py unit tests. 27db96d56Sopenharmony_ciimport tempfile 37db96d56Sopenharmony_ciimport errno 47db96d56Sopenharmony_ciimport io 57db96d56Sopenharmony_ciimport os 67db96d56Sopenharmony_ciimport pathlib 77db96d56Sopenharmony_ciimport sys 87db96d56Sopenharmony_ciimport re 97db96d56Sopenharmony_ciimport warnings 107db96d56Sopenharmony_ciimport contextlib 117db96d56Sopenharmony_ciimport stat 127db96d56Sopenharmony_ciimport types 137db96d56Sopenharmony_ciimport weakref 147db96d56Sopenharmony_ciimport subprocess 157db96d56Sopenharmony_cifrom unittest import mock 167db96d56Sopenharmony_ci 177db96d56Sopenharmony_ciimport unittest 187db96d56Sopenharmony_cifrom test import support 197db96d56Sopenharmony_cifrom test.support import os_helper 207db96d56Sopenharmony_cifrom test.support import script_helper 217db96d56Sopenharmony_cifrom test.support import warnings_helper 227db96d56Sopenharmony_ci 237db96d56Sopenharmony_ci 247db96d56Sopenharmony_cihas_textmode = (tempfile._text_openflags != tempfile._bin_openflags) 257db96d56Sopenharmony_cihas_spawnl = hasattr(os, 'spawnl') 267db96d56Sopenharmony_ci 277db96d56Sopenharmony_ci# TEST_FILES may need to be tweaked for systems depending on the maximum 287db96d56Sopenharmony_ci# number of files that can be opened at one time (see ulimit -n) 297db96d56Sopenharmony_ciif sys.platform.startswith('openbsd'): 307db96d56Sopenharmony_ci TEST_FILES = 48 317db96d56Sopenharmony_cielse: 327db96d56Sopenharmony_ci TEST_FILES = 100 337db96d56Sopenharmony_ci 347db96d56Sopenharmony_ci# This is organized as one test for each chunk of code in tempfile.py, 357db96d56Sopenharmony_ci# in order of their appearance in the file. Testing which requires 367db96d56Sopenharmony_ci# threads is not done here. 377db96d56Sopenharmony_ci 387db96d56Sopenharmony_ciclass TestLowLevelInternals(unittest.TestCase): 397db96d56Sopenharmony_ci def test_infer_return_type_singles(self): 407db96d56Sopenharmony_ci self.assertIs(str, tempfile._infer_return_type('')) 417db96d56Sopenharmony_ci self.assertIs(bytes, tempfile._infer_return_type(b'')) 427db96d56Sopenharmony_ci self.assertIs(str, tempfile._infer_return_type(None)) 437db96d56Sopenharmony_ci 447db96d56Sopenharmony_ci def test_infer_return_type_multiples(self): 457db96d56Sopenharmony_ci self.assertIs(str, tempfile._infer_return_type('', '')) 467db96d56Sopenharmony_ci self.assertIs(bytes, tempfile._infer_return_type(b'', b'')) 477db96d56Sopenharmony_ci with self.assertRaises(TypeError): 487db96d56Sopenharmony_ci tempfile._infer_return_type('', b'') 497db96d56Sopenharmony_ci with self.assertRaises(TypeError): 507db96d56Sopenharmony_ci tempfile._infer_return_type(b'', '') 517db96d56Sopenharmony_ci 527db96d56Sopenharmony_ci def test_infer_return_type_multiples_and_none(self): 537db96d56Sopenharmony_ci self.assertIs(str, tempfile._infer_return_type(None, '')) 547db96d56Sopenharmony_ci self.assertIs(str, tempfile._infer_return_type('', None)) 557db96d56Sopenharmony_ci self.assertIs(str, tempfile._infer_return_type(None, None)) 567db96d56Sopenharmony_ci self.assertIs(bytes, tempfile._infer_return_type(b'', None)) 577db96d56Sopenharmony_ci self.assertIs(bytes, tempfile._infer_return_type(None, b'')) 587db96d56Sopenharmony_ci with self.assertRaises(TypeError): 597db96d56Sopenharmony_ci tempfile._infer_return_type('', None, b'') 607db96d56Sopenharmony_ci with self.assertRaises(TypeError): 617db96d56Sopenharmony_ci tempfile._infer_return_type(b'', None, '') 627db96d56Sopenharmony_ci 637db96d56Sopenharmony_ci def test_infer_return_type_pathlib(self): 647db96d56Sopenharmony_ci self.assertIs(str, tempfile._infer_return_type(pathlib.Path('/'))) 657db96d56Sopenharmony_ci 667db96d56Sopenharmony_ci def test_infer_return_type_pathlike(self): 677db96d56Sopenharmony_ci class Path: 687db96d56Sopenharmony_ci def __init__(self, path): 697db96d56Sopenharmony_ci self.path = path 707db96d56Sopenharmony_ci 717db96d56Sopenharmony_ci def __fspath__(self): 727db96d56Sopenharmony_ci return self.path 737db96d56Sopenharmony_ci 747db96d56Sopenharmony_ci self.assertIs(str, tempfile._infer_return_type(Path('/'))) 757db96d56Sopenharmony_ci self.assertIs(bytes, tempfile._infer_return_type(Path(b'/'))) 767db96d56Sopenharmony_ci self.assertIs(str, tempfile._infer_return_type('', Path(''))) 777db96d56Sopenharmony_ci self.assertIs(bytes, tempfile._infer_return_type(b'', Path(b''))) 787db96d56Sopenharmony_ci self.assertIs(bytes, tempfile._infer_return_type(None, Path(b''))) 797db96d56Sopenharmony_ci self.assertIs(str, tempfile._infer_return_type(None, Path(''))) 807db96d56Sopenharmony_ci 817db96d56Sopenharmony_ci with self.assertRaises(TypeError): 827db96d56Sopenharmony_ci tempfile._infer_return_type('', Path(b'')) 837db96d56Sopenharmony_ci with self.assertRaises(TypeError): 847db96d56Sopenharmony_ci tempfile._infer_return_type(b'', Path('')) 857db96d56Sopenharmony_ci 867db96d56Sopenharmony_ci# Common functionality. 877db96d56Sopenharmony_ci 887db96d56Sopenharmony_ciclass BaseTestCase(unittest.TestCase): 897db96d56Sopenharmony_ci 907db96d56Sopenharmony_ci str_check = re.compile(r"^[a-z0-9_-]{8}$") 917db96d56Sopenharmony_ci b_check = re.compile(br"^[a-z0-9_-]{8}$") 927db96d56Sopenharmony_ci 937db96d56Sopenharmony_ci def setUp(self): 947db96d56Sopenharmony_ci self.enterContext(warnings_helper.check_warnings()) 957db96d56Sopenharmony_ci warnings.filterwarnings("ignore", category=RuntimeWarning, 967db96d56Sopenharmony_ci message="mktemp", module=__name__) 977db96d56Sopenharmony_ci 987db96d56Sopenharmony_ci def nameCheck(self, name, dir, pre, suf): 997db96d56Sopenharmony_ci (ndir, nbase) = os.path.split(name) 1007db96d56Sopenharmony_ci npre = nbase[:len(pre)] 1017db96d56Sopenharmony_ci nsuf = nbase[len(nbase)-len(suf):] 1027db96d56Sopenharmony_ci 1037db96d56Sopenharmony_ci if dir is not None: 1047db96d56Sopenharmony_ci self.assertIs( 1057db96d56Sopenharmony_ci type(name), 1067db96d56Sopenharmony_ci str 1077db96d56Sopenharmony_ci if type(dir) is str or isinstance(dir, os.PathLike) else 1087db96d56Sopenharmony_ci bytes, 1097db96d56Sopenharmony_ci "unexpected return type", 1107db96d56Sopenharmony_ci ) 1117db96d56Sopenharmony_ci if pre is not None: 1127db96d56Sopenharmony_ci self.assertIs(type(name), str if type(pre) is str else bytes, 1137db96d56Sopenharmony_ci "unexpected return type") 1147db96d56Sopenharmony_ci if suf is not None: 1157db96d56Sopenharmony_ci self.assertIs(type(name), str if type(suf) is str else bytes, 1167db96d56Sopenharmony_ci "unexpected return type") 1177db96d56Sopenharmony_ci if (dir, pre, suf) == (None, None, None): 1187db96d56Sopenharmony_ci self.assertIs(type(name), str, "default return type must be str") 1197db96d56Sopenharmony_ci 1207db96d56Sopenharmony_ci # check for equality of the absolute paths! 1217db96d56Sopenharmony_ci self.assertEqual(os.path.abspath(ndir), os.path.abspath(dir), 1227db96d56Sopenharmony_ci "file %r not in directory %r" % (name, dir)) 1237db96d56Sopenharmony_ci self.assertEqual(npre, pre, 1247db96d56Sopenharmony_ci "file %r does not begin with %r" % (nbase, pre)) 1257db96d56Sopenharmony_ci self.assertEqual(nsuf, suf, 1267db96d56Sopenharmony_ci "file %r does not end with %r" % (nbase, suf)) 1277db96d56Sopenharmony_ci 1287db96d56Sopenharmony_ci nbase = nbase[len(pre):len(nbase)-len(suf)] 1297db96d56Sopenharmony_ci check = self.str_check if isinstance(nbase, str) else self.b_check 1307db96d56Sopenharmony_ci self.assertTrue(check.match(nbase), 1317db96d56Sopenharmony_ci "random characters %r do not match %r" 1327db96d56Sopenharmony_ci % (nbase, check.pattern)) 1337db96d56Sopenharmony_ci 1347db96d56Sopenharmony_ci 1357db96d56Sopenharmony_ciclass TestExports(BaseTestCase): 1367db96d56Sopenharmony_ci def test_exports(self): 1377db96d56Sopenharmony_ci # There are no surprising symbols in the tempfile module 1387db96d56Sopenharmony_ci dict = tempfile.__dict__ 1397db96d56Sopenharmony_ci 1407db96d56Sopenharmony_ci expected = { 1417db96d56Sopenharmony_ci "NamedTemporaryFile" : 1, 1427db96d56Sopenharmony_ci "TemporaryFile" : 1, 1437db96d56Sopenharmony_ci "mkstemp" : 1, 1447db96d56Sopenharmony_ci "mkdtemp" : 1, 1457db96d56Sopenharmony_ci "mktemp" : 1, 1467db96d56Sopenharmony_ci "TMP_MAX" : 1, 1477db96d56Sopenharmony_ci "gettempprefix" : 1, 1487db96d56Sopenharmony_ci "gettempprefixb" : 1, 1497db96d56Sopenharmony_ci "gettempdir" : 1, 1507db96d56Sopenharmony_ci "gettempdirb" : 1, 1517db96d56Sopenharmony_ci "tempdir" : 1, 1527db96d56Sopenharmony_ci "template" : 1, 1537db96d56Sopenharmony_ci "SpooledTemporaryFile" : 1, 1547db96d56Sopenharmony_ci "TemporaryDirectory" : 1, 1557db96d56Sopenharmony_ci } 1567db96d56Sopenharmony_ci 1577db96d56Sopenharmony_ci unexp = [] 1587db96d56Sopenharmony_ci for key in dict: 1597db96d56Sopenharmony_ci if key[0] != '_' and key not in expected: 1607db96d56Sopenharmony_ci unexp.append(key) 1617db96d56Sopenharmony_ci self.assertTrue(len(unexp) == 0, 1627db96d56Sopenharmony_ci "unexpected keys: %s" % unexp) 1637db96d56Sopenharmony_ci 1647db96d56Sopenharmony_ci 1657db96d56Sopenharmony_ciclass TestRandomNameSequence(BaseTestCase): 1667db96d56Sopenharmony_ci """Test the internal iterator object _RandomNameSequence.""" 1677db96d56Sopenharmony_ci 1687db96d56Sopenharmony_ci def setUp(self): 1697db96d56Sopenharmony_ci self.r = tempfile._RandomNameSequence() 1707db96d56Sopenharmony_ci super().setUp() 1717db96d56Sopenharmony_ci 1727db96d56Sopenharmony_ci def test_get_eight_char_str(self): 1737db96d56Sopenharmony_ci # _RandomNameSequence returns a eight-character string 1747db96d56Sopenharmony_ci s = next(self.r) 1757db96d56Sopenharmony_ci self.nameCheck(s, '', '', '') 1767db96d56Sopenharmony_ci 1777db96d56Sopenharmony_ci def test_many(self): 1787db96d56Sopenharmony_ci # _RandomNameSequence returns no duplicate strings (stochastic) 1797db96d56Sopenharmony_ci 1807db96d56Sopenharmony_ci dict = {} 1817db96d56Sopenharmony_ci r = self.r 1827db96d56Sopenharmony_ci for i in range(TEST_FILES): 1837db96d56Sopenharmony_ci s = next(r) 1847db96d56Sopenharmony_ci self.nameCheck(s, '', '', '') 1857db96d56Sopenharmony_ci self.assertNotIn(s, dict) 1867db96d56Sopenharmony_ci dict[s] = 1 1877db96d56Sopenharmony_ci 1887db96d56Sopenharmony_ci def supports_iter(self): 1897db96d56Sopenharmony_ci # _RandomNameSequence supports the iterator protocol 1907db96d56Sopenharmony_ci 1917db96d56Sopenharmony_ci i = 0 1927db96d56Sopenharmony_ci r = self.r 1937db96d56Sopenharmony_ci for s in r: 1947db96d56Sopenharmony_ci i += 1 1957db96d56Sopenharmony_ci if i == 20: 1967db96d56Sopenharmony_ci break 1977db96d56Sopenharmony_ci 1987db96d56Sopenharmony_ci @support.requires_fork() 1997db96d56Sopenharmony_ci def test_process_awareness(self): 2007db96d56Sopenharmony_ci # ensure that the random source differs between 2017db96d56Sopenharmony_ci # child and parent. 2027db96d56Sopenharmony_ci read_fd, write_fd = os.pipe() 2037db96d56Sopenharmony_ci pid = None 2047db96d56Sopenharmony_ci try: 2057db96d56Sopenharmony_ci pid = os.fork() 2067db96d56Sopenharmony_ci if not pid: 2077db96d56Sopenharmony_ci # child process 2087db96d56Sopenharmony_ci os.close(read_fd) 2097db96d56Sopenharmony_ci os.write(write_fd, next(self.r).encode("ascii")) 2107db96d56Sopenharmony_ci os.close(write_fd) 2117db96d56Sopenharmony_ci # bypass the normal exit handlers- leave those to 2127db96d56Sopenharmony_ci # the parent. 2137db96d56Sopenharmony_ci os._exit(0) 2147db96d56Sopenharmony_ci 2157db96d56Sopenharmony_ci # parent process 2167db96d56Sopenharmony_ci parent_value = next(self.r) 2177db96d56Sopenharmony_ci child_value = os.read(read_fd, len(parent_value)).decode("ascii") 2187db96d56Sopenharmony_ci finally: 2197db96d56Sopenharmony_ci if pid: 2207db96d56Sopenharmony_ci support.wait_process(pid, exitcode=0) 2217db96d56Sopenharmony_ci 2227db96d56Sopenharmony_ci os.close(read_fd) 2237db96d56Sopenharmony_ci os.close(write_fd) 2247db96d56Sopenharmony_ci self.assertNotEqual(child_value, parent_value) 2257db96d56Sopenharmony_ci 2267db96d56Sopenharmony_ci 2277db96d56Sopenharmony_ci 2287db96d56Sopenharmony_ciclass TestCandidateTempdirList(BaseTestCase): 2297db96d56Sopenharmony_ci """Test the internal function _candidate_tempdir_list.""" 2307db96d56Sopenharmony_ci 2317db96d56Sopenharmony_ci def test_nonempty_list(self): 2327db96d56Sopenharmony_ci # _candidate_tempdir_list returns a nonempty list of strings 2337db96d56Sopenharmony_ci 2347db96d56Sopenharmony_ci cand = tempfile._candidate_tempdir_list() 2357db96d56Sopenharmony_ci 2367db96d56Sopenharmony_ci self.assertFalse(len(cand) == 0) 2377db96d56Sopenharmony_ci for c in cand: 2387db96d56Sopenharmony_ci self.assertIsInstance(c, str) 2397db96d56Sopenharmony_ci 2407db96d56Sopenharmony_ci def test_wanted_dirs(self): 2417db96d56Sopenharmony_ci # _candidate_tempdir_list contains the expected directories 2427db96d56Sopenharmony_ci 2437db96d56Sopenharmony_ci # Make sure the interesting environment variables are all set. 2447db96d56Sopenharmony_ci with os_helper.EnvironmentVarGuard() as env: 2457db96d56Sopenharmony_ci for envname in 'TMPDIR', 'TEMP', 'TMP': 2467db96d56Sopenharmony_ci dirname = os.getenv(envname) 2477db96d56Sopenharmony_ci if not dirname: 2487db96d56Sopenharmony_ci env[envname] = os.path.abspath(envname) 2497db96d56Sopenharmony_ci 2507db96d56Sopenharmony_ci cand = tempfile._candidate_tempdir_list() 2517db96d56Sopenharmony_ci 2527db96d56Sopenharmony_ci for envname in 'TMPDIR', 'TEMP', 'TMP': 2537db96d56Sopenharmony_ci dirname = os.getenv(envname) 2547db96d56Sopenharmony_ci if not dirname: raise ValueError 2557db96d56Sopenharmony_ci self.assertIn(dirname, cand) 2567db96d56Sopenharmony_ci 2577db96d56Sopenharmony_ci try: 2587db96d56Sopenharmony_ci dirname = os.getcwd() 2597db96d56Sopenharmony_ci except (AttributeError, OSError): 2607db96d56Sopenharmony_ci dirname = os.curdir 2617db96d56Sopenharmony_ci 2627db96d56Sopenharmony_ci self.assertIn(dirname, cand) 2637db96d56Sopenharmony_ci 2647db96d56Sopenharmony_ci # Not practical to try to verify the presence of OS-specific 2657db96d56Sopenharmony_ci # paths in this list. 2667db96d56Sopenharmony_ci 2677db96d56Sopenharmony_ci 2687db96d56Sopenharmony_ci# We test _get_default_tempdir some more by testing gettempdir. 2697db96d56Sopenharmony_ci 2707db96d56Sopenharmony_ciclass TestGetDefaultTempdir(BaseTestCase): 2717db96d56Sopenharmony_ci """Test _get_default_tempdir().""" 2727db96d56Sopenharmony_ci 2737db96d56Sopenharmony_ci def test_no_files_left_behind(self): 2747db96d56Sopenharmony_ci # use a private empty directory 2757db96d56Sopenharmony_ci with tempfile.TemporaryDirectory() as our_temp_directory: 2767db96d56Sopenharmony_ci # force _get_default_tempdir() to consider our empty directory 2777db96d56Sopenharmony_ci def our_candidate_list(): 2787db96d56Sopenharmony_ci return [our_temp_directory] 2797db96d56Sopenharmony_ci 2807db96d56Sopenharmony_ci with support.swap_attr(tempfile, "_candidate_tempdir_list", 2817db96d56Sopenharmony_ci our_candidate_list): 2827db96d56Sopenharmony_ci # verify our directory is empty after _get_default_tempdir() 2837db96d56Sopenharmony_ci tempfile._get_default_tempdir() 2847db96d56Sopenharmony_ci self.assertEqual(os.listdir(our_temp_directory), []) 2857db96d56Sopenharmony_ci 2867db96d56Sopenharmony_ci def raise_OSError(*args, **kwargs): 2877db96d56Sopenharmony_ci raise OSError() 2887db96d56Sopenharmony_ci 2897db96d56Sopenharmony_ci with support.swap_attr(os, "open", raise_OSError): 2907db96d56Sopenharmony_ci # test again with failing os.open() 2917db96d56Sopenharmony_ci with self.assertRaises(FileNotFoundError): 2927db96d56Sopenharmony_ci tempfile._get_default_tempdir() 2937db96d56Sopenharmony_ci self.assertEqual(os.listdir(our_temp_directory), []) 2947db96d56Sopenharmony_ci 2957db96d56Sopenharmony_ci with support.swap_attr(os, "write", raise_OSError): 2967db96d56Sopenharmony_ci # test again with failing os.write() 2977db96d56Sopenharmony_ci with self.assertRaises(FileNotFoundError): 2987db96d56Sopenharmony_ci tempfile._get_default_tempdir() 2997db96d56Sopenharmony_ci self.assertEqual(os.listdir(our_temp_directory), []) 3007db96d56Sopenharmony_ci 3017db96d56Sopenharmony_ci 3027db96d56Sopenharmony_ciclass TestGetCandidateNames(BaseTestCase): 3037db96d56Sopenharmony_ci """Test the internal function _get_candidate_names.""" 3047db96d56Sopenharmony_ci 3057db96d56Sopenharmony_ci def test_retval(self): 3067db96d56Sopenharmony_ci # _get_candidate_names returns a _RandomNameSequence object 3077db96d56Sopenharmony_ci obj = tempfile._get_candidate_names() 3087db96d56Sopenharmony_ci self.assertIsInstance(obj, tempfile._RandomNameSequence) 3097db96d56Sopenharmony_ci 3107db96d56Sopenharmony_ci def test_same_thing(self): 3117db96d56Sopenharmony_ci # _get_candidate_names always returns the same object 3127db96d56Sopenharmony_ci a = tempfile._get_candidate_names() 3137db96d56Sopenharmony_ci b = tempfile._get_candidate_names() 3147db96d56Sopenharmony_ci 3157db96d56Sopenharmony_ci self.assertTrue(a is b) 3167db96d56Sopenharmony_ci 3177db96d56Sopenharmony_ci 3187db96d56Sopenharmony_ci@contextlib.contextmanager 3197db96d56Sopenharmony_cidef _inside_empty_temp_dir(): 3207db96d56Sopenharmony_ci dir = tempfile.mkdtemp() 3217db96d56Sopenharmony_ci try: 3227db96d56Sopenharmony_ci with support.swap_attr(tempfile, 'tempdir', dir): 3237db96d56Sopenharmony_ci yield 3247db96d56Sopenharmony_ci finally: 3257db96d56Sopenharmony_ci os_helper.rmtree(dir) 3267db96d56Sopenharmony_ci 3277db96d56Sopenharmony_ci 3287db96d56Sopenharmony_cidef _mock_candidate_names(*names): 3297db96d56Sopenharmony_ci return support.swap_attr(tempfile, 3307db96d56Sopenharmony_ci '_get_candidate_names', 3317db96d56Sopenharmony_ci lambda: iter(names)) 3327db96d56Sopenharmony_ci 3337db96d56Sopenharmony_ci 3347db96d56Sopenharmony_ciclass TestBadTempdir: 3357db96d56Sopenharmony_ci 3367db96d56Sopenharmony_ci @unittest.skipIf( 3377db96d56Sopenharmony_ci support.is_emscripten, "Emscripten cannot remove write bits." 3387db96d56Sopenharmony_ci ) 3397db96d56Sopenharmony_ci def test_read_only_directory(self): 3407db96d56Sopenharmony_ci with _inside_empty_temp_dir(): 3417db96d56Sopenharmony_ci oldmode = mode = os.stat(tempfile.tempdir).st_mode 3427db96d56Sopenharmony_ci mode &= ~(stat.S_IWUSR | stat.S_IWGRP | stat.S_IWOTH) 3437db96d56Sopenharmony_ci os.chmod(tempfile.tempdir, mode) 3447db96d56Sopenharmony_ci try: 3457db96d56Sopenharmony_ci if os.access(tempfile.tempdir, os.W_OK): 3467db96d56Sopenharmony_ci self.skipTest("can't set the directory read-only") 3477db96d56Sopenharmony_ci with self.assertRaises(PermissionError): 3487db96d56Sopenharmony_ci self.make_temp() 3497db96d56Sopenharmony_ci self.assertEqual(os.listdir(tempfile.tempdir), []) 3507db96d56Sopenharmony_ci finally: 3517db96d56Sopenharmony_ci os.chmod(tempfile.tempdir, oldmode) 3527db96d56Sopenharmony_ci 3537db96d56Sopenharmony_ci def test_nonexisting_directory(self): 3547db96d56Sopenharmony_ci with _inside_empty_temp_dir(): 3557db96d56Sopenharmony_ci tempdir = os.path.join(tempfile.tempdir, 'nonexistent') 3567db96d56Sopenharmony_ci with support.swap_attr(tempfile, 'tempdir', tempdir): 3577db96d56Sopenharmony_ci with self.assertRaises(FileNotFoundError): 3587db96d56Sopenharmony_ci self.make_temp() 3597db96d56Sopenharmony_ci 3607db96d56Sopenharmony_ci def test_non_directory(self): 3617db96d56Sopenharmony_ci with _inside_empty_temp_dir(): 3627db96d56Sopenharmony_ci tempdir = os.path.join(tempfile.tempdir, 'file') 3637db96d56Sopenharmony_ci open(tempdir, 'wb').close() 3647db96d56Sopenharmony_ci with support.swap_attr(tempfile, 'tempdir', tempdir): 3657db96d56Sopenharmony_ci with self.assertRaises((NotADirectoryError, FileNotFoundError)): 3667db96d56Sopenharmony_ci self.make_temp() 3677db96d56Sopenharmony_ci 3687db96d56Sopenharmony_ci 3697db96d56Sopenharmony_ciclass TestMkstempInner(TestBadTempdir, BaseTestCase): 3707db96d56Sopenharmony_ci """Test the internal function _mkstemp_inner.""" 3717db96d56Sopenharmony_ci 3727db96d56Sopenharmony_ci class mkstemped: 3737db96d56Sopenharmony_ci _bflags = tempfile._bin_openflags 3747db96d56Sopenharmony_ci _tflags = tempfile._text_openflags 3757db96d56Sopenharmony_ci _close = os.close 3767db96d56Sopenharmony_ci _unlink = os.unlink 3777db96d56Sopenharmony_ci 3787db96d56Sopenharmony_ci def __init__(self, dir, pre, suf, bin): 3797db96d56Sopenharmony_ci if bin: flags = self._bflags 3807db96d56Sopenharmony_ci else: flags = self._tflags 3817db96d56Sopenharmony_ci 3827db96d56Sopenharmony_ci output_type = tempfile._infer_return_type(dir, pre, suf) 3837db96d56Sopenharmony_ci (self.fd, self.name) = tempfile._mkstemp_inner(dir, pre, suf, flags, output_type) 3847db96d56Sopenharmony_ci 3857db96d56Sopenharmony_ci def write(self, str): 3867db96d56Sopenharmony_ci os.write(self.fd, str) 3877db96d56Sopenharmony_ci 3887db96d56Sopenharmony_ci def __del__(self): 3897db96d56Sopenharmony_ci self._close(self.fd) 3907db96d56Sopenharmony_ci self._unlink(self.name) 3917db96d56Sopenharmony_ci 3927db96d56Sopenharmony_ci def do_create(self, dir=None, pre=None, suf=None, bin=1): 3937db96d56Sopenharmony_ci output_type = tempfile._infer_return_type(dir, pre, suf) 3947db96d56Sopenharmony_ci if dir is None: 3957db96d56Sopenharmony_ci if output_type is str: 3967db96d56Sopenharmony_ci dir = tempfile.gettempdir() 3977db96d56Sopenharmony_ci else: 3987db96d56Sopenharmony_ci dir = tempfile.gettempdirb() 3997db96d56Sopenharmony_ci if pre is None: 4007db96d56Sopenharmony_ci pre = output_type() 4017db96d56Sopenharmony_ci if suf is None: 4027db96d56Sopenharmony_ci suf = output_type() 4037db96d56Sopenharmony_ci file = self.mkstemped(dir, pre, suf, bin) 4047db96d56Sopenharmony_ci 4057db96d56Sopenharmony_ci self.nameCheck(file.name, dir, pre, suf) 4067db96d56Sopenharmony_ci return file 4077db96d56Sopenharmony_ci 4087db96d56Sopenharmony_ci def test_basic(self): 4097db96d56Sopenharmony_ci # _mkstemp_inner can create files 4107db96d56Sopenharmony_ci self.do_create().write(b"blat") 4117db96d56Sopenharmony_ci self.do_create(pre="a").write(b"blat") 4127db96d56Sopenharmony_ci self.do_create(suf="b").write(b"blat") 4137db96d56Sopenharmony_ci self.do_create(pre="a", suf="b").write(b"blat") 4147db96d56Sopenharmony_ci self.do_create(pre="aa", suf=".txt").write(b"blat") 4157db96d56Sopenharmony_ci 4167db96d56Sopenharmony_ci def test_basic_with_bytes_names(self): 4177db96d56Sopenharmony_ci # _mkstemp_inner can create files when given name parts all 4187db96d56Sopenharmony_ci # specified as bytes. 4197db96d56Sopenharmony_ci dir_b = tempfile.gettempdirb() 4207db96d56Sopenharmony_ci self.do_create(dir=dir_b, suf=b"").write(b"blat") 4217db96d56Sopenharmony_ci self.do_create(dir=dir_b, pre=b"a").write(b"blat") 4227db96d56Sopenharmony_ci self.do_create(dir=dir_b, suf=b"b").write(b"blat") 4237db96d56Sopenharmony_ci self.do_create(dir=dir_b, pre=b"a", suf=b"b").write(b"blat") 4247db96d56Sopenharmony_ci self.do_create(dir=dir_b, pre=b"aa", suf=b".txt").write(b"blat") 4257db96d56Sopenharmony_ci # Can't mix str & binary types in the args. 4267db96d56Sopenharmony_ci with self.assertRaises(TypeError): 4277db96d56Sopenharmony_ci self.do_create(dir="", suf=b"").write(b"blat") 4287db96d56Sopenharmony_ci with self.assertRaises(TypeError): 4297db96d56Sopenharmony_ci self.do_create(dir=dir_b, pre="").write(b"blat") 4307db96d56Sopenharmony_ci with self.assertRaises(TypeError): 4317db96d56Sopenharmony_ci self.do_create(dir=dir_b, pre=b"", suf="").write(b"blat") 4327db96d56Sopenharmony_ci 4337db96d56Sopenharmony_ci def test_basic_many(self): 4347db96d56Sopenharmony_ci # _mkstemp_inner can create many files (stochastic) 4357db96d56Sopenharmony_ci extant = list(range(TEST_FILES)) 4367db96d56Sopenharmony_ci for i in extant: 4377db96d56Sopenharmony_ci extant[i] = self.do_create(pre="aa") 4387db96d56Sopenharmony_ci 4397db96d56Sopenharmony_ci def test_choose_directory(self): 4407db96d56Sopenharmony_ci # _mkstemp_inner can create files in a user-selected directory 4417db96d56Sopenharmony_ci dir = tempfile.mkdtemp() 4427db96d56Sopenharmony_ci try: 4437db96d56Sopenharmony_ci self.do_create(dir=dir).write(b"blat") 4447db96d56Sopenharmony_ci self.do_create(dir=pathlib.Path(dir)).write(b"blat") 4457db96d56Sopenharmony_ci finally: 4467db96d56Sopenharmony_ci support.gc_collect() # For PyPy or other GCs. 4477db96d56Sopenharmony_ci os.rmdir(dir) 4487db96d56Sopenharmony_ci 4497db96d56Sopenharmony_ci @os_helper.skip_unless_working_chmod 4507db96d56Sopenharmony_ci def test_file_mode(self): 4517db96d56Sopenharmony_ci # _mkstemp_inner creates files with the proper mode 4527db96d56Sopenharmony_ci 4537db96d56Sopenharmony_ci file = self.do_create() 4547db96d56Sopenharmony_ci mode = stat.S_IMODE(os.stat(file.name).st_mode) 4557db96d56Sopenharmony_ci expected = 0o600 4567db96d56Sopenharmony_ci if sys.platform == 'win32': 4577db96d56Sopenharmony_ci # There's no distinction among 'user', 'group' and 'world'; 4587db96d56Sopenharmony_ci # replicate the 'user' bits. 4597db96d56Sopenharmony_ci user = expected >> 6 4607db96d56Sopenharmony_ci expected = user * (1 + 8 + 64) 4617db96d56Sopenharmony_ci self.assertEqual(mode, expected) 4627db96d56Sopenharmony_ci 4637db96d56Sopenharmony_ci @unittest.skipUnless(has_spawnl, 'os.spawnl not available') 4647db96d56Sopenharmony_ci @support.requires_subprocess() 4657db96d56Sopenharmony_ci def test_noinherit(self): 4667db96d56Sopenharmony_ci # _mkstemp_inner file handles are not inherited by child processes 4677db96d56Sopenharmony_ci 4687db96d56Sopenharmony_ci if support.verbose: 4697db96d56Sopenharmony_ci v="v" 4707db96d56Sopenharmony_ci else: 4717db96d56Sopenharmony_ci v="q" 4727db96d56Sopenharmony_ci 4737db96d56Sopenharmony_ci file = self.do_create() 4747db96d56Sopenharmony_ci self.assertEqual(os.get_inheritable(file.fd), False) 4757db96d56Sopenharmony_ci fd = "%d" % file.fd 4767db96d56Sopenharmony_ci 4777db96d56Sopenharmony_ci try: 4787db96d56Sopenharmony_ci me = __file__ 4797db96d56Sopenharmony_ci except NameError: 4807db96d56Sopenharmony_ci me = sys.argv[0] 4817db96d56Sopenharmony_ci 4827db96d56Sopenharmony_ci # We have to exec something, so that FD_CLOEXEC will take 4837db96d56Sopenharmony_ci # effect. The core of this test is therefore in 4847db96d56Sopenharmony_ci # tf_inherit_check.py, which see. 4857db96d56Sopenharmony_ci tester = os.path.join(os.path.dirname(os.path.abspath(me)), 4867db96d56Sopenharmony_ci "tf_inherit_check.py") 4877db96d56Sopenharmony_ci 4887db96d56Sopenharmony_ci # On Windows a spawn* /path/ with embedded spaces shouldn't be quoted, 4897db96d56Sopenharmony_ci # but an arg with embedded spaces should be decorated with double 4907db96d56Sopenharmony_ci # quotes on each end 4917db96d56Sopenharmony_ci if sys.platform == 'win32': 4927db96d56Sopenharmony_ci decorated = '"%s"' % sys.executable 4937db96d56Sopenharmony_ci tester = '"%s"' % tester 4947db96d56Sopenharmony_ci else: 4957db96d56Sopenharmony_ci decorated = sys.executable 4967db96d56Sopenharmony_ci 4977db96d56Sopenharmony_ci retval = os.spawnl(os.P_WAIT, sys.executable, decorated, tester, v, fd) 4987db96d56Sopenharmony_ci self.assertFalse(retval < 0, 4997db96d56Sopenharmony_ci "child process caught fatal signal %d" % -retval) 5007db96d56Sopenharmony_ci self.assertFalse(retval > 0, "child process reports failure %d"%retval) 5017db96d56Sopenharmony_ci 5027db96d56Sopenharmony_ci @unittest.skipUnless(has_textmode, "text mode not available") 5037db96d56Sopenharmony_ci def test_textmode(self): 5047db96d56Sopenharmony_ci # _mkstemp_inner can create files in text mode 5057db96d56Sopenharmony_ci 5067db96d56Sopenharmony_ci # A text file is truncated at the first Ctrl+Z byte 5077db96d56Sopenharmony_ci f = self.do_create(bin=0) 5087db96d56Sopenharmony_ci f.write(b"blat\x1a") 5097db96d56Sopenharmony_ci f.write(b"extra\n") 5107db96d56Sopenharmony_ci os.lseek(f.fd, 0, os.SEEK_SET) 5117db96d56Sopenharmony_ci self.assertEqual(os.read(f.fd, 20), b"blat") 5127db96d56Sopenharmony_ci 5137db96d56Sopenharmony_ci def make_temp(self): 5147db96d56Sopenharmony_ci return tempfile._mkstemp_inner(tempfile.gettempdir(), 5157db96d56Sopenharmony_ci tempfile.gettempprefix(), 5167db96d56Sopenharmony_ci '', 5177db96d56Sopenharmony_ci tempfile._bin_openflags, 5187db96d56Sopenharmony_ci str) 5197db96d56Sopenharmony_ci 5207db96d56Sopenharmony_ci def test_collision_with_existing_file(self): 5217db96d56Sopenharmony_ci # _mkstemp_inner tries another name when a file with 5227db96d56Sopenharmony_ci # the chosen name already exists 5237db96d56Sopenharmony_ci with _inside_empty_temp_dir(), \ 5247db96d56Sopenharmony_ci _mock_candidate_names('aaa', 'aaa', 'bbb'): 5257db96d56Sopenharmony_ci (fd1, name1) = self.make_temp() 5267db96d56Sopenharmony_ci os.close(fd1) 5277db96d56Sopenharmony_ci self.assertTrue(name1.endswith('aaa')) 5287db96d56Sopenharmony_ci 5297db96d56Sopenharmony_ci (fd2, name2) = self.make_temp() 5307db96d56Sopenharmony_ci os.close(fd2) 5317db96d56Sopenharmony_ci self.assertTrue(name2.endswith('bbb')) 5327db96d56Sopenharmony_ci 5337db96d56Sopenharmony_ci def test_collision_with_existing_directory(self): 5347db96d56Sopenharmony_ci # _mkstemp_inner tries another name when a directory with 5357db96d56Sopenharmony_ci # the chosen name already exists 5367db96d56Sopenharmony_ci with _inside_empty_temp_dir(), \ 5377db96d56Sopenharmony_ci _mock_candidate_names('aaa', 'aaa', 'bbb'): 5387db96d56Sopenharmony_ci dir = tempfile.mkdtemp() 5397db96d56Sopenharmony_ci self.assertTrue(dir.endswith('aaa')) 5407db96d56Sopenharmony_ci 5417db96d56Sopenharmony_ci (fd, name) = self.make_temp() 5427db96d56Sopenharmony_ci os.close(fd) 5437db96d56Sopenharmony_ci self.assertTrue(name.endswith('bbb')) 5447db96d56Sopenharmony_ci 5457db96d56Sopenharmony_ci 5467db96d56Sopenharmony_ciclass TestGetTempPrefix(BaseTestCase): 5477db96d56Sopenharmony_ci """Test gettempprefix().""" 5487db96d56Sopenharmony_ci 5497db96d56Sopenharmony_ci def test_sane_template(self): 5507db96d56Sopenharmony_ci # gettempprefix returns a nonempty prefix string 5517db96d56Sopenharmony_ci p = tempfile.gettempprefix() 5527db96d56Sopenharmony_ci 5537db96d56Sopenharmony_ci self.assertIsInstance(p, str) 5547db96d56Sopenharmony_ci self.assertGreater(len(p), 0) 5557db96d56Sopenharmony_ci 5567db96d56Sopenharmony_ci pb = tempfile.gettempprefixb() 5577db96d56Sopenharmony_ci 5587db96d56Sopenharmony_ci self.assertIsInstance(pb, bytes) 5597db96d56Sopenharmony_ci self.assertGreater(len(pb), 0) 5607db96d56Sopenharmony_ci 5617db96d56Sopenharmony_ci def test_usable_template(self): 5627db96d56Sopenharmony_ci # gettempprefix returns a usable prefix string 5637db96d56Sopenharmony_ci 5647db96d56Sopenharmony_ci # Create a temp directory, avoiding use of the prefix. 5657db96d56Sopenharmony_ci # Then attempt to create a file whose name is 5667db96d56Sopenharmony_ci # prefix + 'xxxxxx.xxx' in that directory. 5677db96d56Sopenharmony_ci p = tempfile.gettempprefix() + "xxxxxx.xxx" 5687db96d56Sopenharmony_ci d = tempfile.mkdtemp(prefix="") 5697db96d56Sopenharmony_ci try: 5707db96d56Sopenharmony_ci p = os.path.join(d, p) 5717db96d56Sopenharmony_ci fd = os.open(p, os.O_RDWR | os.O_CREAT) 5727db96d56Sopenharmony_ci os.close(fd) 5737db96d56Sopenharmony_ci os.unlink(p) 5747db96d56Sopenharmony_ci finally: 5757db96d56Sopenharmony_ci os.rmdir(d) 5767db96d56Sopenharmony_ci 5777db96d56Sopenharmony_ci 5787db96d56Sopenharmony_ciclass TestGetTempDir(BaseTestCase): 5797db96d56Sopenharmony_ci """Test gettempdir().""" 5807db96d56Sopenharmony_ci 5817db96d56Sopenharmony_ci def test_directory_exists(self): 5827db96d56Sopenharmony_ci # gettempdir returns a directory which exists 5837db96d56Sopenharmony_ci 5847db96d56Sopenharmony_ci for d in (tempfile.gettempdir(), tempfile.gettempdirb()): 5857db96d56Sopenharmony_ci self.assertTrue(os.path.isabs(d) or d == os.curdir, 5867db96d56Sopenharmony_ci "%r is not an absolute path" % d) 5877db96d56Sopenharmony_ci self.assertTrue(os.path.isdir(d), 5887db96d56Sopenharmony_ci "%r is not a directory" % d) 5897db96d56Sopenharmony_ci 5907db96d56Sopenharmony_ci def test_directory_writable(self): 5917db96d56Sopenharmony_ci # gettempdir returns a directory writable by the user 5927db96d56Sopenharmony_ci 5937db96d56Sopenharmony_ci # sneaky: just instantiate a NamedTemporaryFile, which 5947db96d56Sopenharmony_ci # defaults to writing into the directory returned by 5957db96d56Sopenharmony_ci # gettempdir. 5967db96d56Sopenharmony_ci with tempfile.NamedTemporaryFile() as file: 5977db96d56Sopenharmony_ci file.write(b"blat") 5987db96d56Sopenharmony_ci 5997db96d56Sopenharmony_ci def test_same_thing(self): 6007db96d56Sopenharmony_ci # gettempdir always returns the same object 6017db96d56Sopenharmony_ci a = tempfile.gettempdir() 6027db96d56Sopenharmony_ci b = tempfile.gettempdir() 6037db96d56Sopenharmony_ci c = tempfile.gettempdirb() 6047db96d56Sopenharmony_ci 6057db96d56Sopenharmony_ci self.assertTrue(a is b) 6067db96d56Sopenharmony_ci self.assertNotEqual(type(a), type(c)) 6077db96d56Sopenharmony_ci self.assertEqual(a, os.fsdecode(c)) 6087db96d56Sopenharmony_ci 6097db96d56Sopenharmony_ci def test_case_sensitive(self): 6107db96d56Sopenharmony_ci # gettempdir should not flatten its case 6117db96d56Sopenharmony_ci # even on a case-insensitive file system 6127db96d56Sopenharmony_ci case_sensitive_tempdir = tempfile.mkdtemp("-Temp") 6137db96d56Sopenharmony_ci _tempdir, tempfile.tempdir = tempfile.tempdir, None 6147db96d56Sopenharmony_ci try: 6157db96d56Sopenharmony_ci with os_helper.EnvironmentVarGuard() as env: 6167db96d56Sopenharmony_ci # Fake the first env var which is checked as a candidate 6177db96d56Sopenharmony_ci env["TMPDIR"] = case_sensitive_tempdir 6187db96d56Sopenharmony_ci self.assertEqual(tempfile.gettempdir(), case_sensitive_tempdir) 6197db96d56Sopenharmony_ci finally: 6207db96d56Sopenharmony_ci tempfile.tempdir = _tempdir 6217db96d56Sopenharmony_ci os_helper.rmdir(case_sensitive_tempdir) 6227db96d56Sopenharmony_ci 6237db96d56Sopenharmony_ci 6247db96d56Sopenharmony_ciclass TestMkstemp(BaseTestCase): 6257db96d56Sopenharmony_ci """Test mkstemp().""" 6267db96d56Sopenharmony_ci 6277db96d56Sopenharmony_ci def do_create(self, dir=None, pre=None, suf=None): 6287db96d56Sopenharmony_ci output_type = tempfile._infer_return_type(dir, pre, suf) 6297db96d56Sopenharmony_ci if dir is None: 6307db96d56Sopenharmony_ci if output_type is str: 6317db96d56Sopenharmony_ci dir = tempfile.gettempdir() 6327db96d56Sopenharmony_ci else: 6337db96d56Sopenharmony_ci dir = tempfile.gettempdirb() 6347db96d56Sopenharmony_ci if pre is None: 6357db96d56Sopenharmony_ci pre = output_type() 6367db96d56Sopenharmony_ci if suf is None: 6377db96d56Sopenharmony_ci suf = output_type() 6387db96d56Sopenharmony_ci (fd, name) = tempfile.mkstemp(dir=dir, prefix=pre, suffix=suf) 6397db96d56Sopenharmony_ci (ndir, nbase) = os.path.split(name) 6407db96d56Sopenharmony_ci adir = os.path.abspath(dir) 6417db96d56Sopenharmony_ci self.assertEqual(adir, ndir, 6427db96d56Sopenharmony_ci "Directory '%s' incorrectly returned as '%s'" % (adir, ndir)) 6437db96d56Sopenharmony_ci 6447db96d56Sopenharmony_ci try: 6457db96d56Sopenharmony_ci self.nameCheck(name, dir, pre, suf) 6467db96d56Sopenharmony_ci finally: 6477db96d56Sopenharmony_ci os.close(fd) 6487db96d56Sopenharmony_ci os.unlink(name) 6497db96d56Sopenharmony_ci 6507db96d56Sopenharmony_ci def test_basic(self): 6517db96d56Sopenharmony_ci # mkstemp can create files 6527db96d56Sopenharmony_ci self.do_create() 6537db96d56Sopenharmony_ci self.do_create(pre="a") 6547db96d56Sopenharmony_ci self.do_create(suf="b") 6557db96d56Sopenharmony_ci self.do_create(pre="a", suf="b") 6567db96d56Sopenharmony_ci self.do_create(pre="aa", suf=".txt") 6577db96d56Sopenharmony_ci self.do_create(dir=".") 6587db96d56Sopenharmony_ci 6597db96d56Sopenharmony_ci def test_basic_with_bytes_names(self): 6607db96d56Sopenharmony_ci # mkstemp can create files when given name parts all 6617db96d56Sopenharmony_ci # specified as bytes. 6627db96d56Sopenharmony_ci d = tempfile.gettempdirb() 6637db96d56Sopenharmony_ci self.do_create(dir=d, suf=b"") 6647db96d56Sopenharmony_ci self.do_create(dir=d, pre=b"a") 6657db96d56Sopenharmony_ci self.do_create(dir=d, suf=b"b") 6667db96d56Sopenharmony_ci self.do_create(dir=d, pre=b"a", suf=b"b") 6677db96d56Sopenharmony_ci self.do_create(dir=d, pre=b"aa", suf=b".txt") 6687db96d56Sopenharmony_ci self.do_create(dir=b".") 6697db96d56Sopenharmony_ci with self.assertRaises(TypeError): 6707db96d56Sopenharmony_ci self.do_create(dir=".", pre=b"aa", suf=b".txt") 6717db96d56Sopenharmony_ci with self.assertRaises(TypeError): 6727db96d56Sopenharmony_ci self.do_create(dir=b".", pre="aa", suf=b".txt") 6737db96d56Sopenharmony_ci with self.assertRaises(TypeError): 6747db96d56Sopenharmony_ci self.do_create(dir=b".", pre=b"aa", suf=".txt") 6757db96d56Sopenharmony_ci 6767db96d56Sopenharmony_ci 6777db96d56Sopenharmony_ci def test_choose_directory(self): 6787db96d56Sopenharmony_ci # mkstemp can create directories in a user-selected directory 6797db96d56Sopenharmony_ci dir = tempfile.mkdtemp() 6807db96d56Sopenharmony_ci try: 6817db96d56Sopenharmony_ci self.do_create(dir=dir) 6827db96d56Sopenharmony_ci self.do_create(dir=pathlib.Path(dir)) 6837db96d56Sopenharmony_ci finally: 6847db96d56Sopenharmony_ci os.rmdir(dir) 6857db96d56Sopenharmony_ci 6867db96d56Sopenharmony_ci def test_for_tempdir_is_bytes_issue40701_api_warts(self): 6877db96d56Sopenharmony_ci orig_tempdir = tempfile.tempdir 6887db96d56Sopenharmony_ci self.assertIsInstance(tempfile.tempdir, (str, type(None))) 6897db96d56Sopenharmony_ci try: 6907db96d56Sopenharmony_ci fd, path = tempfile.mkstemp() 6917db96d56Sopenharmony_ci os.close(fd) 6927db96d56Sopenharmony_ci os.unlink(path) 6937db96d56Sopenharmony_ci self.assertIsInstance(path, str) 6947db96d56Sopenharmony_ci tempfile.tempdir = tempfile.gettempdirb() 6957db96d56Sopenharmony_ci self.assertIsInstance(tempfile.tempdir, bytes) 6967db96d56Sopenharmony_ci self.assertIsInstance(tempfile.gettempdir(), str) 6977db96d56Sopenharmony_ci self.assertIsInstance(tempfile.gettempdirb(), bytes) 6987db96d56Sopenharmony_ci fd, path = tempfile.mkstemp() 6997db96d56Sopenharmony_ci os.close(fd) 7007db96d56Sopenharmony_ci os.unlink(path) 7017db96d56Sopenharmony_ci self.assertIsInstance(path, bytes) 7027db96d56Sopenharmony_ci fd, path = tempfile.mkstemp(suffix='.txt') 7037db96d56Sopenharmony_ci os.close(fd) 7047db96d56Sopenharmony_ci os.unlink(path) 7057db96d56Sopenharmony_ci self.assertIsInstance(path, str) 7067db96d56Sopenharmony_ci fd, path = tempfile.mkstemp(prefix='test-temp-') 7077db96d56Sopenharmony_ci os.close(fd) 7087db96d56Sopenharmony_ci os.unlink(path) 7097db96d56Sopenharmony_ci self.assertIsInstance(path, str) 7107db96d56Sopenharmony_ci fd, path = tempfile.mkstemp(dir=tempfile.gettempdir()) 7117db96d56Sopenharmony_ci os.close(fd) 7127db96d56Sopenharmony_ci os.unlink(path) 7137db96d56Sopenharmony_ci self.assertIsInstance(path, str) 7147db96d56Sopenharmony_ci finally: 7157db96d56Sopenharmony_ci tempfile.tempdir = orig_tempdir 7167db96d56Sopenharmony_ci 7177db96d56Sopenharmony_ci 7187db96d56Sopenharmony_ciclass TestMkdtemp(TestBadTempdir, BaseTestCase): 7197db96d56Sopenharmony_ci """Test mkdtemp().""" 7207db96d56Sopenharmony_ci 7217db96d56Sopenharmony_ci def make_temp(self): 7227db96d56Sopenharmony_ci return tempfile.mkdtemp() 7237db96d56Sopenharmony_ci 7247db96d56Sopenharmony_ci def do_create(self, dir=None, pre=None, suf=None): 7257db96d56Sopenharmony_ci output_type = tempfile._infer_return_type(dir, pre, suf) 7267db96d56Sopenharmony_ci if dir is None: 7277db96d56Sopenharmony_ci if output_type is str: 7287db96d56Sopenharmony_ci dir = tempfile.gettempdir() 7297db96d56Sopenharmony_ci else: 7307db96d56Sopenharmony_ci dir = tempfile.gettempdirb() 7317db96d56Sopenharmony_ci if pre is None: 7327db96d56Sopenharmony_ci pre = output_type() 7337db96d56Sopenharmony_ci if suf is None: 7347db96d56Sopenharmony_ci suf = output_type() 7357db96d56Sopenharmony_ci name = tempfile.mkdtemp(dir=dir, prefix=pre, suffix=suf) 7367db96d56Sopenharmony_ci 7377db96d56Sopenharmony_ci try: 7387db96d56Sopenharmony_ci self.nameCheck(name, dir, pre, suf) 7397db96d56Sopenharmony_ci return name 7407db96d56Sopenharmony_ci except: 7417db96d56Sopenharmony_ci os.rmdir(name) 7427db96d56Sopenharmony_ci raise 7437db96d56Sopenharmony_ci 7447db96d56Sopenharmony_ci def test_basic(self): 7457db96d56Sopenharmony_ci # mkdtemp can create directories 7467db96d56Sopenharmony_ci os.rmdir(self.do_create()) 7477db96d56Sopenharmony_ci os.rmdir(self.do_create(pre="a")) 7487db96d56Sopenharmony_ci os.rmdir(self.do_create(suf="b")) 7497db96d56Sopenharmony_ci os.rmdir(self.do_create(pre="a", suf="b")) 7507db96d56Sopenharmony_ci os.rmdir(self.do_create(pre="aa", suf=".txt")) 7517db96d56Sopenharmony_ci 7527db96d56Sopenharmony_ci def test_basic_with_bytes_names(self): 7537db96d56Sopenharmony_ci # mkdtemp can create directories when given all binary parts 7547db96d56Sopenharmony_ci d = tempfile.gettempdirb() 7557db96d56Sopenharmony_ci os.rmdir(self.do_create(dir=d)) 7567db96d56Sopenharmony_ci os.rmdir(self.do_create(dir=d, pre=b"a")) 7577db96d56Sopenharmony_ci os.rmdir(self.do_create(dir=d, suf=b"b")) 7587db96d56Sopenharmony_ci os.rmdir(self.do_create(dir=d, pre=b"a", suf=b"b")) 7597db96d56Sopenharmony_ci os.rmdir(self.do_create(dir=d, pre=b"aa", suf=b".txt")) 7607db96d56Sopenharmony_ci with self.assertRaises(TypeError): 7617db96d56Sopenharmony_ci os.rmdir(self.do_create(dir=d, pre="aa", suf=b".txt")) 7627db96d56Sopenharmony_ci with self.assertRaises(TypeError): 7637db96d56Sopenharmony_ci os.rmdir(self.do_create(dir=d, pre=b"aa", suf=".txt")) 7647db96d56Sopenharmony_ci with self.assertRaises(TypeError): 7657db96d56Sopenharmony_ci os.rmdir(self.do_create(dir="", pre=b"aa", suf=b".txt")) 7667db96d56Sopenharmony_ci 7677db96d56Sopenharmony_ci def test_basic_many(self): 7687db96d56Sopenharmony_ci # mkdtemp can create many directories (stochastic) 7697db96d56Sopenharmony_ci extant = list(range(TEST_FILES)) 7707db96d56Sopenharmony_ci try: 7717db96d56Sopenharmony_ci for i in extant: 7727db96d56Sopenharmony_ci extant[i] = self.do_create(pre="aa") 7737db96d56Sopenharmony_ci finally: 7747db96d56Sopenharmony_ci for i in extant: 7757db96d56Sopenharmony_ci if(isinstance(i, str)): 7767db96d56Sopenharmony_ci os.rmdir(i) 7777db96d56Sopenharmony_ci 7787db96d56Sopenharmony_ci def test_choose_directory(self): 7797db96d56Sopenharmony_ci # mkdtemp can create directories in a user-selected directory 7807db96d56Sopenharmony_ci dir = tempfile.mkdtemp() 7817db96d56Sopenharmony_ci try: 7827db96d56Sopenharmony_ci os.rmdir(self.do_create(dir=dir)) 7837db96d56Sopenharmony_ci os.rmdir(self.do_create(dir=pathlib.Path(dir))) 7847db96d56Sopenharmony_ci finally: 7857db96d56Sopenharmony_ci os.rmdir(dir) 7867db96d56Sopenharmony_ci 7877db96d56Sopenharmony_ci @os_helper.skip_unless_working_chmod 7887db96d56Sopenharmony_ci def test_mode(self): 7897db96d56Sopenharmony_ci # mkdtemp creates directories with the proper mode 7907db96d56Sopenharmony_ci 7917db96d56Sopenharmony_ci dir = self.do_create() 7927db96d56Sopenharmony_ci try: 7937db96d56Sopenharmony_ci mode = stat.S_IMODE(os.stat(dir).st_mode) 7947db96d56Sopenharmony_ci mode &= 0o777 # Mask off sticky bits inherited from /tmp 7957db96d56Sopenharmony_ci expected = 0o700 7967db96d56Sopenharmony_ci if sys.platform == 'win32': 7977db96d56Sopenharmony_ci # There's no distinction among 'user', 'group' and 'world'; 7987db96d56Sopenharmony_ci # replicate the 'user' bits. 7997db96d56Sopenharmony_ci user = expected >> 6 8007db96d56Sopenharmony_ci expected = user * (1 + 8 + 64) 8017db96d56Sopenharmony_ci self.assertEqual(mode, expected) 8027db96d56Sopenharmony_ci finally: 8037db96d56Sopenharmony_ci os.rmdir(dir) 8047db96d56Sopenharmony_ci 8057db96d56Sopenharmony_ci @unittest.skipUnless(os.name == "nt", "Only on Windows.") 8067db96d56Sopenharmony_ci def test_mode_win32(self): 8077db96d56Sopenharmony_ci # Use icacls.exe to extract the users with some level of access 8087db96d56Sopenharmony_ci # Main thing we are testing is that the BUILTIN\Users group has 8097db96d56Sopenharmony_ci # no access. The exact ACL is going to vary based on which user 8107db96d56Sopenharmony_ci # is running the test. 8117db96d56Sopenharmony_ci dir = self.do_create() 8127db96d56Sopenharmony_ci try: 8137db96d56Sopenharmony_ci out = subprocess.check_output(["icacls.exe", dir], encoding="oem").casefold() 8147db96d56Sopenharmony_ci finally: 8157db96d56Sopenharmony_ci os.rmdir(dir) 8167db96d56Sopenharmony_ci 8177db96d56Sopenharmony_ci dir = dir.casefold() 8187db96d56Sopenharmony_ci users = set() 8197db96d56Sopenharmony_ci found_user = False 8207db96d56Sopenharmony_ci for line in out.strip().splitlines(): 8217db96d56Sopenharmony_ci acl = None 8227db96d56Sopenharmony_ci # First line of result includes our directory 8237db96d56Sopenharmony_ci if line.startswith(dir): 8247db96d56Sopenharmony_ci acl = line.removeprefix(dir).strip() 8257db96d56Sopenharmony_ci elif line and line[:1].isspace(): 8267db96d56Sopenharmony_ci acl = line.strip() 8277db96d56Sopenharmony_ci if acl: 8287db96d56Sopenharmony_ci users.add(acl.partition(":")[0]) 8297db96d56Sopenharmony_ci 8307db96d56Sopenharmony_ci self.assertNotIn(r"BUILTIN\Users".casefold(), users) 8317db96d56Sopenharmony_ci 8327db96d56Sopenharmony_ci def test_collision_with_existing_file(self): 8337db96d56Sopenharmony_ci # mkdtemp tries another name when a file with 8347db96d56Sopenharmony_ci # the chosen name already exists 8357db96d56Sopenharmony_ci with _inside_empty_temp_dir(), \ 8367db96d56Sopenharmony_ci _mock_candidate_names('aaa', 'aaa', 'bbb'): 8377db96d56Sopenharmony_ci file = tempfile.NamedTemporaryFile(delete=False) 8387db96d56Sopenharmony_ci file.close() 8397db96d56Sopenharmony_ci self.assertTrue(file.name.endswith('aaa')) 8407db96d56Sopenharmony_ci dir = tempfile.mkdtemp() 8417db96d56Sopenharmony_ci self.assertTrue(dir.endswith('bbb')) 8427db96d56Sopenharmony_ci 8437db96d56Sopenharmony_ci def test_collision_with_existing_directory(self): 8447db96d56Sopenharmony_ci # mkdtemp tries another name when a directory with 8457db96d56Sopenharmony_ci # the chosen name already exists 8467db96d56Sopenharmony_ci with _inside_empty_temp_dir(), \ 8477db96d56Sopenharmony_ci _mock_candidate_names('aaa', 'aaa', 'bbb'): 8487db96d56Sopenharmony_ci dir1 = tempfile.mkdtemp() 8497db96d56Sopenharmony_ci self.assertTrue(dir1.endswith('aaa')) 8507db96d56Sopenharmony_ci dir2 = tempfile.mkdtemp() 8517db96d56Sopenharmony_ci self.assertTrue(dir2.endswith('bbb')) 8527db96d56Sopenharmony_ci 8537db96d56Sopenharmony_ci def test_for_tempdir_is_bytes_issue40701_api_warts(self): 8547db96d56Sopenharmony_ci orig_tempdir = tempfile.tempdir 8557db96d56Sopenharmony_ci self.assertIsInstance(tempfile.tempdir, (str, type(None))) 8567db96d56Sopenharmony_ci try: 8577db96d56Sopenharmony_ci path = tempfile.mkdtemp() 8587db96d56Sopenharmony_ci os.rmdir(path) 8597db96d56Sopenharmony_ci self.assertIsInstance(path, str) 8607db96d56Sopenharmony_ci tempfile.tempdir = tempfile.gettempdirb() 8617db96d56Sopenharmony_ci self.assertIsInstance(tempfile.tempdir, bytes) 8627db96d56Sopenharmony_ci self.assertIsInstance(tempfile.gettempdir(), str) 8637db96d56Sopenharmony_ci self.assertIsInstance(tempfile.gettempdirb(), bytes) 8647db96d56Sopenharmony_ci path = tempfile.mkdtemp() 8657db96d56Sopenharmony_ci os.rmdir(path) 8667db96d56Sopenharmony_ci self.assertIsInstance(path, bytes) 8677db96d56Sopenharmony_ci path = tempfile.mkdtemp(suffix='-dir') 8687db96d56Sopenharmony_ci os.rmdir(path) 8697db96d56Sopenharmony_ci self.assertIsInstance(path, str) 8707db96d56Sopenharmony_ci path = tempfile.mkdtemp(prefix='test-mkdtemp-') 8717db96d56Sopenharmony_ci os.rmdir(path) 8727db96d56Sopenharmony_ci self.assertIsInstance(path, str) 8737db96d56Sopenharmony_ci path = tempfile.mkdtemp(dir=tempfile.gettempdir()) 8747db96d56Sopenharmony_ci os.rmdir(path) 8757db96d56Sopenharmony_ci self.assertIsInstance(path, str) 8767db96d56Sopenharmony_ci finally: 8777db96d56Sopenharmony_ci tempfile.tempdir = orig_tempdir 8787db96d56Sopenharmony_ci 8797db96d56Sopenharmony_ci 8807db96d56Sopenharmony_ciclass TestMktemp(BaseTestCase): 8817db96d56Sopenharmony_ci """Test mktemp().""" 8827db96d56Sopenharmony_ci 8837db96d56Sopenharmony_ci # For safety, all use of mktemp must occur in a private directory. 8847db96d56Sopenharmony_ci # We must also suppress the RuntimeWarning it generates. 8857db96d56Sopenharmony_ci def setUp(self): 8867db96d56Sopenharmony_ci self.dir = tempfile.mkdtemp() 8877db96d56Sopenharmony_ci super().setUp() 8887db96d56Sopenharmony_ci 8897db96d56Sopenharmony_ci def tearDown(self): 8907db96d56Sopenharmony_ci if self.dir: 8917db96d56Sopenharmony_ci os.rmdir(self.dir) 8927db96d56Sopenharmony_ci self.dir = None 8937db96d56Sopenharmony_ci super().tearDown() 8947db96d56Sopenharmony_ci 8957db96d56Sopenharmony_ci class mktemped: 8967db96d56Sopenharmony_ci _unlink = os.unlink 8977db96d56Sopenharmony_ci _bflags = tempfile._bin_openflags 8987db96d56Sopenharmony_ci 8997db96d56Sopenharmony_ci def __init__(self, dir, pre, suf): 9007db96d56Sopenharmony_ci self.name = tempfile.mktemp(dir=dir, prefix=pre, suffix=suf) 9017db96d56Sopenharmony_ci # Create the file. This will raise an exception if it's 9027db96d56Sopenharmony_ci # mysteriously appeared in the meanwhile. 9037db96d56Sopenharmony_ci os.close(os.open(self.name, self._bflags, 0o600)) 9047db96d56Sopenharmony_ci 9057db96d56Sopenharmony_ci def __del__(self): 9067db96d56Sopenharmony_ci self._unlink(self.name) 9077db96d56Sopenharmony_ci 9087db96d56Sopenharmony_ci def do_create(self, pre="", suf=""): 9097db96d56Sopenharmony_ci file = self.mktemped(self.dir, pre, suf) 9107db96d56Sopenharmony_ci 9117db96d56Sopenharmony_ci self.nameCheck(file.name, self.dir, pre, suf) 9127db96d56Sopenharmony_ci return file 9137db96d56Sopenharmony_ci 9147db96d56Sopenharmony_ci def test_basic(self): 9157db96d56Sopenharmony_ci # mktemp can choose usable file names 9167db96d56Sopenharmony_ci self.do_create() 9177db96d56Sopenharmony_ci self.do_create(pre="a") 9187db96d56Sopenharmony_ci self.do_create(suf="b") 9197db96d56Sopenharmony_ci self.do_create(pre="a", suf="b") 9207db96d56Sopenharmony_ci self.do_create(pre="aa", suf=".txt") 9217db96d56Sopenharmony_ci 9227db96d56Sopenharmony_ci def test_many(self): 9237db96d56Sopenharmony_ci # mktemp can choose many usable file names (stochastic) 9247db96d56Sopenharmony_ci extant = list(range(TEST_FILES)) 9257db96d56Sopenharmony_ci for i in extant: 9267db96d56Sopenharmony_ci extant[i] = self.do_create(pre="aa") 9277db96d56Sopenharmony_ci del extant 9287db96d56Sopenharmony_ci support.gc_collect() # For PyPy or other GCs. 9297db96d56Sopenharmony_ci 9307db96d56Sopenharmony_ci## def test_warning(self): 9317db96d56Sopenharmony_ci## # mktemp issues a warning when used 9327db96d56Sopenharmony_ci## warnings.filterwarnings("error", 9337db96d56Sopenharmony_ci## category=RuntimeWarning, 9347db96d56Sopenharmony_ci## message="mktemp") 9357db96d56Sopenharmony_ci## self.assertRaises(RuntimeWarning, 9367db96d56Sopenharmony_ci## tempfile.mktemp, dir=self.dir) 9377db96d56Sopenharmony_ci 9387db96d56Sopenharmony_ci 9397db96d56Sopenharmony_ci# We test _TemporaryFileWrapper by testing NamedTemporaryFile. 9407db96d56Sopenharmony_ci 9417db96d56Sopenharmony_ci 9427db96d56Sopenharmony_ciclass TestNamedTemporaryFile(BaseTestCase): 9437db96d56Sopenharmony_ci """Test NamedTemporaryFile().""" 9447db96d56Sopenharmony_ci 9457db96d56Sopenharmony_ci def do_create(self, dir=None, pre="", suf="", delete=True): 9467db96d56Sopenharmony_ci if dir is None: 9477db96d56Sopenharmony_ci dir = tempfile.gettempdir() 9487db96d56Sopenharmony_ci file = tempfile.NamedTemporaryFile(dir=dir, prefix=pre, suffix=suf, 9497db96d56Sopenharmony_ci delete=delete) 9507db96d56Sopenharmony_ci 9517db96d56Sopenharmony_ci self.nameCheck(file.name, dir, pre, suf) 9527db96d56Sopenharmony_ci return file 9537db96d56Sopenharmony_ci 9547db96d56Sopenharmony_ci 9557db96d56Sopenharmony_ci def test_basic(self): 9567db96d56Sopenharmony_ci # NamedTemporaryFile can create files 9577db96d56Sopenharmony_ci self.do_create() 9587db96d56Sopenharmony_ci self.do_create(pre="a") 9597db96d56Sopenharmony_ci self.do_create(suf="b") 9607db96d56Sopenharmony_ci self.do_create(pre="a", suf="b") 9617db96d56Sopenharmony_ci self.do_create(pre="aa", suf=".txt") 9627db96d56Sopenharmony_ci 9637db96d56Sopenharmony_ci def test_method_lookup(self): 9647db96d56Sopenharmony_ci # Issue #18879: Looking up a temporary file method should keep it 9657db96d56Sopenharmony_ci # alive long enough. 9667db96d56Sopenharmony_ci f = self.do_create() 9677db96d56Sopenharmony_ci wr = weakref.ref(f) 9687db96d56Sopenharmony_ci write = f.write 9697db96d56Sopenharmony_ci write2 = f.write 9707db96d56Sopenharmony_ci del f 9717db96d56Sopenharmony_ci write(b'foo') 9727db96d56Sopenharmony_ci del write 9737db96d56Sopenharmony_ci write2(b'bar') 9747db96d56Sopenharmony_ci del write2 9757db96d56Sopenharmony_ci if support.check_impl_detail(cpython=True): 9767db96d56Sopenharmony_ci # No reference cycle was created. 9777db96d56Sopenharmony_ci self.assertIsNone(wr()) 9787db96d56Sopenharmony_ci 9797db96d56Sopenharmony_ci def test_iter(self): 9807db96d56Sopenharmony_ci # Issue #23700: getting iterator from a temporary file should keep 9817db96d56Sopenharmony_ci # it alive as long as it's being iterated over 9827db96d56Sopenharmony_ci lines = [b'spam\n', b'eggs\n', b'beans\n'] 9837db96d56Sopenharmony_ci def make_file(): 9847db96d56Sopenharmony_ci f = tempfile.NamedTemporaryFile(mode='w+b') 9857db96d56Sopenharmony_ci f.write(b''.join(lines)) 9867db96d56Sopenharmony_ci f.seek(0) 9877db96d56Sopenharmony_ci return f 9887db96d56Sopenharmony_ci for i, l in enumerate(make_file()): 9897db96d56Sopenharmony_ci self.assertEqual(l, lines[i]) 9907db96d56Sopenharmony_ci self.assertEqual(i, len(lines) - 1) 9917db96d56Sopenharmony_ci 9927db96d56Sopenharmony_ci def test_creates_named(self): 9937db96d56Sopenharmony_ci # NamedTemporaryFile creates files with names 9947db96d56Sopenharmony_ci f = tempfile.NamedTemporaryFile() 9957db96d56Sopenharmony_ci self.assertTrue(os.path.exists(f.name), 9967db96d56Sopenharmony_ci "NamedTemporaryFile %s does not exist" % f.name) 9977db96d56Sopenharmony_ci 9987db96d56Sopenharmony_ci def test_del_on_close(self): 9997db96d56Sopenharmony_ci # A NamedTemporaryFile is deleted when closed 10007db96d56Sopenharmony_ci dir = tempfile.mkdtemp() 10017db96d56Sopenharmony_ci try: 10027db96d56Sopenharmony_ci with tempfile.NamedTemporaryFile(dir=dir) as f: 10037db96d56Sopenharmony_ci f.write(b'blat') 10047db96d56Sopenharmony_ci self.assertEqual(os.listdir(dir), []) 10057db96d56Sopenharmony_ci self.assertFalse(os.path.exists(f.name), 10067db96d56Sopenharmony_ci "NamedTemporaryFile %s exists after close" % f.name) 10077db96d56Sopenharmony_ci finally: 10087db96d56Sopenharmony_ci os.rmdir(dir) 10097db96d56Sopenharmony_ci 10107db96d56Sopenharmony_ci def test_dis_del_on_close(self): 10117db96d56Sopenharmony_ci # Tests that delete-on-close can be disabled 10127db96d56Sopenharmony_ci dir = tempfile.mkdtemp() 10137db96d56Sopenharmony_ci tmp = None 10147db96d56Sopenharmony_ci try: 10157db96d56Sopenharmony_ci f = tempfile.NamedTemporaryFile(dir=dir, delete=False) 10167db96d56Sopenharmony_ci tmp = f.name 10177db96d56Sopenharmony_ci f.write(b'blat') 10187db96d56Sopenharmony_ci f.close() 10197db96d56Sopenharmony_ci self.assertTrue(os.path.exists(f.name), 10207db96d56Sopenharmony_ci "NamedTemporaryFile %s missing after close" % f.name) 10217db96d56Sopenharmony_ci finally: 10227db96d56Sopenharmony_ci if tmp is not None: 10237db96d56Sopenharmony_ci os.unlink(tmp) 10247db96d56Sopenharmony_ci os.rmdir(dir) 10257db96d56Sopenharmony_ci 10267db96d56Sopenharmony_ci def test_multiple_close(self): 10277db96d56Sopenharmony_ci # A NamedTemporaryFile can be closed many times without error 10287db96d56Sopenharmony_ci f = tempfile.NamedTemporaryFile() 10297db96d56Sopenharmony_ci f.write(b'abc\n') 10307db96d56Sopenharmony_ci f.close() 10317db96d56Sopenharmony_ci f.close() 10327db96d56Sopenharmony_ci f.close() 10337db96d56Sopenharmony_ci 10347db96d56Sopenharmony_ci def test_context_manager(self): 10357db96d56Sopenharmony_ci # A NamedTemporaryFile can be used as a context manager 10367db96d56Sopenharmony_ci with tempfile.NamedTemporaryFile() as f: 10377db96d56Sopenharmony_ci self.assertTrue(os.path.exists(f.name)) 10387db96d56Sopenharmony_ci self.assertFalse(os.path.exists(f.name)) 10397db96d56Sopenharmony_ci def use_closed(): 10407db96d56Sopenharmony_ci with f: 10417db96d56Sopenharmony_ci pass 10427db96d56Sopenharmony_ci self.assertRaises(ValueError, use_closed) 10437db96d56Sopenharmony_ci 10447db96d56Sopenharmony_ci def test_bad_mode(self): 10457db96d56Sopenharmony_ci dir = tempfile.mkdtemp() 10467db96d56Sopenharmony_ci self.addCleanup(os_helper.rmtree, dir) 10477db96d56Sopenharmony_ci with self.assertRaises(ValueError): 10487db96d56Sopenharmony_ci tempfile.NamedTemporaryFile(mode='wr', dir=dir) 10497db96d56Sopenharmony_ci with self.assertRaises(TypeError): 10507db96d56Sopenharmony_ci tempfile.NamedTemporaryFile(mode=2, dir=dir) 10517db96d56Sopenharmony_ci self.assertEqual(os.listdir(dir), []) 10527db96d56Sopenharmony_ci 10537db96d56Sopenharmony_ci def test_bad_encoding(self): 10547db96d56Sopenharmony_ci dir = tempfile.mkdtemp() 10557db96d56Sopenharmony_ci self.addCleanup(os_helper.rmtree, dir) 10567db96d56Sopenharmony_ci with self.assertRaises(LookupError): 10577db96d56Sopenharmony_ci tempfile.NamedTemporaryFile('w', encoding='bad-encoding', dir=dir) 10587db96d56Sopenharmony_ci self.assertEqual(os.listdir(dir), []) 10597db96d56Sopenharmony_ci 10607db96d56Sopenharmony_ci def test_unexpected_error(self): 10617db96d56Sopenharmony_ci dir = tempfile.mkdtemp() 10627db96d56Sopenharmony_ci self.addCleanup(os_helper.rmtree, dir) 10637db96d56Sopenharmony_ci with mock.patch('tempfile._TemporaryFileWrapper') as mock_ntf, \ 10647db96d56Sopenharmony_ci mock.patch('io.open', mock.mock_open()) as mock_open: 10657db96d56Sopenharmony_ci mock_ntf.side_effect = KeyboardInterrupt() 10667db96d56Sopenharmony_ci with self.assertRaises(KeyboardInterrupt): 10677db96d56Sopenharmony_ci tempfile.NamedTemporaryFile(dir=dir) 10687db96d56Sopenharmony_ci mock_open().close.assert_called() 10697db96d56Sopenharmony_ci self.assertEqual(os.listdir(dir), []) 10707db96d56Sopenharmony_ci 10717db96d56Sopenharmony_ci # How to test the mode and bufsize parameters? 10727db96d56Sopenharmony_ci 10737db96d56Sopenharmony_ciclass TestSpooledTemporaryFile(BaseTestCase): 10747db96d56Sopenharmony_ci """Test SpooledTemporaryFile().""" 10757db96d56Sopenharmony_ci 10767db96d56Sopenharmony_ci def do_create(self, max_size=0, dir=None, pre="", suf=""): 10777db96d56Sopenharmony_ci if dir is None: 10787db96d56Sopenharmony_ci dir = tempfile.gettempdir() 10797db96d56Sopenharmony_ci file = tempfile.SpooledTemporaryFile(max_size=max_size, dir=dir, prefix=pre, suffix=suf) 10807db96d56Sopenharmony_ci 10817db96d56Sopenharmony_ci return file 10827db96d56Sopenharmony_ci 10837db96d56Sopenharmony_ci 10847db96d56Sopenharmony_ci def test_basic(self): 10857db96d56Sopenharmony_ci # SpooledTemporaryFile can create files 10867db96d56Sopenharmony_ci f = self.do_create() 10877db96d56Sopenharmony_ci self.assertFalse(f._rolled) 10887db96d56Sopenharmony_ci f = self.do_create(max_size=100, pre="a", suf=".txt") 10897db96d56Sopenharmony_ci self.assertFalse(f._rolled) 10907db96d56Sopenharmony_ci 10917db96d56Sopenharmony_ci def test_is_iobase(self): 10927db96d56Sopenharmony_ci # SpooledTemporaryFile should implement io.IOBase 10937db96d56Sopenharmony_ci self.assertIsInstance(self.do_create(), io.IOBase) 10947db96d56Sopenharmony_ci 10957db96d56Sopenharmony_ci def test_iobase_interface(self): 10967db96d56Sopenharmony_ci # SpooledTemporaryFile should implement the io.IOBase interface. 10977db96d56Sopenharmony_ci # Ensure it has all the required methods and properties. 10987db96d56Sopenharmony_ci iobase_attrs = { 10997db96d56Sopenharmony_ci # From IOBase 11007db96d56Sopenharmony_ci 'fileno', 'seek', 'truncate', 'close', 'closed', '__enter__', 11017db96d56Sopenharmony_ci '__exit__', 'flush', 'isatty', '__iter__', '__next__', 'readable', 11027db96d56Sopenharmony_ci 'readline', 'readlines', 'seekable', 'tell', 'writable', 11037db96d56Sopenharmony_ci 'writelines', 11047db96d56Sopenharmony_ci # From BufferedIOBase (binary mode) and TextIOBase (text mode) 11057db96d56Sopenharmony_ci 'detach', 'read', 'read1', 'write', 'readinto', 'readinto1', 11067db96d56Sopenharmony_ci 'encoding', 'errors', 'newlines', 11077db96d56Sopenharmony_ci } 11087db96d56Sopenharmony_ci spooledtempfile_attrs = set(dir(tempfile.SpooledTemporaryFile)) 11097db96d56Sopenharmony_ci missing_attrs = iobase_attrs - spooledtempfile_attrs 11107db96d56Sopenharmony_ci self.assertFalse( 11117db96d56Sopenharmony_ci missing_attrs, 11127db96d56Sopenharmony_ci 'SpooledTemporaryFile missing attributes from IOBase/BufferedIOBase/TextIOBase' 11137db96d56Sopenharmony_ci ) 11147db96d56Sopenharmony_ci 11157db96d56Sopenharmony_ci def test_del_on_close(self): 11167db96d56Sopenharmony_ci # A SpooledTemporaryFile is deleted when closed 11177db96d56Sopenharmony_ci dir = tempfile.mkdtemp() 11187db96d56Sopenharmony_ci try: 11197db96d56Sopenharmony_ci f = tempfile.SpooledTemporaryFile(max_size=10, dir=dir) 11207db96d56Sopenharmony_ci self.assertFalse(f._rolled) 11217db96d56Sopenharmony_ci f.write(b'blat ' * 5) 11227db96d56Sopenharmony_ci self.assertTrue(f._rolled) 11237db96d56Sopenharmony_ci filename = f.name 11247db96d56Sopenharmony_ci f.close() 11257db96d56Sopenharmony_ci self.assertEqual(os.listdir(dir), []) 11267db96d56Sopenharmony_ci if not isinstance(filename, int): 11277db96d56Sopenharmony_ci self.assertFalse(os.path.exists(filename), 11287db96d56Sopenharmony_ci "SpooledTemporaryFile %s exists after close" % filename) 11297db96d56Sopenharmony_ci finally: 11307db96d56Sopenharmony_ci os.rmdir(dir) 11317db96d56Sopenharmony_ci 11327db96d56Sopenharmony_ci def test_del_unrolled_file(self): 11337db96d56Sopenharmony_ci # The unrolled SpooledTemporaryFile should raise a ResourceWarning 11347db96d56Sopenharmony_ci # when deleted since the file was not explicitly closed. 11357db96d56Sopenharmony_ci f = self.do_create(max_size=10) 11367db96d56Sopenharmony_ci f.write(b'foo') 11377db96d56Sopenharmony_ci self.assertEqual(f.name, None) # Unrolled so no filename/fd 11387db96d56Sopenharmony_ci with self.assertWarns(ResourceWarning): 11397db96d56Sopenharmony_ci f.__del__() 11407db96d56Sopenharmony_ci 11417db96d56Sopenharmony_ci @unittest.skipIf( 11427db96d56Sopenharmony_ci support.is_emscripten, "Emscripten cannot fstat renamed files." 11437db96d56Sopenharmony_ci ) 11447db96d56Sopenharmony_ci def test_del_rolled_file(self): 11457db96d56Sopenharmony_ci # The rolled file should be deleted when the SpooledTemporaryFile 11467db96d56Sopenharmony_ci # object is deleted. This should raise a ResourceWarning since the file 11477db96d56Sopenharmony_ci # was not explicitly closed. 11487db96d56Sopenharmony_ci f = self.do_create(max_size=2) 11497db96d56Sopenharmony_ci f.write(b'foo') 11507db96d56Sopenharmony_ci name = f.name # This is a fd on posix+cygwin, a filename everywhere else 11517db96d56Sopenharmony_ci self.assertTrue(os.path.exists(name)) 11527db96d56Sopenharmony_ci with self.assertWarns(ResourceWarning): 11537db96d56Sopenharmony_ci f.__del__() 11547db96d56Sopenharmony_ci self.assertFalse( 11557db96d56Sopenharmony_ci os.path.exists(name), 11567db96d56Sopenharmony_ci "Rolled SpooledTemporaryFile (name=%s) exists after delete" % name 11577db96d56Sopenharmony_ci ) 11587db96d56Sopenharmony_ci 11597db96d56Sopenharmony_ci def test_rewrite_small(self): 11607db96d56Sopenharmony_ci # A SpooledTemporaryFile can be written to multiple within the max_size 11617db96d56Sopenharmony_ci f = self.do_create(max_size=30) 11627db96d56Sopenharmony_ci self.assertFalse(f._rolled) 11637db96d56Sopenharmony_ci for i in range(5): 11647db96d56Sopenharmony_ci f.seek(0, 0) 11657db96d56Sopenharmony_ci f.write(b'x' * 20) 11667db96d56Sopenharmony_ci self.assertFalse(f._rolled) 11677db96d56Sopenharmony_ci 11687db96d56Sopenharmony_ci def test_write_sequential(self): 11697db96d56Sopenharmony_ci # A SpooledTemporaryFile should hold exactly max_size bytes, and roll 11707db96d56Sopenharmony_ci # over afterward 11717db96d56Sopenharmony_ci f = self.do_create(max_size=30) 11727db96d56Sopenharmony_ci self.assertFalse(f._rolled) 11737db96d56Sopenharmony_ci f.write(b'x' * 20) 11747db96d56Sopenharmony_ci self.assertFalse(f._rolled) 11757db96d56Sopenharmony_ci f.write(b'x' * 10) 11767db96d56Sopenharmony_ci self.assertFalse(f._rolled) 11777db96d56Sopenharmony_ci f.write(b'x') 11787db96d56Sopenharmony_ci self.assertTrue(f._rolled) 11797db96d56Sopenharmony_ci 11807db96d56Sopenharmony_ci def test_writelines(self): 11817db96d56Sopenharmony_ci # Verify writelines with a SpooledTemporaryFile 11827db96d56Sopenharmony_ci f = self.do_create() 11837db96d56Sopenharmony_ci f.writelines((b'x', b'y', b'z')) 11847db96d56Sopenharmony_ci pos = f.seek(0) 11857db96d56Sopenharmony_ci self.assertEqual(pos, 0) 11867db96d56Sopenharmony_ci buf = f.read() 11877db96d56Sopenharmony_ci self.assertEqual(buf, b'xyz') 11887db96d56Sopenharmony_ci 11897db96d56Sopenharmony_ci def test_writelines_sequential(self): 11907db96d56Sopenharmony_ci # A SpooledTemporaryFile should hold exactly max_size bytes, and roll 11917db96d56Sopenharmony_ci # over afterward 11927db96d56Sopenharmony_ci f = self.do_create(max_size=35) 11937db96d56Sopenharmony_ci f.writelines((b'x' * 20, b'x' * 10, b'x' * 5)) 11947db96d56Sopenharmony_ci self.assertFalse(f._rolled) 11957db96d56Sopenharmony_ci f.write(b'x') 11967db96d56Sopenharmony_ci self.assertTrue(f._rolled) 11977db96d56Sopenharmony_ci 11987db96d56Sopenharmony_ci def test_sparse(self): 11997db96d56Sopenharmony_ci # A SpooledTemporaryFile that is written late in the file will extend 12007db96d56Sopenharmony_ci # when that occurs 12017db96d56Sopenharmony_ci f = self.do_create(max_size=30) 12027db96d56Sopenharmony_ci self.assertFalse(f._rolled) 12037db96d56Sopenharmony_ci pos = f.seek(100, 0) 12047db96d56Sopenharmony_ci self.assertEqual(pos, 100) 12057db96d56Sopenharmony_ci self.assertFalse(f._rolled) 12067db96d56Sopenharmony_ci f.write(b'x') 12077db96d56Sopenharmony_ci self.assertTrue(f._rolled) 12087db96d56Sopenharmony_ci 12097db96d56Sopenharmony_ci def test_fileno(self): 12107db96d56Sopenharmony_ci # A SpooledTemporaryFile should roll over to a real file on fileno() 12117db96d56Sopenharmony_ci f = self.do_create(max_size=30) 12127db96d56Sopenharmony_ci self.assertFalse(f._rolled) 12137db96d56Sopenharmony_ci self.assertTrue(f.fileno() > 0) 12147db96d56Sopenharmony_ci self.assertTrue(f._rolled) 12157db96d56Sopenharmony_ci 12167db96d56Sopenharmony_ci def test_multiple_close_before_rollover(self): 12177db96d56Sopenharmony_ci # A SpooledTemporaryFile can be closed many times without error 12187db96d56Sopenharmony_ci f = tempfile.SpooledTemporaryFile() 12197db96d56Sopenharmony_ci f.write(b'abc\n') 12207db96d56Sopenharmony_ci self.assertFalse(f._rolled) 12217db96d56Sopenharmony_ci f.close() 12227db96d56Sopenharmony_ci f.close() 12237db96d56Sopenharmony_ci f.close() 12247db96d56Sopenharmony_ci 12257db96d56Sopenharmony_ci def test_multiple_close_after_rollover(self): 12267db96d56Sopenharmony_ci # A SpooledTemporaryFile can be closed many times without error 12277db96d56Sopenharmony_ci f = tempfile.SpooledTemporaryFile(max_size=1) 12287db96d56Sopenharmony_ci f.write(b'abc\n') 12297db96d56Sopenharmony_ci self.assertTrue(f._rolled) 12307db96d56Sopenharmony_ci f.close() 12317db96d56Sopenharmony_ci f.close() 12327db96d56Sopenharmony_ci f.close() 12337db96d56Sopenharmony_ci 12347db96d56Sopenharmony_ci def test_bound_methods(self): 12357db96d56Sopenharmony_ci # It should be OK to steal a bound method from a SpooledTemporaryFile 12367db96d56Sopenharmony_ci # and use it independently; when the file rolls over, those bound 12377db96d56Sopenharmony_ci # methods should continue to function 12387db96d56Sopenharmony_ci f = self.do_create(max_size=30) 12397db96d56Sopenharmony_ci read = f.read 12407db96d56Sopenharmony_ci write = f.write 12417db96d56Sopenharmony_ci seek = f.seek 12427db96d56Sopenharmony_ci 12437db96d56Sopenharmony_ci write(b"a" * 35) 12447db96d56Sopenharmony_ci write(b"b" * 35) 12457db96d56Sopenharmony_ci seek(0, 0) 12467db96d56Sopenharmony_ci self.assertEqual(read(70), b'a'*35 + b'b'*35) 12477db96d56Sopenharmony_ci 12487db96d56Sopenharmony_ci def test_properties(self): 12497db96d56Sopenharmony_ci f = tempfile.SpooledTemporaryFile(max_size=10) 12507db96d56Sopenharmony_ci f.write(b'x' * 10) 12517db96d56Sopenharmony_ci self.assertFalse(f._rolled) 12527db96d56Sopenharmony_ci self.assertEqual(f.mode, 'w+b') 12537db96d56Sopenharmony_ci self.assertIsNone(f.name) 12547db96d56Sopenharmony_ci with self.assertRaises(AttributeError): 12557db96d56Sopenharmony_ci f.newlines 12567db96d56Sopenharmony_ci with self.assertRaises(AttributeError): 12577db96d56Sopenharmony_ci f.encoding 12587db96d56Sopenharmony_ci with self.assertRaises(AttributeError): 12597db96d56Sopenharmony_ci f.errors 12607db96d56Sopenharmony_ci 12617db96d56Sopenharmony_ci f.write(b'x') 12627db96d56Sopenharmony_ci self.assertTrue(f._rolled) 12637db96d56Sopenharmony_ci self.assertEqual(f.mode, 'rb+') 12647db96d56Sopenharmony_ci self.assertIsNotNone(f.name) 12657db96d56Sopenharmony_ci with self.assertRaises(AttributeError): 12667db96d56Sopenharmony_ci f.newlines 12677db96d56Sopenharmony_ci with self.assertRaises(AttributeError): 12687db96d56Sopenharmony_ci f.encoding 12697db96d56Sopenharmony_ci with self.assertRaises(AttributeError): 12707db96d56Sopenharmony_ci f.errors 12717db96d56Sopenharmony_ci 12727db96d56Sopenharmony_ci def test_text_mode(self): 12737db96d56Sopenharmony_ci # Creating a SpooledTemporaryFile with a text mode should produce 12747db96d56Sopenharmony_ci # a file object reading and writing (Unicode) text strings. 12757db96d56Sopenharmony_ci f = tempfile.SpooledTemporaryFile(mode='w+', max_size=10, 12767db96d56Sopenharmony_ci encoding="utf-8") 12777db96d56Sopenharmony_ci f.write("abc\n") 12787db96d56Sopenharmony_ci f.seek(0) 12797db96d56Sopenharmony_ci self.assertEqual(f.read(), "abc\n") 12807db96d56Sopenharmony_ci f.write("def\n") 12817db96d56Sopenharmony_ci f.seek(0) 12827db96d56Sopenharmony_ci self.assertEqual(f.read(), "abc\ndef\n") 12837db96d56Sopenharmony_ci self.assertFalse(f._rolled) 12847db96d56Sopenharmony_ci self.assertEqual(f.mode, 'w+') 12857db96d56Sopenharmony_ci self.assertIsNone(f.name) 12867db96d56Sopenharmony_ci self.assertEqual(f.newlines, os.linesep) 12877db96d56Sopenharmony_ci self.assertEqual(f.encoding, "utf-8") 12887db96d56Sopenharmony_ci self.assertEqual(f.errors, "strict") 12897db96d56Sopenharmony_ci 12907db96d56Sopenharmony_ci f.write("xyzzy\n") 12917db96d56Sopenharmony_ci f.seek(0) 12927db96d56Sopenharmony_ci self.assertEqual(f.read(), "abc\ndef\nxyzzy\n") 12937db96d56Sopenharmony_ci # Check that Ctrl+Z doesn't truncate the file 12947db96d56Sopenharmony_ci f.write("foo\x1abar\n") 12957db96d56Sopenharmony_ci f.seek(0) 12967db96d56Sopenharmony_ci self.assertEqual(f.read(), "abc\ndef\nxyzzy\nfoo\x1abar\n") 12977db96d56Sopenharmony_ci self.assertTrue(f._rolled) 12987db96d56Sopenharmony_ci self.assertEqual(f.mode, 'w+') 12997db96d56Sopenharmony_ci self.assertIsNotNone(f.name) 13007db96d56Sopenharmony_ci self.assertEqual(f.newlines, os.linesep) 13017db96d56Sopenharmony_ci self.assertEqual(f.encoding, "utf-8") 13027db96d56Sopenharmony_ci self.assertEqual(f.errors, "strict") 13037db96d56Sopenharmony_ci 13047db96d56Sopenharmony_ci def test_text_newline_and_encoding(self): 13057db96d56Sopenharmony_ci f = tempfile.SpooledTemporaryFile(mode='w+', max_size=10, 13067db96d56Sopenharmony_ci newline='', encoding='utf-8', 13077db96d56Sopenharmony_ci errors='ignore') 13087db96d56Sopenharmony_ci f.write("\u039B\r\n") 13097db96d56Sopenharmony_ci f.seek(0) 13107db96d56Sopenharmony_ci self.assertEqual(f.read(), "\u039B\r\n") 13117db96d56Sopenharmony_ci self.assertFalse(f._rolled) 13127db96d56Sopenharmony_ci self.assertEqual(f.mode, 'w+') 13137db96d56Sopenharmony_ci self.assertIsNone(f.name) 13147db96d56Sopenharmony_ci self.assertIsNotNone(f.newlines) 13157db96d56Sopenharmony_ci self.assertEqual(f.encoding, "utf-8") 13167db96d56Sopenharmony_ci self.assertEqual(f.errors, "ignore") 13177db96d56Sopenharmony_ci 13187db96d56Sopenharmony_ci f.write("\u039C" * 10 + "\r\n") 13197db96d56Sopenharmony_ci f.write("\u039D" * 20) 13207db96d56Sopenharmony_ci f.seek(0) 13217db96d56Sopenharmony_ci self.assertEqual(f.read(), 13227db96d56Sopenharmony_ci "\u039B\r\n" + ("\u039C" * 10) + "\r\n" + ("\u039D" * 20)) 13237db96d56Sopenharmony_ci self.assertTrue(f._rolled) 13247db96d56Sopenharmony_ci self.assertEqual(f.mode, 'w+') 13257db96d56Sopenharmony_ci self.assertIsNotNone(f.name) 13267db96d56Sopenharmony_ci self.assertIsNotNone(f.newlines) 13277db96d56Sopenharmony_ci self.assertEqual(f.encoding, 'utf-8') 13287db96d56Sopenharmony_ci self.assertEqual(f.errors, 'ignore') 13297db96d56Sopenharmony_ci 13307db96d56Sopenharmony_ci def test_context_manager_before_rollover(self): 13317db96d56Sopenharmony_ci # A SpooledTemporaryFile can be used as a context manager 13327db96d56Sopenharmony_ci with tempfile.SpooledTemporaryFile(max_size=1) as f: 13337db96d56Sopenharmony_ci self.assertFalse(f._rolled) 13347db96d56Sopenharmony_ci self.assertFalse(f.closed) 13357db96d56Sopenharmony_ci self.assertTrue(f.closed) 13367db96d56Sopenharmony_ci def use_closed(): 13377db96d56Sopenharmony_ci with f: 13387db96d56Sopenharmony_ci pass 13397db96d56Sopenharmony_ci self.assertRaises(ValueError, use_closed) 13407db96d56Sopenharmony_ci 13417db96d56Sopenharmony_ci def test_context_manager_during_rollover(self): 13427db96d56Sopenharmony_ci # A SpooledTemporaryFile can be used as a context manager 13437db96d56Sopenharmony_ci with tempfile.SpooledTemporaryFile(max_size=1) as f: 13447db96d56Sopenharmony_ci self.assertFalse(f._rolled) 13457db96d56Sopenharmony_ci f.write(b'abc\n') 13467db96d56Sopenharmony_ci f.flush() 13477db96d56Sopenharmony_ci self.assertTrue(f._rolled) 13487db96d56Sopenharmony_ci self.assertFalse(f.closed) 13497db96d56Sopenharmony_ci self.assertTrue(f.closed) 13507db96d56Sopenharmony_ci def use_closed(): 13517db96d56Sopenharmony_ci with f: 13527db96d56Sopenharmony_ci pass 13537db96d56Sopenharmony_ci self.assertRaises(ValueError, use_closed) 13547db96d56Sopenharmony_ci 13557db96d56Sopenharmony_ci def test_context_manager_after_rollover(self): 13567db96d56Sopenharmony_ci # A SpooledTemporaryFile can be used as a context manager 13577db96d56Sopenharmony_ci f = tempfile.SpooledTemporaryFile(max_size=1) 13587db96d56Sopenharmony_ci f.write(b'abc\n') 13597db96d56Sopenharmony_ci f.flush() 13607db96d56Sopenharmony_ci self.assertTrue(f._rolled) 13617db96d56Sopenharmony_ci with f: 13627db96d56Sopenharmony_ci self.assertFalse(f.closed) 13637db96d56Sopenharmony_ci self.assertTrue(f.closed) 13647db96d56Sopenharmony_ci def use_closed(): 13657db96d56Sopenharmony_ci with f: 13667db96d56Sopenharmony_ci pass 13677db96d56Sopenharmony_ci self.assertRaises(ValueError, use_closed) 13687db96d56Sopenharmony_ci 13697db96d56Sopenharmony_ci @unittest.skipIf( 13707db96d56Sopenharmony_ci support.is_emscripten, "Emscripten cannot fstat renamed files." 13717db96d56Sopenharmony_ci ) 13727db96d56Sopenharmony_ci def test_truncate_with_size_parameter(self): 13737db96d56Sopenharmony_ci # A SpooledTemporaryFile can be truncated to zero size 13747db96d56Sopenharmony_ci f = tempfile.SpooledTemporaryFile(max_size=10) 13757db96d56Sopenharmony_ci f.write(b'abcdefg\n') 13767db96d56Sopenharmony_ci f.seek(0) 13777db96d56Sopenharmony_ci f.truncate() 13787db96d56Sopenharmony_ci self.assertFalse(f._rolled) 13797db96d56Sopenharmony_ci self.assertEqual(f._file.getvalue(), b'') 13807db96d56Sopenharmony_ci # A SpooledTemporaryFile can be truncated to a specific size 13817db96d56Sopenharmony_ci f = tempfile.SpooledTemporaryFile(max_size=10) 13827db96d56Sopenharmony_ci f.write(b'abcdefg\n') 13837db96d56Sopenharmony_ci f.truncate(4) 13847db96d56Sopenharmony_ci self.assertFalse(f._rolled) 13857db96d56Sopenharmony_ci self.assertEqual(f._file.getvalue(), b'abcd') 13867db96d56Sopenharmony_ci # A SpooledTemporaryFile rolls over if truncated to large size 13877db96d56Sopenharmony_ci f = tempfile.SpooledTemporaryFile(max_size=10) 13887db96d56Sopenharmony_ci f.write(b'abcdefg\n') 13897db96d56Sopenharmony_ci f.truncate(20) 13907db96d56Sopenharmony_ci self.assertTrue(f._rolled) 13917db96d56Sopenharmony_ci self.assertEqual(os.fstat(f.fileno()).st_size, 20) 13927db96d56Sopenharmony_ci 13937db96d56Sopenharmony_ci def test_class_getitem(self): 13947db96d56Sopenharmony_ci self.assertIsInstance(tempfile.SpooledTemporaryFile[bytes], 13957db96d56Sopenharmony_ci types.GenericAlias) 13967db96d56Sopenharmony_ci 13977db96d56Sopenharmony_ciif tempfile.NamedTemporaryFile is not tempfile.TemporaryFile: 13987db96d56Sopenharmony_ci 13997db96d56Sopenharmony_ci class TestTemporaryFile(BaseTestCase): 14007db96d56Sopenharmony_ci """Test TemporaryFile().""" 14017db96d56Sopenharmony_ci 14027db96d56Sopenharmony_ci def test_basic(self): 14037db96d56Sopenharmony_ci # TemporaryFile can create files 14047db96d56Sopenharmony_ci # No point in testing the name params - the file has no name. 14057db96d56Sopenharmony_ci tempfile.TemporaryFile() 14067db96d56Sopenharmony_ci 14077db96d56Sopenharmony_ci def test_has_no_name(self): 14087db96d56Sopenharmony_ci # TemporaryFile creates files with no names (on this system) 14097db96d56Sopenharmony_ci dir = tempfile.mkdtemp() 14107db96d56Sopenharmony_ci f = tempfile.TemporaryFile(dir=dir) 14117db96d56Sopenharmony_ci f.write(b'blat') 14127db96d56Sopenharmony_ci 14137db96d56Sopenharmony_ci # Sneaky: because this file has no name, it should not prevent 14147db96d56Sopenharmony_ci # us from removing the directory it was created in. 14157db96d56Sopenharmony_ci try: 14167db96d56Sopenharmony_ci os.rmdir(dir) 14177db96d56Sopenharmony_ci except: 14187db96d56Sopenharmony_ci # cleanup 14197db96d56Sopenharmony_ci f.close() 14207db96d56Sopenharmony_ci os.rmdir(dir) 14217db96d56Sopenharmony_ci raise 14227db96d56Sopenharmony_ci 14237db96d56Sopenharmony_ci def test_multiple_close(self): 14247db96d56Sopenharmony_ci # A TemporaryFile can be closed many times without error 14257db96d56Sopenharmony_ci f = tempfile.TemporaryFile() 14267db96d56Sopenharmony_ci f.write(b'abc\n') 14277db96d56Sopenharmony_ci f.close() 14287db96d56Sopenharmony_ci f.close() 14297db96d56Sopenharmony_ci f.close() 14307db96d56Sopenharmony_ci 14317db96d56Sopenharmony_ci # How to test the mode and bufsize parameters? 14327db96d56Sopenharmony_ci def test_mode_and_encoding(self): 14337db96d56Sopenharmony_ci 14347db96d56Sopenharmony_ci def roundtrip(input, *args, **kwargs): 14357db96d56Sopenharmony_ci with tempfile.TemporaryFile(*args, **kwargs) as fileobj: 14367db96d56Sopenharmony_ci fileobj.write(input) 14377db96d56Sopenharmony_ci fileobj.seek(0) 14387db96d56Sopenharmony_ci self.assertEqual(input, fileobj.read()) 14397db96d56Sopenharmony_ci 14407db96d56Sopenharmony_ci roundtrip(b"1234", "w+b") 14417db96d56Sopenharmony_ci roundtrip("abdc\n", "w+") 14427db96d56Sopenharmony_ci roundtrip("\u039B", "w+", encoding="utf-16") 14437db96d56Sopenharmony_ci roundtrip("foo\r\n", "w+", newline="") 14447db96d56Sopenharmony_ci 14457db96d56Sopenharmony_ci def test_bad_mode(self): 14467db96d56Sopenharmony_ci dir = tempfile.mkdtemp() 14477db96d56Sopenharmony_ci self.addCleanup(os_helper.rmtree, dir) 14487db96d56Sopenharmony_ci with self.assertRaises(ValueError): 14497db96d56Sopenharmony_ci tempfile.TemporaryFile(mode='wr', dir=dir) 14507db96d56Sopenharmony_ci with self.assertRaises(TypeError): 14517db96d56Sopenharmony_ci tempfile.TemporaryFile(mode=2, dir=dir) 14527db96d56Sopenharmony_ci self.assertEqual(os.listdir(dir), []) 14537db96d56Sopenharmony_ci 14547db96d56Sopenharmony_ci def test_bad_encoding(self): 14557db96d56Sopenharmony_ci dir = tempfile.mkdtemp() 14567db96d56Sopenharmony_ci self.addCleanup(os_helper.rmtree, dir) 14577db96d56Sopenharmony_ci with self.assertRaises(LookupError): 14587db96d56Sopenharmony_ci tempfile.TemporaryFile('w', encoding='bad-encoding', dir=dir) 14597db96d56Sopenharmony_ci self.assertEqual(os.listdir(dir), []) 14607db96d56Sopenharmony_ci 14617db96d56Sopenharmony_ci def test_unexpected_error(self): 14627db96d56Sopenharmony_ci dir = tempfile.mkdtemp() 14637db96d56Sopenharmony_ci self.addCleanup(os_helper.rmtree, dir) 14647db96d56Sopenharmony_ci with mock.patch('tempfile._O_TMPFILE_WORKS', False), \ 14657db96d56Sopenharmony_ci mock.patch('os.unlink') as mock_unlink, \ 14667db96d56Sopenharmony_ci mock.patch('os.open') as mock_open, \ 14677db96d56Sopenharmony_ci mock.patch('os.close') as mock_close: 14687db96d56Sopenharmony_ci mock_unlink.side_effect = KeyboardInterrupt() 14697db96d56Sopenharmony_ci with self.assertRaises(KeyboardInterrupt): 14707db96d56Sopenharmony_ci tempfile.TemporaryFile(dir=dir) 14717db96d56Sopenharmony_ci mock_close.assert_called() 14727db96d56Sopenharmony_ci self.assertEqual(os.listdir(dir), []) 14737db96d56Sopenharmony_ci 14747db96d56Sopenharmony_ci 14757db96d56Sopenharmony_ci# Helper for test_del_on_shutdown 14767db96d56Sopenharmony_ciclass NulledModules: 14777db96d56Sopenharmony_ci def __init__(self, *modules): 14787db96d56Sopenharmony_ci self.refs = [mod.__dict__ for mod in modules] 14797db96d56Sopenharmony_ci self.contents = [ref.copy() for ref in self.refs] 14807db96d56Sopenharmony_ci 14817db96d56Sopenharmony_ci def __enter__(self): 14827db96d56Sopenharmony_ci for d in self.refs: 14837db96d56Sopenharmony_ci for key in d: 14847db96d56Sopenharmony_ci d[key] = None 14857db96d56Sopenharmony_ci 14867db96d56Sopenharmony_ci def __exit__(self, *exc_info): 14877db96d56Sopenharmony_ci for d, c in zip(self.refs, self.contents): 14887db96d56Sopenharmony_ci d.clear() 14897db96d56Sopenharmony_ci d.update(c) 14907db96d56Sopenharmony_ci 14917db96d56Sopenharmony_ci 14927db96d56Sopenharmony_ciclass TestTemporaryDirectory(BaseTestCase): 14937db96d56Sopenharmony_ci """Test TemporaryDirectory().""" 14947db96d56Sopenharmony_ci 14957db96d56Sopenharmony_ci def do_create(self, dir=None, pre="", suf="", recurse=1, dirs=1, files=1, 14967db96d56Sopenharmony_ci ignore_cleanup_errors=False): 14977db96d56Sopenharmony_ci if dir is None: 14987db96d56Sopenharmony_ci dir = tempfile.gettempdir() 14997db96d56Sopenharmony_ci tmp = tempfile.TemporaryDirectory( 15007db96d56Sopenharmony_ci dir=dir, prefix=pre, suffix=suf, 15017db96d56Sopenharmony_ci ignore_cleanup_errors=ignore_cleanup_errors) 15027db96d56Sopenharmony_ci self.nameCheck(tmp.name, dir, pre, suf) 15037db96d56Sopenharmony_ci self.do_create2(tmp.name, recurse, dirs, files) 15047db96d56Sopenharmony_ci return tmp 15057db96d56Sopenharmony_ci 15067db96d56Sopenharmony_ci def do_create2(self, path, recurse=1, dirs=1, files=1): 15077db96d56Sopenharmony_ci # Create subdirectories and some files 15087db96d56Sopenharmony_ci if recurse: 15097db96d56Sopenharmony_ci for i in range(dirs): 15107db96d56Sopenharmony_ci name = os.path.join(path, "dir%d" % i) 15117db96d56Sopenharmony_ci os.mkdir(name) 15127db96d56Sopenharmony_ci self.do_create2(name, recurse-1, dirs, files) 15137db96d56Sopenharmony_ci for i in range(files): 15147db96d56Sopenharmony_ci with open(os.path.join(path, "test%d.txt" % i), "wb") as f: 15157db96d56Sopenharmony_ci f.write(b"Hello world!") 15167db96d56Sopenharmony_ci 15177db96d56Sopenharmony_ci def test_mkdtemp_failure(self): 15187db96d56Sopenharmony_ci # Check no additional exception if mkdtemp fails 15197db96d56Sopenharmony_ci # Previously would raise AttributeError instead 15207db96d56Sopenharmony_ci # (noted as part of Issue #10188) 15217db96d56Sopenharmony_ci with tempfile.TemporaryDirectory() as nonexistent: 15227db96d56Sopenharmony_ci pass 15237db96d56Sopenharmony_ci with self.assertRaises(FileNotFoundError) as cm: 15247db96d56Sopenharmony_ci tempfile.TemporaryDirectory(dir=nonexistent) 15257db96d56Sopenharmony_ci self.assertEqual(cm.exception.errno, errno.ENOENT) 15267db96d56Sopenharmony_ci 15277db96d56Sopenharmony_ci def test_explicit_cleanup(self): 15287db96d56Sopenharmony_ci # A TemporaryDirectory is deleted when cleaned up 15297db96d56Sopenharmony_ci dir = tempfile.mkdtemp() 15307db96d56Sopenharmony_ci try: 15317db96d56Sopenharmony_ci d = self.do_create(dir=dir) 15327db96d56Sopenharmony_ci self.assertTrue(os.path.exists(d.name), 15337db96d56Sopenharmony_ci "TemporaryDirectory %s does not exist" % d.name) 15347db96d56Sopenharmony_ci d.cleanup() 15357db96d56Sopenharmony_ci self.assertFalse(os.path.exists(d.name), 15367db96d56Sopenharmony_ci "TemporaryDirectory %s exists after cleanup" % d.name) 15377db96d56Sopenharmony_ci finally: 15387db96d56Sopenharmony_ci os.rmdir(dir) 15397db96d56Sopenharmony_ci 15407db96d56Sopenharmony_ci def test_explict_cleanup_ignore_errors(self): 15417db96d56Sopenharmony_ci """Test that cleanup doesn't return an error when ignoring them.""" 15427db96d56Sopenharmony_ci with tempfile.TemporaryDirectory() as working_dir: 15437db96d56Sopenharmony_ci temp_dir = self.do_create( 15447db96d56Sopenharmony_ci dir=working_dir, ignore_cleanup_errors=True) 15457db96d56Sopenharmony_ci temp_path = pathlib.Path(temp_dir.name) 15467db96d56Sopenharmony_ci self.assertTrue(temp_path.exists(), 15477db96d56Sopenharmony_ci f"TemporaryDirectory {temp_path!s} does not exist") 15487db96d56Sopenharmony_ci with open(temp_path / "a_file.txt", "w+t") as open_file: 15497db96d56Sopenharmony_ci open_file.write("Hello world!\n") 15507db96d56Sopenharmony_ci temp_dir.cleanup() 15517db96d56Sopenharmony_ci self.assertEqual(len(list(temp_path.glob("*"))), 15527db96d56Sopenharmony_ci int(sys.platform.startswith("win")), 15537db96d56Sopenharmony_ci "Unexpected number of files in " 15547db96d56Sopenharmony_ci f"TemporaryDirectory {temp_path!s}") 15557db96d56Sopenharmony_ci self.assertEqual( 15567db96d56Sopenharmony_ci temp_path.exists(), 15577db96d56Sopenharmony_ci sys.platform.startswith("win"), 15587db96d56Sopenharmony_ci f"TemporaryDirectory {temp_path!s} existence state unexpected") 15597db96d56Sopenharmony_ci temp_dir.cleanup() 15607db96d56Sopenharmony_ci self.assertFalse( 15617db96d56Sopenharmony_ci temp_path.exists(), 15627db96d56Sopenharmony_ci f"TemporaryDirectory {temp_path!s} exists after cleanup") 15637db96d56Sopenharmony_ci 15647db96d56Sopenharmony_ci @os_helper.skip_unless_symlink 15657db96d56Sopenharmony_ci def test_cleanup_with_symlink_to_a_directory(self): 15667db96d56Sopenharmony_ci # cleanup() should not follow symlinks to directories (issue #12464) 15677db96d56Sopenharmony_ci d1 = self.do_create() 15687db96d56Sopenharmony_ci d2 = self.do_create(recurse=0) 15697db96d56Sopenharmony_ci 15707db96d56Sopenharmony_ci # Symlink d1/foo -> d2 15717db96d56Sopenharmony_ci os.symlink(d2.name, os.path.join(d1.name, "foo")) 15727db96d56Sopenharmony_ci 15737db96d56Sopenharmony_ci # This call to cleanup() should not follow the "foo" symlink 15747db96d56Sopenharmony_ci d1.cleanup() 15757db96d56Sopenharmony_ci 15767db96d56Sopenharmony_ci self.assertFalse(os.path.exists(d1.name), 15777db96d56Sopenharmony_ci "TemporaryDirectory %s exists after cleanup" % d1.name) 15787db96d56Sopenharmony_ci self.assertTrue(os.path.exists(d2.name), 15797db96d56Sopenharmony_ci "Directory pointed to by a symlink was deleted") 15807db96d56Sopenharmony_ci self.assertEqual(os.listdir(d2.name), ['test0.txt'], 15817db96d56Sopenharmony_ci "Contents of the directory pointed to by a symlink " 15827db96d56Sopenharmony_ci "were deleted") 15837db96d56Sopenharmony_ci d2.cleanup() 15847db96d56Sopenharmony_ci 15857db96d56Sopenharmony_ci @os_helper.skip_unless_symlink 15867db96d56Sopenharmony_ci def test_cleanup_with_symlink_modes(self): 15877db96d56Sopenharmony_ci # cleanup() should not follow symlinks when fixing mode bits (#91133) 15887db96d56Sopenharmony_ci with self.do_create(recurse=0) as d2: 15897db96d56Sopenharmony_ci file1 = os.path.join(d2, 'file1') 15907db96d56Sopenharmony_ci open(file1, 'wb').close() 15917db96d56Sopenharmony_ci dir1 = os.path.join(d2, 'dir1') 15927db96d56Sopenharmony_ci os.mkdir(dir1) 15937db96d56Sopenharmony_ci for mode in range(8): 15947db96d56Sopenharmony_ci mode <<= 6 15957db96d56Sopenharmony_ci with self.subTest(mode=format(mode, '03o')): 15967db96d56Sopenharmony_ci def test(target, target_is_directory): 15977db96d56Sopenharmony_ci d1 = self.do_create(recurse=0) 15987db96d56Sopenharmony_ci symlink = os.path.join(d1.name, 'symlink') 15997db96d56Sopenharmony_ci os.symlink(target, symlink, 16007db96d56Sopenharmony_ci target_is_directory=target_is_directory) 16017db96d56Sopenharmony_ci try: 16027db96d56Sopenharmony_ci os.chmod(symlink, mode, follow_symlinks=False) 16037db96d56Sopenharmony_ci except NotImplementedError: 16047db96d56Sopenharmony_ci pass 16057db96d56Sopenharmony_ci try: 16067db96d56Sopenharmony_ci os.chmod(symlink, mode) 16077db96d56Sopenharmony_ci except FileNotFoundError: 16087db96d56Sopenharmony_ci pass 16097db96d56Sopenharmony_ci os.chmod(d1.name, mode) 16107db96d56Sopenharmony_ci d1.cleanup() 16117db96d56Sopenharmony_ci self.assertFalse(os.path.exists(d1.name)) 16127db96d56Sopenharmony_ci 16137db96d56Sopenharmony_ci with self.subTest('nonexisting file'): 16147db96d56Sopenharmony_ci test('nonexisting', target_is_directory=False) 16157db96d56Sopenharmony_ci with self.subTest('nonexisting dir'): 16167db96d56Sopenharmony_ci test('nonexisting', target_is_directory=True) 16177db96d56Sopenharmony_ci 16187db96d56Sopenharmony_ci with self.subTest('existing file'): 16197db96d56Sopenharmony_ci os.chmod(file1, mode) 16207db96d56Sopenharmony_ci old_mode = os.stat(file1).st_mode 16217db96d56Sopenharmony_ci test(file1, target_is_directory=False) 16227db96d56Sopenharmony_ci new_mode = os.stat(file1).st_mode 16237db96d56Sopenharmony_ci self.assertEqual(new_mode, old_mode, 16247db96d56Sopenharmony_ci '%03o != %03o' % (new_mode, old_mode)) 16257db96d56Sopenharmony_ci 16267db96d56Sopenharmony_ci with self.subTest('existing dir'): 16277db96d56Sopenharmony_ci os.chmod(dir1, mode) 16287db96d56Sopenharmony_ci old_mode = os.stat(dir1).st_mode 16297db96d56Sopenharmony_ci test(dir1, target_is_directory=True) 16307db96d56Sopenharmony_ci new_mode = os.stat(dir1).st_mode 16317db96d56Sopenharmony_ci self.assertEqual(new_mode, old_mode, 16327db96d56Sopenharmony_ci '%03o != %03o' % (new_mode, old_mode)) 16337db96d56Sopenharmony_ci 16347db96d56Sopenharmony_ci @unittest.skipUnless(hasattr(os, 'chflags'), 'requires os.chflags') 16357db96d56Sopenharmony_ci @os_helper.skip_unless_symlink 16367db96d56Sopenharmony_ci def test_cleanup_with_symlink_flags(self): 16377db96d56Sopenharmony_ci # cleanup() should not follow symlinks when fixing flags (#91133) 16387db96d56Sopenharmony_ci flags = stat.UF_IMMUTABLE | stat.UF_NOUNLINK 16397db96d56Sopenharmony_ci self.check_flags(flags) 16407db96d56Sopenharmony_ci 16417db96d56Sopenharmony_ci with self.do_create(recurse=0) as d2: 16427db96d56Sopenharmony_ci file1 = os.path.join(d2, 'file1') 16437db96d56Sopenharmony_ci open(file1, 'wb').close() 16447db96d56Sopenharmony_ci dir1 = os.path.join(d2, 'dir1') 16457db96d56Sopenharmony_ci os.mkdir(dir1) 16467db96d56Sopenharmony_ci def test(target, target_is_directory): 16477db96d56Sopenharmony_ci d1 = self.do_create(recurse=0) 16487db96d56Sopenharmony_ci symlink = os.path.join(d1.name, 'symlink') 16497db96d56Sopenharmony_ci os.symlink(target, symlink, 16507db96d56Sopenharmony_ci target_is_directory=target_is_directory) 16517db96d56Sopenharmony_ci try: 16527db96d56Sopenharmony_ci os.chflags(symlink, flags, follow_symlinks=False) 16537db96d56Sopenharmony_ci except NotImplementedError: 16547db96d56Sopenharmony_ci pass 16557db96d56Sopenharmony_ci try: 16567db96d56Sopenharmony_ci os.chflags(symlink, flags) 16577db96d56Sopenharmony_ci except FileNotFoundError: 16587db96d56Sopenharmony_ci pass 16597db96d56Sopenharmony_ci os.chflags(d1.name, flags) 16607db96d56Sopenharmony_ci d1.cleanup() 16617db96d56Sopenharmony_ci self.assertFalse(os.path.exists(d1.name)) 16627db96d56Sopenharmony_ci 16637db96d56Sopenharmony_ci with self.subTest('nonexisting file'): 16647db96d56Sopenharmony_ci test('nonexisting', target_is_directory=False) 16657db96d56Sopenharmony_ci with self.subTest('nonexisting dir'): 16667db96d56Sopenharmony_ci test('nonexisting', target_is_directory=True) 16677db96d56Sopenharmony_ci 16687db96d56Sopenharmony_ci with self.subTest('existing file'): 16697db96d56Sopenharmony_ci os.chflags(file1, flags) 16707db96d56Sopenharmony_ci old_flags = os.stat(file1).st_flags 16717db96d56Sopenharmony_ci test(file1, target_is_directory=False) 16727db96d56Sopenharmony_ci new_flags = os.stat(file1).st_flags 16737db96d56Sopenharmony_ci self.assertEqual(new_flags, old_flags) 16747db96d56Sopenharmony_ci 16757db96d56Sopenharmony_ci with self.subTest('existing dir'): 16767db96d56Sopenharmony_ci os.chflags(dir1, flags) 16777db96d56Sopenharmony_ci old_flags = os.stat(dir1).st_flags 16787db96d56Sopenharmony_ci test(dir1, target_is_directory=True) 16797db96d56Sopenharmony_ci new_flags = os.stat(dir1).st_flags 16807db96d56Sopenharmony_ci self.assertEqual(new_flags, old_flags) 16817db96d56Sopenharmony_ci 16827db96d56Sopenharmony_ci @support.cpython_only 16837db96d56Sopenharmony_ci def test_del_on_collection(self): 16847db96d56Sopenharmony_ci # A TemporaryDirectory is deleted when garbage collected 16857db96d56Sopenharmony_ci dir = tempfile.mkdtemp() 16867db96d56Sopenharmony_ci try: 16877db96d56Sopenharmony_ci d = self.do_create(dir=dir) 16887db96d56Sopenharmony_ci name = d.name 16897db96d56Sopenharmony_ci del d # Rely on refcounting to invoke __del__ 16907db96d56Sopenharmony_ci self.assertFalse(os.path.exists(name), 16917db96d56Sopenharmony_ci "TemporaryDirectory %s exists after __del__" % name) 16927db96d56Sopenharmony_ci finally: 16937db96d56Sopenharmony_ci os.rmdir(dir) 16947db96d56Sopenharmony_ci 16957db96d56Sopenharmony_ci @support.cpython_only 16967db96d56Sopenharmony_ci def test_del_on_collection_ignore_errors(self): 16977db96d56Sopenharmony_ci """Test that ignoring errors works when TemporaryDirectory is gced.""" 16987db96d56Sopenharmony_ci with tempfile.TemporaryDirectory() as working_dir: 16997db96d56Sopenharmony_ci temp_dir = self.do_create( 17007db96d56Sopenharmony_ci dir=working_dir, ignore_cleanup_errors=True) 17017db96d56Sopenharmony_ci temp_path = pathlib.Path(temp_dir.name) 17027db96d56Sopenharmony_ci self.assertTrue(temp_path.exists(), 17037db96d56Sopenharmony_ci f"TemporaryDirectory {temp_path!s} does not exist") 17047db96d56Sopenharmony_ci with open(temp_path / "a_file.txt", "w+t") as open_file: 17057db96d56Sopenharmony_ci open_file.write("Hello world!\n") 17067db96d56Sopenharmony_ci del temp_dir 17077db96d56Sopenharmony_ci self.assertEqual(len(list(temp_path.glob("*"))), 17087db96d56Sopenharmony_ci int(sys.platform.startswith("win")), 17097db96d56Sopenharmony_ci "Unexpected number of files in " 17107db96d56Sopenharmony_ci f"TemporaryDirectory {temp_path!s}") 17117db96d56Sopenharmony_ci self.assertEqual( 17127db96d56Sopenharmony_ci temp_path.exists(), 17137db96d56Sopenharmony_ci sys.platform.startswith("win"), 17147db96d56Sopenharmony_ci f"TemporaryDirectory {temp_path!s} existence state unexpected") 17157db96d56Sopenharmony_ci 17167db96d56Sopenharmony_ci def test_del_on_shutdown(self): 17177db96d56Sopenharmony_ci # A TemporaryDirectory may be cleaned up during shutdown 17187db96d56Sopenharmony_ci with self.do_create() as dir: 17197db96d56Sopenharmony_ci for mod in ('builtins', 'os', 'shutil', 'sys', 'tempfile', 'warnings'): 17207db96d56Sopenharmony_ci code = """if True: 17217db96d56Sopenharmony_ci import builtins 17227db96d56Sopenharmony_ci import os 17237db96d56Sopenharmony_ci import shutil 17247db96d56Sopenharmony_ci import sys 17257db96d56Sopenharmony_ci import tempfile 17267db96d56Sopenharmony_ci import warnings 17277db96d56Sopenharmony_ci 17287db96d56Sopenharmony_ci tmp = tempfile.TemporaryDirectory(dir={dir!r}) 17297db96d56Sopenharmony_ci sys.stdout.buffer.write(tmp.name.encode()) 17307db96d56Sopenharmony_ci 17317db96d56Sopenharmony_ci tmp2 = os.path.join(tmp.name, 'test_dir') 17327db96d56Sopenharmony_ci os.mkdir(tmp2) 17337db96d56Sopenharmony_ci with open(os.path.join(tmp2, "test0.txt"), "w") as f: 17347db96d56Sopenharmony_ci f.write("Hello world!") 17357db96d56Sopenharmony_ci 17367db96d56Sopenharmony_ci {mod}.tmp = tmp 17377db96d56Sopenharmony_ci 17387db96d56Sopenharmony_ci warnings.filterwarnings("always", category=ResourceWarning) 17397db96d56Sopenharmony_ci """.format(dir=dir, mod=mod) 17407db96d56Sopenharmony_ci rc, out, err = script_helper.assert_python_ok("-c", code) 17417db96d56Sopenharmony_ci tmp_name = out.decode().strip() 17427db96d56Sopenharmony_ci self.assertFalse(os.path.exists(tmp_name), 17437db96d56Sopenharmony_ci "TemporaryDirectory %s exists after cleanup" % tmp_name) 17447db96d56Sopenharmony_ci err = err.decode('utf-8', 'backslashreplace') 17457db96d56Sopenharmony_ci self.assertNotIn("Exception ", err) 17467db96d56Sopenharmony_ci self.assertIn("ResourceWarning: Implicitly cleaning up", err) 17477db96d56Sopenharmony_ci 17487db96d56Sopenharmony_ci def test_del_on_shutdown_ignore_errors(self): 17497db96d56Sopenharmony_ci """Test ignoring errors works when a tempdir is gc'ed on shutdown.""" 17507db96d56Sopenharmony_ci with tempfile.TemporaryDirectory() as working_dir: 17517db96d56Sopenharmony_ci code = """if True: 17527db96d56Sopenharmony_ci import pathlib 17537db96d56Sopenharmony_ci import sys 17547db96d56Sopenharmony_ci import tempfile 17557db96d56Sopenharmony_ci import warnings 17567db96d56Sopenharmony_ci 17577db96d56Sopenharmony_ci temp_dir = tempfile.TemporaryDirectory( 17587db96d56Sopenharmony_ci dir={working_dir!r}, ignore_cleanup_errors=True) 17597db96d56Sopenharmony_ci sys.stdout.buffer.write(temp_dir.name.encode()) 17607db96d56Sopenharmony_ci 17617db96d56Sopenharmony_ci temp_dir_2 = pathlib.Path(temp_dir.name) / "test_dir" 17627db96d56Sopenharmony_ci temp_dir_2.mkdir() 17637db96d56Sopenharmony_ci with open(temp_dir_2 / "test0.txt", "w") as test_file: 17647db96d56Sopenharmony_ci test_file.write("Hello world!") 17657db96d56Sopenharmony_ci open_file = open(temp_dir_2 / "open_file.txt", "w") 17667db96d56Sopenharmony_ci open_file.write("Hello world!") 17677db96d56Sopenharmony_ci 17687db96d56Sopenharmony_ci warnings.filterwarnings("always", category=ResourceWarning) 17697db96d56Sopenharmony_ci """.format(working_dir=working_dir) 17707db96d56Sopenharmony_ci __, out, err = script_helper.assert_python_ok("-c", code) 17717db96d56Sopenharmony_ci temp_path = pathlib.Path(out.decode().strip()) 17727db96d56Sopenharmony_ci self.assertEqual(len(list(temp_path.glob("*"))), 17737db96d56Sopenharmony_ci int(sys.platform.startswith("win")), 17747db96d56Sopenharmony_ci "Unexpected number of files in " 17757db96d56Sopenharmony_ci f"TemporaryDirectory {temp_path!s}") 17767db96d56Sopenharmony_ci self.assertEqual( 17777db96d56Sopenharmony_ci temp_path.exists(), 17787db96d56Sopenharmony_ci sys.platform.startswith("win"), 17797db96d56Sopenharmony_ci f"TemporaryDirectory {temp_path!s} existence state unexpected") 17807db96d56Sopenharmony_ci err = err.decode('utf-8', 'backslashreplace') 17817db96d56Sopenharmony_ci self.assertNotIn("Exception", err) 17827db96d56Sopenharmony_ci self.assertNotIn("Error", err) 17837db96d56Sopenharmony_ci self.assertIn("ResourceWarning: Implicitly cleaning up", err) 17847db96d56Sopenharmony_ci 17857db96d56Sopenharmony_ci def test_exit_on_shutdown(self): 17867db96d56Sopenharmony_ci # Issue #22427 17877db96d56Sopenharmony_ci with self.do_create() as dir: 17887db96d56Sopenharmony_ci code = """if True: 17897db96d56Sopenharmony_ci import sys 17907db96d56Sopenharmony_ci import tempfile 17917db96d56Sopenharmony_ci import warnings 17927db96d56Sopenharmony_ci 17937db96d56Sopenharmony_ci def generator(): 17947db96d56Sopenharmony_ci with tempfile.TemporaryDirectory(dir={dir!r}) as tmp: 17957db96d56Sopenharmony_ci yield tmp 17967db96d56Sopenharmony_ci g = generator() 17977db96d56Sopenharmony_ci sys.stdout.buffer.write(next(g).encode()) 17987db96d56Sopenharmony_ci 17997db96d56Sopenharmony_ci warnings.filterwarnings("always", category=ResourceWarning) 18007db96d56Sopenharmony_ci """.format(dir=dir) 18017db96d56Sopenharmony_ci rc, out, err = script_helper.assert_python_ok("-c", code) 18027db96d56Sopenharmony_ci tmp_name = out.decode().strip() 18037db96d56Sopenharmony_ci self.assertFalse(os.path.exists(tmp_name), 18047db96d56Sopenharmony_ci "TemporaryDirectory %s exists after cleanup" % tmp_name) 18057db96d56Sopenharmony_ci err = err.decode('utf-8', 'backslashreplace') 18067db96d56Sopenharmony_ci self.assertNotIn("Exception ", err) 18077db96d56Sopenharmony_ci self.assertIn("ResourceWarning: Implicitly cleaning up", err) 18087db96d56Sopenharmony_ci 18097db96d56Sopenharmony_ci def test_warnings_on_cleanup(self): 18107db96d56Sopenharmony_ci # ResourceWarning will be triggered by __del__ 18117db96d56Sopenharmony_ci with self.do_create() as dir: 18127db96d56Sopenharmony_ci d = self.do_create(dir=dir, recurse=3) 18137db96d56Sopenharmony_ci name = d.name 18147db96d56Sopenharmony_ci 18157db96d56Sopenharmony_ci # Check for the resource warning 18167db96d56Sopenharmony_ci with warnings_helper.check_warnings(('Implicitly', 18177db96d56Sopenharmony_ci ResourceWarning), 18187db96d56Sopenharmony_ci quiet=False): 18197db96d56Sopenharmony_ci warnings.filterwarnings("always", category=ResourceWarning) 18207db96d56Sopenharmony_ci del d 18217db96d56Sopenharmony_ci support.gc_collect() 18227db96d56Sopenharmony_ci self.assertFalse(os.path.exists(name), 18237db96d56Sopenharmony_ci "TemporaryDirectory %s exists after __del__" % name) 18247db96d56Sopenharmony_ci 18257db96d56Sopenharmony_ci def test_multiple_close(self): 18267db96d56Sopenharmony_ci # Can be cleaned-up many times without error 18277db96d56Sopenharmony_ci d = self.do_create() 18287db96d56Sopenharmony_ci d.cleanup() 18297db96d56Sopenharmony_ci d.cleanup() 18307db96d56Sopenharmony_ci d.cleanup() 18317db96d56Sopenharmony_ci 18327db96d56Sopenharmony_ci def test_context_manager(self): 18337db96d56Sopenharmony_ci # Can be used as a context manager 18347db96d56Sopenharmony_ci d = self.do_create() 18357db96d56Sopenharmony_ci with d as name: 18367db96d56Sopenharmony_ci self.assertTrue(os.path.exists(name)) 18377db96d56Sopenharmony_ci self.assertEqual(name, d.name) 18387db96d56Sopenharmony_ci self.assertFalse(os.path.exists(name)) 18397db96d56Sopenharmony_ci 18407db96d56Sopenharmony_ci def test_modes(self): 18417db96d56Sopenharmony_ci for mode in range(8): 18427db96d56Sopenharmony_ci mode <<= 6 18437db96d56Sopenharmony_ci with self.subTest(mode=format(mode, '03o')): 18447db96d56Sopenharmony_ci d = self.do_create(recurse=3, dirs=2, files=2) 18457db96d56Sopenharmony_ci with d: 18467db96d56Sopenharmony_ci # Change files and directories mode recursively. 18477db96d56Sopenharmony_ci for root, dirs, files in os.walk(d.name, topdown=False): 18487db96d56Sopenharmony_ci for name in files: 18497db96d56Sopenharmony_ci os.chmod(os.path.join(root, name), mode) 18507db96d56Sopenharmony_ci os.chmod(root, mode) 18517db96d56Sopenharmony_ci d.cleanup() 18527db96d56Sopenharmony_ci self.assertFalse(os.path.exists(d.name)) 18537db96d56Sopenharmony_ci 18547db96d56Sopenharmony_ci def check_flags(self, flags): 18557db96d56Sopenharmony_ci # skip the test if these flags are not supported (ex: FreeBSD 13) 18567db96d56Sopenharmony_ci filename = os_helper.TESTFN 18577db96d56Sopenharmony_ci try: 18587db96d56Sopenharmony_ci open(filename, "w").close() 18597db96d56Sopenharmony_ci try: 18607db96d56Sopenharmony_ci os.chflags(filename, flags) 18617db96d56Sopenharmony_ci except OSError as exc: 18627db96d56Sopenharmony_ci # "OSError: [Errno 45] Operation not supported" 18637db96d56Sopenharmony_ci self.skipTest(f"chflags() doesn't support flags " 18647db96d56Sopenharmony_ci f"{flags:#b}: {exc}") 18657db96d56Sopenharmony_ci else: 18667db96d56Sopenharmony_ci os.chflags(filename, 0) 18677db96d56Sopenharmony_ci finally: 18687db96d56Sopenharmony_ci os_helper.unlink(filename) 18697db96d56Sopenharmony_ci 18707db96d56Sopenharmony_ci @unittest.skipUnless(hasattr(os, 'chflags'), 'requires os.chflags') 18717db96d56Sopenharmony_ci def test_flags(self): 18727db96d56Sopenharmony_ci flags = stat.UF_IMMUTABLE | stat.UF_NOUNLINK 18737db96d56Sopenharmony_ci self.check_flags(flags) 18747db96d56Sopenharmony_ci 18757db96d56Sopenharmony_ci d = self.do_create(recurse=3, dirs=2, files=2) 18767db96d56Sopenharmony_ci with d: 18777db96d56Sopenharmony_ci # Change files and directories flags recursively. 18787db96d56Sopenharmony_ci for root, dirs, files in os.walk(d.name, topdown=False): 18797db96d56Sopenharmony_ci for name in files: 18807db96d56Sopenharmony_ci os.chflags(os.path.join(root, name), flags) 18817db96d56Sopenharmony_ci os.chflags(root, flags) 18827db96d56Sopenharmony_ci d.cleanup() 18837db96d56Sopenharmony_ci self.assertFalse(os.path.exists(d.name)) 18847db96d56Sopenharmony_ci 18857db96d56Sopenharmony_ci 18867db96d56Sopenharmony_ciif __name__ == "__main__": 18877db96d56Sopenharmony_ci unittest.main() 1888