diff --git a/CHANGES.md b/CHANGES.md index 0f7a5de3..cbbdc27c 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,6 +1,12 @@ # pyfakefs Release Notes The released versions correspond to PyPI releases. +## Unreleased + +### Fixes +* Re-create temp directory if it had been created before on resetting file system + (see [#814](../../issues/814)). + ## [Version 5.2.2](https://pypi.python.org/pypi/pyfakefs/5.2.2) (2023-04-13) Fixes a regression in 5.2.0 diff --git a/pyfakefs/fake_filesystem.py b/pyfakefs/fake_filesystem.py index 0b85e770..c3de9e48 100644 --- a/pyfakefs/fake_filesystem.py +++ b/pyfakefs/fake_filesystem.py @@ -85,6 +85,7 @@ import os import random import sys +import tempfile from collections import namedtuple, OrderedDict from doctest import TestResults from enum import Enum @@ -197,12 +198,17 @@ def __init__( path_separator: str = os.path.sep, total_size: Optional[int] = None, patcher: Any = None, + create_temp_dir: bool = False, ) -> None: """ Args: path_separator: optional substitute for os.path.sep total_size: if not None, the total size in bytes of the root filesystem. + patcher: the Patcher instance if created from the Patcher + create_temp_dir: If True, a temp directory is created on initialization. + Under Posix, if the temp directory is not `/tmp`, a link to the temp + path is additionally created at `/tmp`. Example usage to use the same path separator under all systems: @@ -212,6 +218,7 @@ def __init__( self.path_separator: str = path_separator self.alternative_path_separator: Optional[str] = os.path.altsep self.patcher = patcher + self.create_temp_dir = create_temp_dir if path_separator != os.sep: self.alternative_path_separator = None @@ -247,6 +254,7 @@ def __init__( self._add_root_mount_point(total_size) self._add_standard_streams() self.dev_null: Any = FakeNullFile(self) + self._create_temp_dir() # set from outside if needed self.patch_open_code = PatchMode.OFF self.shuffle_listdir_results = False @@ -342,6 +350,7 @@ def reset(self, total_size: Optional[int] = None): self.mount_points = OrderedDict() self._add_root_mount_point(total_size) self._add_standard_streams() + self._create_temp_dir() from pyfakefs import fake_pathlib fake_pathlib.init_module(self) @@ -1380,7 +1389,7 @@ def exists(self, file_path: AnyPath, check_link: bool = False) -> bool: """ if check_link and self.islink(file_path): return True - path = to_string(make_string_path(file_path)) + path = to_string(self.make_string_path(file_path)) if path is None: raise TypeError if not path: @@ -2915,6 +2924,21 @@ def _add_standard_streams(self) -> None: self._add_open_file(StandardStreamWrapper(sys.stdout)) self._add_open_file(StandardStreamWrapper(sys.stderr)) + def _create_temp_dir(self): + if not self.create_temp_dir: + return + # the temp directory is assumed to exist at least in `tempfile`, + # so we create it here for convenience + temp_dir = tempfile.gettempdir() + if not self.exists(temp_dir): + self.create_dir(temp_dir) + if sys.platform != "win32" and not self.exists("/tmp"): + # under Posix, we also create a link in /tmp if the path does not exist + self.create_symlink("/tmp", temp_dir) + # reset the used size to 0 to avoid having the link size counted + # which would make disk size tests more complicated + next(iter(self.mount_points.values()))["used_size"] = 0 + def _run_doctest() -> TestResults: import doctest diff --git a/pyfakefs/fake_filesystem_unittest.py b/pyfakefs/fake_filesystem_unittest.py index 00831b68..0e180553 100644 --- a/pyfakefs/fake_filesystem_unittest.py +++ b/pyfakefs/fake_filesystem_unittest.py @@ -35,7 +35,7 @@ pyfakefs by simply changing their base class from `:py:class`unittest.TestCase` to `:py:class`pyfakefs.fake_filesystem_unittest.TestCase`. """ -import _io # type:ignore [import] +import _io # type:ignore[import] import doctest import functools import genericpath @@ -844,7 +844,7 @@ def _refresh(self) -> None: self._stubs.smart_unset_all() self._stubs = mox3_stubout.StubOutForTesting() - self.fs = fake_filesystem.FakeFilesystem(patcher=self) + self.fs = fake_filesystem.FakeFilesystem(patcher=self, create_temp_dir=True) self.fs.patch_open_code = self.patch_open_code for name in self._fake_module_classes: self.fake_modules[name] = self._fake_module_classes[name](self.fs) @@ -876,7 +876,6 @@ def setUp(self, doctester: Any = None) -> None: if self.has_fcopy_file: shutil._HAS_FCOPYFILE = False # type: ignore[attr-defined] - temp_dir = tempfile.gettempdir() with warnings.catch_warnings(): # ignore warnings, see #542 and #614 warnings.filterwarnings("ignore") @@ -891,17 +890,6 @@ def setUp(self, doctester: Any = None) -> None: linecache.open = self.original_open # type: ignore[attr-defined] tokenize._builtin_open = self.original_open # type: ignore - # the temp directory is assumed to exist at least in `tempfile`, - # so we create it here for convenience - assert self.fs is not None - self.fs.create_dir(temp_dir) - if sys.platform != "win32" and not self.fs.exists("/tmp"): - # under Posix, we also create a link in /tmp if the path does not exist - self.fs.create_symlink("/tmp", temp_dir) - # reset the used size to 0 to avoid having the link size counted - # which would make disk size tests more complicated - next(iter(self.fs.mount_points.values()))["used_size"] = 0 - def start_patching(self) -> None: if not self._patching: self._patching = True diff --git a/pyfakefs/pytest_tests/pytest_plugin_test.py b/pyfakefs/pytest_tests/pytest_plugin_test.py index 22221912..51f95cbd 100644 --- a/pyfakefs/pytest_tests/pytest_plugin_test.py +++ b/pyfakefs/pytest_tests/pytest_plugin_test.py @@ -2,6 +2,7 @@ import os import tempfile +from pyfakefs.fake_filesystem import OSType from pyfakefs.fake_filesystem_unittest import Pause import pyfakefs.pytest_tests.io @@ -60,3 +61,18 @@ def test_use_own_io_module(fs): stream = pyfakefs.pytest_tests.io.InputStream(filepath) assert stream.read() == "bar" + + +def test_switch_to_windows(fs): + fs.os = OSType.WINDOWS + assert os.path.exists(tempfile.gettempdir()) + + +def test_switch_to_linux(fs): + fs.os = OSType.LINUX + assert os.path.exists(tempfile.gettempdir()) + + +def test_switch_to_macos(fs): + fs.os = OSType.MACOS + assert os.path.exists(tempfile.gettempdir()) diff --git a/pyfakefs/tests/fake_filesystem_unittest_test.py b/pyfakefs/tests/fake_filesystem_unittest_test.py index f77677c3..88b08d1b 100644 --- a/pyfakefs/tests/fake_filesystem_unittest_test.py +++ b/pyfakefs/tests/fake_filesystem_unittest_test.py @@ -657,11 +657,11 @@ class TestTempDirCreation(fake_filesystem_unittest.TestCase): def setUp(self): self.setUpPyfakefs() - def testTempDirExists(self): + def test_tempdir_exists(self): self.assertTrue(os.path.exists(tempfile.gettempdir())) @unittest.skipIf(sys.platform == "win32", "POSIX only test") - def testTmpExists(self): + def test_tmp_exists(self): # directory or link under Linux, link under macOS self.assertTrue(os.path.exists("/tmp"))