pyfakefs: Crash with pytest-subtests in Windows
Describe the bug I’m trying to use pyfakefs together with pytest-subtests. It works without any problems in Linux, but when I tested it on Windows, it just crashes. I’m not sure if I should report it here or on the pytest-subtests, but error points to pyfakefs, so I report it here.
How To Reproduce Execute this test in Windows:
import pytest_subtests
import pyfakefs
def test_subtest(subtests: pytest_subtests.SubTests, fs: pyfakefs.fake_filesystem.FakeFilesystem) -> None:
fs.os = pyfakefs.fake_filesystem.OSType.LINUX
with subtests.test("Test"):
print("Hello")
Full Error
========================================================================================================================================================================= test session starts =========================================================================================================================================================================
platform win32 -- Python 3.11.1, pytest-7.4.3, pluggy-1.0.0
benchmark: 4.0.0 (defaults: timer=time.perf_counter disable_gc=False min_rounds=5 min_time=0.000005 max_time=1.0 calibration_precision=10 warmup=False warmup_iterations=100000)
rootdir: C:\Users\username\tmp
plugins: anyio-3.7.1, Faker-18.4.0, pyfakefs-5.3.1, asyncio-0.21.0, benchmark-4.0.0, cov-4.1.0, integration-0.2.3, mock-3.11.1, recording-0.12.2, subtests-0.11.0, xdist-3.3.1, requests-mock-1.11.0
asyncio: mode=Mode.STRICT
collected 1 item
test.py F [100%]
============================================================================================================================================================================== FAILURES ===============================================================================================================================================================================
____________________________________________________________________________________________________________________________________________________________________________ test_subtest _____________________________________________________________________________________________________________________________________________________________________________
self = <pyfakefs.fake_filesystem.FakeFilesystem object at 0x0000017B356D4790>, file_path = '/C:\\Users\\username\\AppData\\Local\\Temp/tmph6mkc_a2', check_read_perm = True, check_owner = True
def get_object_from_normpath(
self,
file_path: AnyPath,
check_read_perm: bool = True,
check_owner: bool = False,
) -> AnyFile:
"""Search for the specified filesystem object within the fake
filesystem.
Args:
file_path: Specifies target FakeFile object to retrieve, with a
path that has already been normalized/resolved.
check_read_perm: If True, raises OSError if a parent directory
does not have read permission
check_owner: If True, and check_read_perm is also True,
only checks read permission if the current user id is
different from the file object user id
Returns:
The FakeFile object corresponding to file_path.
Raises:
OSError: if the object is not found.
"""
path = make_string_path(file_path)
if path == matching_string(path, self.root.name):
return self.root
if path == matching_string(path, self.dev_null.name):
return self.dev_null
path = self._original_path(path)
path_components = self._path_components(path)
target = self.root
try:
for component in path_components:
if S_ISLNK(target.st_mode):
if target.contents:
target = cast(FakeDirectory, self.resolve(target.contents))
if not S_ISDIR(target.st_mode):
if not self.is_windows_fs:
self.raise_os_error(errno.ENOTDIR, path)
self.raise_os_error(errno.ENOENT, path)
> target = target.get_entry(component) # type: ignore
C:\Users\username\AppData\Local\Programs\Python\Python311\Lib\site-packages\pyfakefs\fake_filesystem.py:1633:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = <pyfakefs.fake_file.FakeDirectory object at 0x0000017B357CF3D0>, pathname_name = 'C:\\Users\\username\\AppData\\Local\\Temp'
def get_entry(self, pathname_name: str) -> AnyFile:
"""Retrieves the specified child file or directory entry.
Args:
pathname_name: The basename of the child object to retrieve.
Returns:
The fake file or directory object.
Raises:
KeyError: if no child exists by the specified name.
"""
pathname_name = self._normalized_entryname(pathname_name)
> return self.entries[to_string(pathname_name)]
E KeyError: 'C:\\Users\\username\\AppData\\Local\\Temp'
C:\Users\username\AppData\Local\Programs\Python\Python311\Lib\site-packages\pyfakefs\fake_file.py:542: KeyError
During handling of the above exception, another exception occurred:
subtests = SubTests(ihook=<_pytest.config.compat.PathAwareHookProxy object at 0x0000017B306B1450>, suspend_capture_ctx=<bound met...='suspended' _in_suspended=False> _capture_fixture=None>>, request=<SubRequest 'subtests' for <Function test_subtest>>), fs = <pyfakefs.fake_filesystem.FakeFilesystem object at 0x0000017B356D4790>
def test_subtest(subtests: pytest_subtests.SubTests, fs: pyfakefs.fake_filesystem.FakeFilesystem) -> None:
fs.os = pyfakefs.fake_filesystem.OSType.LINUX
> with subtests.test("Test"):
C:\Users\username\tmp\test.py:8:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
C:\Users\username\AppData\Local\Programs\Python\Python311\Lib\contextlib.py:137: in __enter__
return next(self.gen)
C:\Users\username\AppData\Local\Programs\Python\Python311\Lib\site-packages\pytest_subtests.py:200: in test
with self._capturing_output() as captured_output, self._capturing_logs() as captured_logs:
C:\Users\username\AppData\Local\Programs\Python\Python311\Lib\contextlib.py:137: in __enter__
return next(self.gen)
C:\Users\username\AppData\Local\Programs\Python\Python311\Lib\site-packages\pytest_subtests.py:169: in _capturing_output
fixture._start()
C:\Users\username\AppData\Local\Programs\Python\Python311\Lib\site-packages\_pytest\capture.py:913: in _start
out=self.captureclass(1),
C:\Users\username\AppData\Local\Programs\Python\Python311\Lib\site-packages\_pytest\capture.py:466: in __init__
TemporaryFile(buffering=0),
C:\Users\username\AppData\Local\Programs\Python\Python311\Lib\tempfile.py:563: in NamedTemporaryFile
file = _io.open(dir, mode, buffering=buffering,
C:\Users\username\AppData\Local\Programs\Python\Python311\Lib\site-packages\pyfakefs\fake_io.py:124: in open
return fake_open(
C:\Users\username\AppData\Local\Programs\Python\Python311\Lib\site-packages\pyfakefs\fake_open.py:97: in __call__
return self.call(*args, **kwargs)
C:\Users\username\AppData\Local\Programs\Python\Python311\Lib\site-packages\pyfakefs\fake_open.py:158: in call
file_ = opener(file_, self._open_flags_from_open_modes(open_modes))
C:\Users\username\AppData\Local\Programs\Python\Python311\Lib\tempfile.py:560: in opener
fd, name = _mkstemp_inner(dir, prefix, suffix, flags, output_type)
C:\Users\username\AppData\Local\Programs\Python\Python311\Lib\tempfile.py:256: in _mkstemp_inner
fd = _os.open(file, flags, 0o600)
C:\Users\username\AppData\Local\Programs\Python\Python311\Lib\site-packages\pyfakefs\fake_os.py:1353: in wrapped
return f(*args, **kwargs)
C:\Users\username\AppData\Local\Programs\Python\Python311\Lib\site-packages\pyfakefs\fake_os.py:295: in open
self.chmod(path, mode)
C:\Users\username\AppData\Local\Programs\Python\Python311\Lib\site-packages\pyfakefs\fake_os.py:1353: in wrapped
return f(*args, **kwargs)
C:\Users\username\AppData\Local\Programs\Python\Python311\Lib\site-packages\pyfakefs\fake_os.py:1017: in chmod
self.filesystem.chmod(path, mode, follow_symlinks)
C:\Users\username\AppData\Local\Programs\Python\Python311\Lib\site-packages\pyfakefs\fake_filesystem.py:738: in chmod
file_object = self.resolve(
C:\Users\username\AppData\Local\Programs\Python\Python311\Lib\site-packages\pyfakefs\fake_filesystem.py:1709: in resolve
return self.get_object_from_normpath(
C:\Users\username\AppData\Local\Programs\Python\Python311\Lib\site-packages\pyfakefs\fake_filesystem.py:1642: in get_object_from_normpath
self.raise_os_error(errno.ENOENT, path)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = <pyfakefs.fake_filesystem.FakeFilesystem object at 0x0000017B356D4790>, err_no = 2, filename = '/C:\\Users\\username\\AppData\\Local\\Temp/tmph6mkc_a2', winerror = None
def raise_os_error(
self,
err_no: int,
filename: Optional[AnyString] = None,
winerror: Optional[int] = None,
) -> NoReturn:
"""Raises OSError.
The error message is constructed from the given error code and shall
start with the error string issued in the real system.
Note: this is not true under Windows if winerror is given - in this
case a localized message specific to winerror will be shown in the
real file system.
Args:
err_no: A numeric error code from the C variable errno.
filename: The name of the affected file, if any.
winerror: Windows only - the specific Windows error code.
"""
message = os.strerror(err_no) + " in the fake filesystem"
if winerror is not None and sys.platform == "win32" and self.is_windows_fs:
raise OSError(err_no, message, filename, winerror)
> raise OSError(err_no, message, filename)
E FileNotFoundError: [Errno 2] No such file or directory in the fake filesystem: '/C:\\Users\\username\\AppData\\Local\\Temp/tmph6mkc_a2'
C:\Users\username\AppData\Local\Programs\Python\Python311\Lib\site-packages\pyfakefs\fake_filesystem.py:429: FileNotFoundError
======================================================================================================================================================================= short test summary info =======================================================================================================================================================================
FAILED test.py::test_subtest - FileNotFoundError: [Errno 2] No such file or directory in the fake filesystem: '/C:\\Users\\username\\AppData\\Local\\Temp/tmph6mkc_a2'
========================================================================================================================================================================== 1 failed in 1.16s ==========================================================================================================================================================================
Your environment Please run the following in the environment where the problem happened and paste the output.
python -c "import platform; print(platform.platform())"
Windows-10-10.0.19045-SP0
python -c "import sys; print('Python', sys.version)"
Python 3.11.1 (tags/v3.11.1:a7a450f, Dec 6 2022, 19:58:39) [MSC v.1934 64 bit (AMD64)]
python -c "from pyfakefs import __version__; print('pyfakefs', __version__)"
pyfakefs 5.3.1
python -c "import pytest; print('pytest', pytest.__version__)"
pytest 7.4.3
About this issue
- Original URL
- State: closed
- Created 7 months ago
- Comments: 16 (11 by maintainers)
Commits related to this issue
- Fix separator mismatch with Linux emulated under Windows - the tempfile module will access the temp path using Windows separators under Windows, even if emulating Posix - this had to be handled -... — committed to mrbean-bremen/pyfakefs by mrbean-bremen 7 months ago
- Fix separator mismatch with Linux emulated under Windows - the tempfile module will access the temp path using Windows separators under Windows, even if emulating Posix - this had to be handled -... — committed to pytest-dev/pyfakefs by mrbean-bremen 7 months ago
The release is out.