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