diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 68ed1371..d0ec480d 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -11,13 +11,13 @@ repos: - "--py310-plus" - repo: https://github.com/astral-sh/ruff-pre-commit - rev: "v0.15.11" + rev: "v0.16.3" hooks: - id: ruff args: ["--fix"] - id: ruff-format - repo: https://github.com/codespell-project/codespell - rev: v2.4.2 + rev: v2.4.3 hooks: - id: codespell args: @@ -44,7 +44,7 @@ repos: language: python files: \.py$ - repo: https://github.com/pre-commit/mirrors-mypy - rev: v1.20.1 + rev: v2.3.1 hooks: - id: mypy exclude: (docs|pyfakefs/tests) diff --git a/docs/conf.py b/docs/conf.py old mode 100644 new mode 100755 diff --git a/pyfakefs/__init__.py b/pyfakefs/__init__.py old mode 100755 new mode 100644 diff --git a/pyfakefs/fake_file.py b/pyfakefs/fake_file.py index 6c6ada11..4e30676b 100644 --- a/pyfakefs/fake_file.py +++ b/pyfakefs/fake_file.py @@ -22,38 +22,37 @@ import sys import traceback import weakref +from collections.abc import Callable, Iterator from stat import ( - S_IFREG, S_IFDIR, + S_IFREG, ) from types import TracebackType from typing import ( - Union, + TYPE_CHECKING, Any, - cast, AnyStr, NoReturn, TextIO, - TYPE_CHECKING, + Union, + cast, ) -from collections.abc import Callable, Iterator - from pyfakefs import helpers from pyfakefs.helpers import ( - FakeStatResult, + AnyPath, + AnyString, BinaryBufferIO, + FakeStatResult, TextBufferIO, + _OpenModes, + get_locale_encoding, is_int_type, + is_root, is_unicode_string, - to_string, matching_string, real_encoding, - AnyPath, - AnyString, - get_locale_encoding, - _OpenModes, - is_root, + to_string, ) if TYPE_CHECKING: @@ -79,8 +78,7 @@ class FakeLargeFileIoException(Exception): def __init__(self, file_path: str) -> None: super().__init__( - "Read and write operations not supported for " - "fake large file: %s" % file_path + f"Read and write operations not supported for fake large file: {file_path}" ) @@ -635,7 +633,7 @@ def remove_entry(self, pathname_name: str, recursive: bool = True) -> None: if recursive and isinstance(entry, FakeDirectory): while entry.entries: - entry.remove_entry(list(entry.entries)[0]) + entry.remove_entry(next(iter(entry.entries))) elif entry.st_nlink == 1: self.filesystem.change_disk_usage(-entry.size, pathname_name, entry.st_dev) @@ -836,7 +834,7 @@ def filesystem(self) -> FakeFilesystem: assert fs is not None return fs - def __enter__(self) -> FakeFileWrapper: + def __enter__(self) -> FakeFileWrapper: # noqa:PYI034 """To support usage of this fake file with the 'with' statement.""" return self @@ -1255,9 +1253,8 @@ def __getattr__(self, name: str) -> Any: def _read_error(self) -> Callable: def read_error(*args, **kwargs): """Throw an error unless the argument is zero.""" - if args and args[0] == 0: - if self.filesystem.is_windows_fs and self.raw_io: - return b"" if self._binary else "" + if args and args[0] == 0 and self.filesystem.is_windows_fs and self.raw_io: + return b"" if self._binary else "" self._raise("File is not open for reading.") return read_error @@ -1265,9 +1262,13 @@ def read_error(*args, **kwargs): def _write_error(self) -> Callable: def write_error(*args, **kwargs): """Throw an error.""" - if self.raw_io: - if self.filesystem.is_windows_fs and args and len(args[0]) == 0: - return 0 + if ( + self.raw_io + and self.filesystem.is_windows_fs + and args + and len(args[0]) == 0 + ): + return 0 self._raise("File is not open for writing.") return write_error @@ -1352,7 +1353,7 @@ def close_fd(self, fd: int | None) -> None: def is_stream(self) -> bool: return True - def __enter__(self) -> StandardStreamWrapper: + def __enter__(self) -> StandardStreamWrapper: # noqa:PYI034 """To support usage of this standard stream with the 'with' statement.""" return self @@ -1410,7 +1411,7 @@ def write(self, contents: bytes) -> int: self.file_object.write(contents) return len(contents) - def __enter__(self) -> FakeDirWrapper: + def __enter__(self) -> FakeDirWrapper: # noqa:PYI034 """To support usage of this fake directory with the 'with' statement.""" return self @@ -1443,9 +1444,9 @@ def __init__( self.filedes: int | None = None self.real_file = None if mode: - self.real_file = open(fd, mode) + self.real_file = open(fd, mode) # noqa: SIM115 - def __enter__(self) -> FakePipeWrapper: + def __enter__(self) -> FakePipeWrapper: # noqa:PYI034 """To support usage of this fake pipe with the 'with' statement.""" return self diff --git a/pyfakefs/fake_filesystem.py b/pyfakefs/fake_filesystem.py index 7ea38657..2f4bcfd0 100644 --- a/pyfakefs/fake_filesystem.py +++ b/pyfakefs/fake_filesystem.py @@ -92,42 +92,40 @@ import sys import tempfile import weakref -from collections import namedtuple, OrderedDict +from collections import OrderedDict, namedtuple +from collections.abc import Callable from doctest import TestResults from enum import Enum - from stat import ( - S_IFREG, S_IFDIR, - S_ISLNK, + S_IFLNK, S_IFMT, + S_IFREG, S_ISDIR, - S_IFLNK, + S_ISLNK, S_ISREG, ) from typing import ( + TYPE_CHECKING, Any, - cast, AnyStr, - overload, NoReturn, - TYPE_CHECKING, + cast, + overload, ) -from collections.abc import Callable - -from pyfakefs import fake_file, fake_path, fake_io, fake_os, helpers, fake_open -from pyfakefs.fake_file import AnyFileWrapper, AnyFile +from pyfakefs import fake_file, fake_io, fake_open, fake_os, fake_path, helpers +from pyfakefs.fake_file import AnyFile, AnyFileWrapper from pyfakefs.helpers import ( - is_int_type, - make_string_path, - to_string, - matching_string, + POSIX_PROPERTIES, + WINDOWS_PROPERTIES, AnyPath, AnyString, - WINDOWS_PROPERTIES, - POSIX_PROPERTIES, FSType, + is_int_type, + make_string_path, + matching_string, + to_string, ) if TYPE_CHECKING: @@ -745,9 +743,11 @@ def change_disk_usage( mount_point = self._mount_point_for_device(st_dev) if mount_point: total_size = mount_point["total_size"] - if total_size is not None: - if total_size - mount_point["used_size"] < usage_change: - self.raise_os_error(errno.ENOSPC, file_path) + if ( + total_size is not None + and total_size - mount_point["used_size"] < usage_change + ): + self.raise_os_error(errno.ENOSPC, file_path) mount_point["used_size"] += usage_change def stat(self, entry_path: AnyStr, follow_symlinks: bool = True): @@ -1208,25 +1208,24 @@ def splitdrive(self, path: AnyStr) -> tuple[AnyStr, AnyStr]: not supported or no drive is present. """ path_str = make_string_path(path) - if self.is_windows_fs: - if len(path_str) >= 2: - norm_str = self.normcase(path_str) - sep = self.get_path_separator(path_str) - # UNC path_str handling - if (norm_str[0:2] == sep * 2) and (norm_str[2:3] != sep): - # UNC path_str handling - splits off the mount point - # instead of the drive - sep_index = norm_str.find(sep, 2) - if sep_index == -1: - return path_str[:0], path_str - sep_index2 = norm_str.find(sep, sep_index + 1) - if sep_index2 == sep_index + 1: - return path_str[:0], path_str - if sep_index2 == -1: - sep_index2 = len(path_str) - return path_str[:sep_index2], path_str[sep_index2:] - if path_str[1:2] == matching_string(path_str, ":"): - return path_str[:2], path_str[2:] + if self.is_windows_fs and len(path_str) >= 2: + norm_str = self.normcase(path_str) + sep = self.get_path_separator(path_str) + # UNC path_str handling + if (norm_str[0:2] == sep * 2) and (norm_str[2:3] != sep): + # UNC path_str handling - splits off the mount point + # instead of the drive + sep_index = norm_str.find(sep, 2) + if sep_index == -1: + return path_str[:0], path_str + sep_index2 = norm_str.find(sep, sep_index + 1) + if sep_index2 == sep_index + 1: + return path_str[:0], path_str + if sep_index2 == -1: + sep_index2 = len(path_str) + return path_str[:sep_index2], path_str[sep_index2:] + if path_str[1:2] == matching_string(path_str, ":"): + return path_str[:2], path_str[2:] return path_str[:0], path_str def splitroot(self, path: AnyStr): @@ -1423,10 +1422,8 @@ def starts_with_drive_letter(self, file_path: AnyStr) -> bool: if len(file_path) == 2: # avoid recursion, check directly in the entries return any( - [ - entry.upper() == file_path.upper() - for entry in self.root_dir.entries - ] + entry.upper() == file_path.upper() + for entry in self.root_dir.entries ) self.get_object_from_normpath(file_path) return True @@ -1779,9 +1776,8 @@ def get_object_from_normpath( 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 S_ISLNK(target.st_mode) and 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) @@ -2070,10 +2066,9 @@ def _do_rename(self, old_dir_object, old_name, new_dir_object, new_name): def _handle_broken_link_with_trailing_sep(self, path: AnyStr) -> None: # note that the check for trailing sep has to be done earlier - if self.islink(path): - if not self.exists(path): - error = errno.ENOENT if self.is_macos else errno.ENOTDIR - self.raise_os_error(error, path) + if self.islink(path) and not self.exists(path): + error = errno.ENOENT if self.is_macos else errno.ENOTDIR + self.raise_os_error(error, path) def _handle_posix_dir_link_errors( self, new_file_path: AnyStr, old_file_path: AnyStr, ends_with_sep: bool @@ -2108,8 +2103,7 @@ def _rename_to_existing_path( new_object = self._get_object(new_file_path) if old_file_path == new_file_path: if not S_ISLNK(new_object.st_mode) and ends_with_sep: - error = errno.ENOTDIR if self.is_windows_fs else errno.ENOTDIR - self.raise_os_error(error, old_file_path) + self.raise_os_error(errno.ENOTDIR, old_file_path) return None # Nothing to do here if old_object == new_object: @@ -2145,13 +2139,12 @@ def _handle_rename_error_for_dir_or_link( else: self.raise_os_error(errno.EEXIST, new_file_path) if not S_ISLNK(new_object.st_mode): - if new_object.entries: - if ( - not S_ISLNK(old_object.st_mode) - or not ends_with_sep - or not self.is_macos - ): - self.raise_os_error(errno.ENOTEMPTY, new_file_path) + if new_object.entries and ( + not S_ISLNK(old_object.st_mode) + or not ends_with_sep + or not self.is_macos + ): + self.raise_os_error(errno.ENOTEMPTY, new_file_path) if S_ISREG(old_object.st_mode): self.raise_os_error(errno.EISDIR, new_file_path) @@ -2567,7 +2560,7 @@ def add_package_metadata(self, package_name: str) -> None: Raises: PackageNotFoundError: if the package with the given name is not found """ - from importlib.metadata import distribution, PackageNotFoundError + from importlib.metadata import PackageNotFoundError, distribution # we have to pause patching to get the distribution # from the real filesystem if we are in patch mode @@ -2898,7 +2891,7 @@ def makedir(self, dir_path: AnyPath, mode: int = helpers.PERM_DEF) -> None: base_dir = self.normpath(parent_dir) ellipsis = matching_string(parent_dir, self.path_separator + "..") if parent_dir.endswith(ellipsis) and not self.is_windows_fs: - base_dir, dummy_dotdot, _ = parent_dir.partition(ellipsis) + base_dir, _, _ = parent_dir.partition(ellipsis) if self.is_windows_fs and not rest and not self.exists(base_dir): # under Windows, the parent dir may be a drive or UNC path # which has to be mounted @@ -3291,6 +3284,7 @@ def _create_temp_dir(self): def _run_doctest() -> TestResults: import doctest + import pyfakefs return doctest.testmod(pyfakefs.fake_filesystem) diff --git a/pyfakefs/fake_filesystem_shutil.py b/pyfakefs/fake_filesystem_shutil.py old mode 100755 new mode 100644 index b688b386..42afe3fc --- a/pyfakefs/fake_filesystem_shutil.py +++ b/pyfakefs/fake_filesystem_shutil.py @@ -34,9 +34,9 @@ import os import shutil import sys -from threading import RLock from collections.abc import Callable -from typing import TYPE_CHECKING +from threading import RLock +from typing import TYPE_CHECKING, ClassVar if TYPE_CHECKING: from pyfakefs.fake_filesystem import FakeFilesystem @@ -58,7 +58,7 @@ class FakeShutilModule: has_fcopy_file = hasattr(shutil, "_HAS_FCOPYFILE") and shutil._HAS_FCOPYFILE # type: ignore[attr-defined] use_sendfile = hasattr(shutil, "_USE_CP_SENDFILE") and shutil._USE_CP_SENDFILE # type: ignore[attr-defined] use_fd_functions = shutil._use_fd_functions # type: ignore[attr-defined] - functions_to_patch = ["copy", "copyfile", "rmtree"] + functions_to_patch: ClassVar[list[str]] = ["copy", "copyfile", "rmtree"] if sys.version_info < (3, 12) or sys.platform != "win32": functions_to_patch.extend(["copy2", "copytree", "move"]) diff --git a/pyfakefs/fake_filesystem_unittest.py b/pyfakefs/fake_filesystem_unittest.py index 100e8b47..22ce33d4 100644 --- a/pyfakefs/fake_filesystem_unittest.py +++ b/pyfakefs/fake_filesystem_unittest.py @@ -51,30 +51,37 @@ import unittest import warnings import weakref +from collections.abc import Callable, ItemsView, Iterator, Sequence from importlib import reload from importlib.abc import Loader, MetaPathFinder from importlib.machinery import ModuleSpec -from importlib.util import spec_from_file_location, module_from_spec -from types import ModuleType, TracebackType, FunctionType +from importlib.util import module_from_spec, spec_from_file_location +from types import FunctionType, ModuleType, TracebackType from typing import ( Any, + ClassVar, Optional, cast, ) - -from collections.abc import Callable, Iterator, ItemsView, Sequence from unittest import TestSuite -from pyfakefs import fake_filesystem, fake_io, fake_os, fake_open, fake_path, fake_file -from pyfakefs import fake_filesystem_shutil -from pyfakefs import fake_pathlib -from pyfakefs import mox3_stubout +from pyfakefs import ( + fake_file, + fake_filesystem, + fake_filesystem_shutil, + fake_io, + fake_open, + fake_os, + fake_path, + fake_pathlib, + mox3_stubout, +) from pyfakefs.fake_filesystem import ( - set_uid, - set_gid, - reset_ids, - PatchMode, FakeFilesystem, + PatchMode, + reset_ids, + set_gid, + set_uid, ) from pyfakefs.fake_os import use_original_os from pyfakefs.helpers import IS_PYPY, IS_WIN @@ -529,7 +536,7 @@ class Patcher: we skip faking the module. We also have to set back the cached open function in tokenize. """ - SKIPMODULES = { + SKIPMODULES: ClassVar[set] = { None, fake_filesystem, fake_filesystem_shutil, @@ -554,9 +561,9 @@ class Patcher: SKIPMODULES.add(nt) SKIPMODULES.add(ntpath) else: + import fcntl import posix import posixpath - import fcntl SKIPMODULES.add(posix) SKIPMODULES.add(posixpath) @@ -564,11 +571,11 @@ class Patcher: # a list of modules detected at run-time # each tool defines one or more module name prefixes for modules to be skipped - RUNTIME_SKIPMODULES = { + RUNTIME_SKIPMODULES: ClassVar[dict] = { "pydevd": ["_pydevd_", "pydevd", "_pydev_"], # Python debugger (PyCharm/VSCode) "_jb_runner_tools": ["_jb_"], # JetBrains tools } - VSCODE_SKIPMODULES = {} + VSCODE_SKIPMODULES: ClassVar[dict] = {} if "VSCODE_CWD" in os.environ: # VSCode unit test runner # we add this only if actually running in VSCode, as it has to be checked @@ -578,21 +585,21 @@ class Patcher: # caches all modules that do not have file system modules or function # to speed up _find_modules - CACHED_MODULES: set[ModuleType] = set() - FS_MODULES: dict[str, set[tuple[ModuleType, str]]] = {} - FS_FUNCTIONS: dict[tuple[str, str, str], set[ModuleType]] = {} - FS_DEFARGS: list[tuple[FunctionType, int, Callable[..., Any]]] = [] - SKIPPED_FS_MODULES: dict[str, set[tuple[ModuleType, str]]] = {} + CACHED_MODULES: ClassVar[set[ModuleType]] = set() + FS_MODULES: ClassVar[dict[str, set[tuple[ModuleType, str]]]] = {} + FS_FUNCTIONS: ClassVar[dict[tuple[str, str, str], set[ModuleType]]] = {} + FS_DEFARGS: ClassVar[list[tuple[FunctionType, int, Callable[..., Any]]]] = [] + SKIPPED_FS_MODULES: ClassVar[dict[str, set[tuple[ModuleType, str]]]] = {} assert None in SKIPMODULES, "sys.modules contains 'None' values; must skip them." IS_WINDOWS = sys.platform in ("win32", "cygwin") - SKIPNAMES: set[str] = set() + SKIPNAMES: ClassVar[set[str]] = set() # hold values from last call - if changed, the cache has to be invalidated - PATCHED_MODULE_NAMES: set[str] = set() - ADDITIONAL_SKIP_NAMES: set[str] = set() + PATCHED_MODULE_NAMES: ClassVar[set[str]] = set() + ADDITIONAL_SKIP_NAMES: ClassVar[set[str]] = set() PATCH_DEFAULT_ARGS = False PATCHER: Optional["Patcher"] = None DOC_PATCHER: Optional["Patcher"] = None @@ -725,10 +732,10 @@ def __init__( if use_known_patches: from pyfakefs.patched_packages import ( - get_modules_to_patch, get_classes_to_patch, - get_fake_module_classes, get_cleanup_handlers, + get_fake_module_classes, + get_modules_to_patch, ) modules_to_patch = modules_to_patch or {} @@ -865,7 +872,7 @@ def _init_fake_module_functions(self) -> None: module_attr ) - def __enter__(self) -> "Patcher": + def __enter__(self) -> "Patcher": # noqa:PYI034 """Context manager for usage outside of fake_filesystem_unittest.TestCase. Ensure that all patched modules are removed in case of an @@ -892,7 +899,7 @@ def _is_fs_module( or inspect.isclass(mod) and mod.__module__ in self._class_modules.get(name, []) ) - except Exception: + except Exception: # noqa:BLE001 # handle cases where the module has no __name__ or __module__ # attribute - see #460, and any other exception triggered # by inspect functions @@ -905,7 +912,7 @@ def _is_fs_function(self, fct: FunctionType) -> bool: and fct.__name__ in self._fake_module_functions and fct.__module__ in self._fake_module_functions[fct.__name__] ) - except Exception: + except Exception: # noqa:BLE001 # handle cases where the function has no __name__ or __module__ # attribute, or any other exception in inspect functions return False @@ -921,7 +928,7 @@ def _def_values( for i, d in enumerate(item.__defaults__): if self._is_fs_function(d): yield item, i, d - except Exception: + except Exception: # noqa:BLE001,S110 pass try: if inspect.isclass(item): @@ -934,7 +941,7 @@ def _def_values( for i, d in enumerate(f.__defaults__): if self._is_fs_function(d): yield f, i, d - except Exception: + except Exception: # noqa:BLE001,S110 # Ignore any exception, examples: # ImportError: No module named '_gdbm' # _DontDoThat() (see #523) @@ -960,7 +967,7 @@ def _find_modules(self) -> None: or not inspect.ismodule(module) ): continue - except Exception: + except Exception: # noqa:BLE001 # workaround for some py (part of pytest) versions # where py.error has no __name__ attribute # see https://github.com/pytest-dev/py/issues/73 @@ -973,7 +980,7 @@ def _find_modules(self) -> None: pass continue skipped = module in self.SKIPMODULES or any( - [sn.startswith(module.__name__) for sn in self.skip_names] + sn.startswith(module.__name__) for sn in self.skip_names ) module_items = module.__dict__.copy().items() @@ -1120,7 +1127,7 @@ def patch_modules(self) -> None: self._stubs.smart_set(module, name, self.fake_modules[attr]) elif attr in self.unfaked_modules: self._stubs.smart_set(module, name, self.unfaked_modules[attr]) - except Exception: + except Exception: # noqa:BLE001,S110 # handle the rare case that a module has no __name__ pass @@ -1239,7 +1246,7 @@ def __init__(self, caller: Patcher | TestCaseMixin | FakeFilesystem): elif isinstance(caller, FakeFilesystem): self._fs = caller else: - raise ValueError( + raise TypeError( "Invalid argument - should be of type " '"fake_filesystem_unittest.Patcher", ' '"fake_filesystem_unittest.TestCase" ' @@ -1250,7 +1257,7 @@ def __enter__(self) -> FakeFilesystem: self._fs.pause() return self._fs - def __exit__(self, *args: Any) -> None: + def __exit__(self, *args: object) -> None: self._fs.resume() @@ -1299,9 +1306,9 @@ def needs_patch(self, name: str) -> bool: if name not in self.modules: self._loaded_module_names.add(name) return False - if name in sys.modules and type(sys.modules[name]) is self.modules[name]: - return False - return True + return ( + name not in sys.modules or type(sys.modules[name]) is not self.modules[name] + ) def fake_module_path(self, name: str) -> str: """Checks if the module with the given name is a module existing in the fake diff --git a/pyfakefs/fake_io.py b/pyfakefs/fake_io.py index 9e064156..8f3bd6fb 100644 --- a/pyfakefs/fake_io.py +++ b/pyfakefs/fake_io.py @@ -21,16 +21,15 @@ import _io # pytype: disable=import-error import io import sys +from collections.abc import Callable from enum import Enum from typing import ( - Any, - AnyStr, IO, TYPE_CHECKING, + Any, + AnyStr, ) -from collections.abc import Callable - from pyfakefs.fake_file import AnyFileWrapper from pyfakefs.fake_open import fake_open from pyfakefs.helpers import IS_PYPY, is_called_from_skipped_module diff --git a/pyfakefs/fake_open.py b/pyfakefs/fake_open.py index a5cf88e4..f7903b4d 100644 --- a/pyfakefs/fake_open.py +++ b/pyfakefs/fake_open.py @@ -25,29 +25,29 @@ S_ISDIR, ) from typing import ( + IO, + TYPE_CHECKING, Any, - cast, AnyStr, - TYPE_CHECKING, - IO, + cast, ) +from pyfakefs import helpers from pyfakefs.fake_file import ( + AnyFileWrapper, FakeBinaryFileWrapper, - FakeTextFileWrapper, - FakePipeWrapper, - FakeFileWrapper, FakeFile, - AnyFileWrapper, + FakeFileWrapper, + FakePipeWrapper, + FakeTextFileWrapper, ) -from pyfakefs import helpers from pyfakefs.helpers import ( - AnyString, - is_called_from_skipped_module, - is_root, PERM_READ, PERM_WRITE, + AnyString, _OpenModes, + is_called_from_skipped_module, + is_root, is_unfaked_path, ) @@ -340,9 +340,8 @@ def _init_file_object( ) ): self.filesystem.raise_os_error(errno.EACCES, file_path) - if open_modes.can_write: - if open_modes.truncate: - file_object.set_contents("") + if open_modes.can_write and open_modes.truncate: + file_object.set_contents("") else: if open_modes.must_exist: self.filesystem.raise_os_error(errno.ENOENT, file_path) @@ -425,7 +424,7 @@ def _handle_file_mode( mode = mode.replace("rU", "r").replace("U", "r") if not self.raw_io: if mode not in _OPEN_MODE_MAP: - raise ValueError("Invalid mode: %r" % orig_modes) + raise ValueError(f"Invalid mode: {orig_modes}") open_modes = _OpenModes(*_OPEN_MODE_MAP[mode]) assert open_modes is not None return newline, open_modes diff --git a/pyfakefs/fake_os.py b/pyfakefs/fake_os.py index 56c1e8ea..3c3edc03 100644 --- a/pyfakefs/fake_os.py +++ b/pyfakefs/fake_os.py @@ -24,48 +24,47 @@ import os import sys import uuid +from collections.abc import Callable from contextlib import contextmanager from stat import ( S_IFREG, S_IFSOCK, ) from typing import ( + TYPE_CHECKING, Any, - cast, AnyStr, - TYPE_CHECKING, + cast, ) -from collections.abc import Callable - from pyfakefs.fake_file import ( + AnyFileWrapper, FakeDirectory, FakeDirWrapper, - StandardStreamWrapper, + FakeFile, FakeFileWrapper, FakePipeWrapper, - FakeFile, - AnyFileWrapper, + StandardStreamWrapper, ) from pyfakefs.fake_open import FakeFileOpen, _OpenModes from pyfakefs.fake_path import FakePathModule -from pyfakefs.fake_scandir import scandir, walk, ScanDirIter +from pyfakefs.fake_scandir import ScanDirIter, scandir, walk from pyfakefs.helpers import ( + IS_PYPY, + PERM_DEF, + PERM_EXE, + AnyString, FakeStatResult, + get_gid, + get_uid, + is_byte_string, is_called_from_skipped_module, is_int_type, - is_byte_string, + is_root, make_string_path, - IS_PYPY, - to_string, matching_string, - AnyString, to_bytes, - PERM_EXE, - PERM_DEF, - is_root, - get_uid, - get_gid, + to_string, ) if TYPE_CHECKING: @@ -975,14 +974,14 @@ def _path_with_dir_fd( path = make_string_path(path) except TypeError: # the error is handled later - path = path + pass if dir_fd is not None: # check if fd is supported for the built-in real function if check_supported and (fct not in self.supports_dir_fd): raise NotImplementedError("dir_fd unavailable on this platform") if isinstance(path, int): raise ValueError( - "%s: Can't specify dir_fd without matching path_str" % fct.__name__ + f"{fct.__name__}: Can't specify dir_fd without matching path_str" ) if not self.path.isabs(path): open_file = self.filesystem.get_open_file(dir_fd) @@ -1325,9 +1324,10 @@ def fsync(self, fd: int) -> None: if 0 <= fd < NR_STD_STREAMS: self.filesystem.raise_os_error(errno.EINVAL) file_object = cast(FakeFileWrapper, self.filesystem.get_open_file(fd)) - if self.filesystem.is_windows_fs: - if not hasattr(file_object, "allow_update") or not file_object.allow_update: - self.filesystem.raise_os_error(errno.EBADF, file_object.file_path) + if self.filesystem.is_windows_fs and ( + not hasattr(file_object, "allow_update") or not file_object.allow_update + ): + self.filesystem.raise_os_error(errno.EBADF, file_object.file_path) def fdatasync(self, fd: int) -> None: """Perform fdatasync for a fake file (in other words, do nothing). @@ -1372,9 +1372,11 @@ def sendfile(self, fd_out: int, fd_in: int, offset: int, count: int) -> int: self.filesystem.raise_os_error(errno.EINVAL) source = cast(FakeFileWrapper, self.filesystem.get_open_file(fd_in)) dest = cast(FakeFileWrapper, self.filesystem.get_open_file(fd_out)) - if self.filesystem.is_macos: - if dest.get_object().stat_result.st_mode & 0o777000 != S_IFSOCK: - raise OSError("Socket operation on non-socket") + if ( + self.filesystem.is_macos + and dest.get_object().stat_result.st_mode & 0o777000 != S_IFSOCK + ): + raise OSError("Socket operation on non-socket") if offset is None: if self.filesystem.is_macos: raise TypeError("None is not a valid offset") diff --git a/pyfakefs/fake_path.py b/pyfakefs/fake_path.py index b4434e05..504f1c55 100644 --- a/pyfakefs/fake_path.py +++ b/pyfakefs/fake_path.py @@ -21,27 +21,26 @@ import inspect import os import sys +from collections.abc import Callable from stat import ( S_IFDIR, S_IFMT, ) from types import ModuleType from typing import ( + TYPE_CHECKING, Any, AnyStr, - overload, ClassVar, - TYPE_CHECKING, + overload, ) -from collections.abc import Callable - from pyfakefs.helpers import ( is_called_from_skipped_module, make_string_path, - to_string, matching_string, to_bytes, + to_string, ) if TYPE_CHECKING: diff --git a/pyfakefs/fake_pathlib.py b/pyfakefs/fake_pathlib.py index 50b20f55..050c0930 100644 --- a/pyfakefs/fake_pathlib.py +++ b/pyfakefs/fake_pathlib.py @@ -35,10 +35,9 @@ import re import sys import warnings -from pathlib import PurePath - from collections.abc import Callable -from typing import Any, Union +from pathlib import PurePath +from typing import Any, ClassVar, Union from unittest import mock from urllib.parse import quote_from_bytes as urlquote_from_bytes @@ -47,13 +46,12 @@ from pyfakefs.fake_open import fake_open from pyfakefs.fake_os import FakeOsModule, use_original_os from pyfakefs.fake_path import FakePathModule -from pyfakefs.helpers import IS_PYPY, is_called_from_skipped_module, FSType - +from pyfakefs.helpers import IS_PYPY, FSType, is_called_from_skipped_module _WIN_RESERVED_NAMES = ( {"CON", "PRN", "AUX", "NUL"} - | {"COM%d" % i for i in range(1, 10)} - | {"LPT%d" % i for i in range(1, 10)} + | {f"COM{i}" for i in range(1, 10)} + | {f"LPT{i}" for i in range(1, 10)} ) @@ -99,12 +97,11 @@ def _wrap_strfunc(fake_fct, original_fct): @functools.wraps(fake_fct) def _wrapped(pathobj, *args, **kwargs): fs: FakeFilesystem = pathobj.filesystem - if fs.has_patcher: - if is_called_from_skipped_module( - skip_names=fs.patcher.skip_names, - case_sensitive=fs.is_case_sensitive, - ): - return original_fct(str(pathobj), *args, **kwargs) + if fs.has_patcher and is_called_from_skipped_module( + skip_names=fs.patcher.skip_names, + case_sensitive=fs.is_case_sensitive, + ): + return original_fct(str(pathobj), *args, **kwargs) return fake_fct(fs, str(pathobj), *args, **kwargs) return staticmethod(_wrapped) @@ -114,12 +111,11 @@ def _wrap_binary_strfunc(fake_fct, original_fct): @functools.wraps(fake_fct) def _wrapped(pathobj1, pathobj2, *args): fs: FakeFilesystem = pathobj1.filesystem - if fs.has_patcher: - if is_called_from_skipped_module( - skip_names=fs.patcher.skip_names, - case_sensitive=fs.is_case_sensitive, - ): - return original_fct(str(pathobj1), str(pathobj2), *args) + if fs.has_patcher and is_called_from_skipped_module( + skip_names=fs.patcher.skip_names, + case_sensitive=fs.is_case_sensitive, + ): + return original_fct(str(pathobj1), str(pathobj2), *args) return fake_fct(fs, str(pathobj1), str(pathobj2), *args) return staticmethod(_wrapped) @@ -129,12 +125,11 @@ def _wrap_binary_strfunc_reverse(fake_fct, original_fct): @functools.wraps(fake_fct) def _wrapped(pathobj1, pathobj2, *args): fs: FakeFilesystem = pathobj2.filesystem - if fs.has_patcher: - if is_called_from_skipped_module( - skip_names=fs.patcher.skip_names, - case_sensitive=fs.is_case_sensitive, - ): - return original_fct(str(pathobj2), str(pathobj1), *args) + if fs.has_patcher and is_called_from_skipped_module( + skip_names=fs.patcher.skip_names, + case_sensitive=fs.is_case_sensitive, + ): + return original_fct(str(pathobj2), str(pathobj1), *args) return fake_fct(fs, str(pathobj2), str(pathobj1), *args) return staticmethod(_wrapped) @@ -174,19 +169,17 @@ def lchmod(self, pathobj, *args, **kwargs): raise NotImplementedError("lchmod() not available on this system") def chmod(self, pathobj, *args, **kwargs): - if "follow_symlinks" in kwargs: - if sys.version_info < (3, 10): - raise TypeError( - "chmod() got an unexpected keyword argument 'follow_symlinks'" - ) - - if not kwargs["follow_symlinks"] and ( + if ( + "follow_symlinks" in kwargs + and not kwargs["follow_symlinks"] + and ( os.chmod not in os.supports_follow_symlinks or (IS_PYPY and not pathobj.filesystem.is_macos) - ): - raise NotImplementedError( - "`follow_symlinks` for chmod() is not available on this system" - ) + ) + ): + raise NotImplementedError( + "`follow_symlinks` for chmod() is not available on this system" + ) return pathobj.filesystem.chmod(str(pathobj), *args, **kwargs) mkdir = _wrap_strfunc(FakeFilesystem.makedir, os.mkdir) @@ -362,7 +355,7 @@ def _resolve(path, rest): continue # The symlink is not resolved, so we must have # a symlink loop. - raise RuntimeError("Symlink loop from %r" % newpath) + raise RuntimeError(f"Symlink loop from {newpath}") # Resolve the symbolic link try: target = self.filesystem.readlink(newpath) @@ -428,9 +421,7 @@ def gethomedir(self, username): try: return pwd.getpwnam(username).pw_dir except KeyError: - raise RuntimeError( - "Can't determine home directory for %r" % username - ) + raise RuntimeError(f"Can't determine home directory for {username}") class _FakeWindowsFlavour(_FakeFlavour): """Flavour used by PureWindowsPath with some Windows specific @@ -490,22 +481,19 @@ def gethomedir(self, username): else: raise RuntimeError("Can't determine home directory") - if username: - # Try to guess user home directory. By default all users - # directories are located in the same place and are named by - # corresponding usernames. If current user home directory points - # to nonstandard place, this guess is likely wrong. - if os.environ["USERNAME"] != username: - drv, root, parts = self.parse_parts((userhome,)) - if parts[-1] != os.environ["USERNAME"]: - raise RuntimeError( - "Can't determine home directory for %r" % username - ) - parts[-1] = username - if drv or root: - userhome = drv + root + self.join(parts[1:]) - else: - userhome = self.join(parts) + # Try to guess user home directory. By default all users + # directories are located in the same place and are named by + # corresponding usernames. If current user home directory points + # to nonstandard place, this guess is likely wrong. + if username and (os.environ["USERNAME"] != username): + drv, root, parts = self.parse_parts((userhome,)) + if parts[-1] != os.environ["USERNAME"]: + raise RuntimeError(f"Can't determine home directory for {username}") + parts[-1] = username + if drv or root: + userhome = drv + root + self.join(parts[1:]) + else: + userhome = self.join(parts) return userhome def compile_pattern(self, pattern): @@ -545,9 +533,7 @@ def gethomedir(self, username): try: return pwd.getpwnam(username).pw_dir except KeyError: - raise RuntimeError( - "Can't determine home directory for %r" % username - ) + raise RuntimeError(f"Can't determine home directory for {username}") def compile_pattern(self, pattern): return re.compile(fnmatch.translate(pattern)).fullmatch @@ -593,20 +579,21 @@ class FakePath(pathlib.Path): # the underlying fake filesystem filesystem = None - skip_names: list[str] = [] + skip_names: ClassVar[list[str]] = [] def __new__(cls, *args, **kwargs): """Creates the correct subclass based on OS.""" if cls is FakePathlibModule.Path: - cls = ( + klass = ( FakePathlibModule.WindowsPath if cls.filesystem.is_windows_fs else FakePathlibModule.PosixPath ) - if sys.version_info < (3, 12): - return cls._from_parts(args) # pytype: disable=attribute-error else: - return object.__new__(cls) + klass = cls + if sys.version_info < (3, 12): + return klass._from_parts(args) # pytype: disable=attribute-error + return object.__new__(klass) if sys.version_info[:2] == (3, 10): # Overwritten class methods to call _init to set the fake accessor, @@ -756,7 +743,7 @@ def write_text(self, data, encoding=None, errors=None, newline=None): invalid or permission is denied. """ if not isinstance(data, str): - raise TypeError("data must be str, not %s" % data.__class__.__name__) + raise TypeError(f"data must be str, not {data.__class__.__name__}") with fake_open( self.filesystem, self.skip_names, @@ -1091,7 +1078,7 @@ def __init__(self, filesystem=None, from_patcher=False): def __or__(self, other: Any) -> Any: # workaround for #1242 - pytest chokes on Path | ... type hint in wrapped function - return Union[self, other] + return Union[self, other] # noqa: UP007 __ror__ = __or__ @@ -1136,33 +1123,34 @@ class RealPath(pathlib.Path): def __new__(cls, *args, **kwargs): """Creates the correct subclass based on OS.""" if cls is RealPathlibModule.Path: - cls = ( + klass = ( RealPathlibModule.WindowsPath # pytype: disable=attribute-error if os.name == "nt" else RealPathlibModule.PosixPath # pytype: disable=attribute-error ) + else: + klass = cls if sys.version_info < (3, 12): - return cls._from_parts(args) # pytype: disable=attribute-error + return klass._from_parts(args) # pytype: disable=attribute-error else: - return object.__new__(cls) + return object.__new__(klass) -if sys.version_info > (3, 10): +def with_original_os(f: Callable) -> Callable: + """Decorator used for real pathlib Path methods to ensure that + real os functions instead of faked ones are used.""" - def with_original_os(f: Callable) -> Callable: - """Decorator used for real pathlib Path methods to ensure that - real os functions instead of faked ones are used.""" + @functools.wraps(f) + def wrapped(*args, **kwargs): + with use_original_os(): + return f(*args, **kwargs) - @functools.wraps(f) - def wrapped(*args, **kwargs): - with use_original_os(): - return f(*args, **kwargs) + return wrapped - return wrapped - for fct_name, fn in inspect.getmembers(RealPath, inspect.isfunction): - if not fct_name.startswith("__"): - setattr(RealPath, fct_name, with_original_os(fn)) +for fct_name, fn in inspect.getmembers(RealPath, inspect.isfunction): + if not fct_name.startswith("__"): + setattr(RealPath, fct_name, with_original_os(fn)) class RealPathlibPathModule: diff --git a/pyfakefs/fake_scandir.py b/pyfakefs/fake_scandir.py index 75ffa9c8..1ef82f9b 100644 --- a/pyfakefs/fake_scandir.py +++ b/pyfakefs/fake_scandir.py @@ -21,7 +21,7 @@ import weakref from typing import TYPE_CHECKING -from pyfakefs.helpers import to_string, make_string_path, IS_PYPY +from pyfakefs.helpers import IS_PYPY, make_string_path, to_string if TYPE_CHECKING: from pyfakefs.fake_filesystem import FakeFilesystem @@ -145,7 +145,7 @@ def __init__(self, filesystem, path): .path # pytype:disable=attribute-error ) self.path = "" - self.entry_iter = iter(tuple()) + self.entry_iter = iter(()) else: if path is None: path = "." diff --git a/pyfakefs/helpers.py b/pyfakefs/helpers.py index 85bc7967..b000261f 100644 --- a/pyfakefs/helpers.py +++ b/pyfakefs/helpers.py @@ -29,10 +29,10 @@ from dataclasses import dataclass from enum import Enum from stat import S_IFLNK -from typing import Union, Any, AnyStr, overload, cast +from typing import Any, AnyStr, Union, cast, overload -AnyString = Union[str, bytes] -AnyPath = Union[AnyStr, os.PathLike] +AnyString = str | bytes +AnyPath = Union[AnyStr, os.PathLike] # noqa: UP007 IS_PYPY = platform.python_implementation() == "PyPy" IS_WIN = sys.platform == "win32" @@ -286,7 +286,7 @@ def __init__( self._st_mtime_ns: int = self._st_atime_ns self._st_ctime_ns: int = self._st_atime_ns - def __eq__(self, other: Any) -> bool: + def __eq__(self, other: object) -> bool: return ( isinstance(other, FakeStatResult) and self._st_atime_ns == other._st_atime_ns @@ -301,7 +301,7 @@ def __eq__(self, other: Any) -> bool: and self.st_mode == other.st_mode ) - def __ne__(self, other: Any) -> bool: + def __ne__(self, other: object) -> bool: return not self == other def copy(self) -> "FakeStatResult": @@ -330,7 +330,7 @@ def st_ctime(self) -> int | float: return self._st_ctime_ns / 1e9 @st_ctime.setter - def st_ctime(self, val: int | float) -> None: + def st_ctime(self, val: float) -> None: """Set the creation time in seconds.""" self._st_ctime_ns = int(val * 1e9) @@ -340,7 +340,7 @@ def st_atime(self) -> int | float: return self._st_atime_ns / 1e9 @st_atime.setter - def st_atime(self, val: int | float) -> None: + def st_atime(self, val: float) -> None: """Set the access time in seconds.""" self._st_atime_ns = int(val * 1e9) @@ -350,7 +350,7 @@ def st_mtime(self) -> int | float: return self._st_mtime_ns / 1e9 @st_mtime.setter - def st_mtime(self, val: int | float) -> None: + def st_mtime(self, val: float) -> None: """Set the modification time in seconds.""" self._st_mtime_ns = int(val * 1e9) @@ -552,10 +552,8 @@ def starts_with(path, string): caller_module_name = caller_module_name.replace(os.sep, ".") if any( - [ - caller_module_name == sn or caller_module_name.endswith("." + sn) - for sn in skip_names - ] + caller_module_name == sn or caller_module_name.endswith("." + sn) + for sn in skip_names ): return True return False diff --git a/pyfakefs/patched_packages.py b/pyfakefs/patched_packages.py index 4f6d8b70..3fde22d1 100644 --- a/pyfakefs/patched_packages.py +++ b/pyfakefs/patched_packages.py @@ -22,7 +22,7 @@ import pandas as pd try: - import pandas.io.parsers as parsers + from pandas.io import parsers except ImportError: parsers = None except ImportError: @@ -231,5 +231,5 @@ def django_view_modules(): django.conf.settings.ROOT_URLCONF ).urls.urlpatterns return get_all_view_modules(all_urlpatterns) - except Exception: + except ImportError: return set() diff --git a/pyfakefs/pytest_tests/conftest.py b/pyfakefs/pytest_tests/conftest.py index d23dad2f..8327488d 100644 --- a/pyfakefs/pytest_tests/conftest.py +++ b/pyfakefs/pytest_tests/conftest.py @@ -21,8 +21,7 @@ # import the fs fixture to be visible if pyfakefs is not installed from pyfakefs.pytest_plugin import fs, fs_module # noqa: F401 - -from pyfakefs.pytest_tests import example # noqa: E402 +from pyfakefs.pytest_tests import example @pytest.fixture diff --git a/pyfakefs/pytest_tests/hook_test/conftest.py b/pyfakefs/pytest_tests/hook_test/conftest.py index 615d1d2b..b27f3a6e 100644 --- a/pyfakefs/pytest_tests/hook_test/conftest.py +++ b/pyfakefs/pytest_tests/hook_test/conftest.py @@ -13,7 +13,6 @@ import pytest - # Used for testing paused patching during reporting. diff --git a/pyfakefs/pytest_tests/pytest_fixture_param_test.py b/pyfakefs/pytest_tests/pytest_fixture_param_test.py index 5a72782e..d1351500 100644 --- a/pyfakefs/pytest_tests/pytest_fixture_param_test.py +++ b/pyfakefs/pytest_tests/pytest_fixture_param_test.py @@ -15,7 +15,7 @@ import pytest -import pyfakefs.pytest_tests.example as example +from pyfakefs.pytest_tests import example @pytest.mark.xfail diff --git a/pyfakefs/pytest_tests/pytest_fixture_test.py b/pyfakefs/pytest_tests/pytest_fixture_test.py index db5436ca..3e5d16fb 100644 --- a/pyfakefs/pytest_tests/pytest_fixture_test.py +++ b/pyfakefs/pytest_tests/pytest_fixture_test.py @@ -12,12 +12,10 @@ import pathlib # Example for a test using a custom pytest fixture with an argument to Patcher - import pytest -import pyfakefs.pytest_tests.example as example from pyfakefs.fake_filesystem_unittest import Patcher -from pyfakefs.pytest_tests import unhashable +from pyfakefs.pytest_tests import example, unhashable @pytest.mark.xfail diff --git a/pyfakefs/pytest_tests/pytest_plugin_failing_helper.py b/pyfakefs/pytest_tests/pytest_plugin_failing_helper.py index cec614c0..651c232d 100644 --- a/pyfakefs/pytest_tests/pytest_plugin_failing_helper.py +++ b/pyfakefs/pytest_tests/pytest_plugin_failing_helper.py @@ -3,4 +3,4 @@ def test_fs(fs): - assert 1 == 2 + assert 1 == 2 # noqa:PLR0133 diff --git a/pyfakefs/pytest_tests/pytest_plugin_test.py b/pyfakefs/pytest_tests/pytest_plugin_test.py index 1bdd4f57..857e81c0 100644 --- a/pyfakefs/pytest_tests/pytest_plugin_test.py +++ b/pyfakefs/pytest_tests/pytest_plugin_test.py @@ -3,9 +3,9 @@ import os import tempfile +import pyfakefs.pytest_tests.io from pyfakefs.fake_filesystem import OSType from pyfakefs.fake_filesystem_unittest import Pause -import pyfakefs.pytest_tests.io def test_fs_fixture(fs): @@ -27,32 +27,36 @@ def test_both_fixtures(fs, fake_filesystem): def test_pause_resume(fs): - fake_temp_file = tempfile.NamedTemporaryFile() - assert fs.exists(fake_temp_file.name) - assert os.path.exists(fake_temp_file.name) - fs.pause() - assert fs.exists(fake_temp_file.name) - assert not os.path.exists(fake_temp_file.name) - real_temp_file = tempfile.NamedTemporaryFile() - assert not fs.exists(real_temp_file.name) - assert os.path.exists(real_temp_file.name) - fs.resume() - assert not os.path.exists(real_temp_file.name) - assert os.path.exists(fake_temp_file.name) + with tempfile.NamedTemporaryFile() as fake_temp_file: + assert fs.exists(fake_temp_file.name) + assert os.path.exists(fake_temp_file.name) + fs.pause() + assert fs.exists(fake_temp_file.name) + assert not os.path.exists(fake_temp_file.name) + with tempfile.NamedTemporaryFile() as real_temp_file: + assert not fs.exists(real_temp_file.name) + assert os.path.exists(real_temp_file.name) + fs.resume() + assert not os.path.exists(real_temp_file.name) + assert os.path.exists(fake_temp_file.name) + fs.pause() + fs.resume() def test_pause_resume_contextmanager(fs): - fake_temp_file = tempfile.NamedTemporaryFile() - assert fs.exists(fake_temp_file.name) - assert os.path.exists(fake_temp_file.name) - with Pause(fs): + with tempfile.NamedTemporaryFile() as fake_temp_file: assert fs.exists(fake_temp_file.name) - assert not os.path.exists(fake_temp_file.name) - real_temp_file = tempfile.NamedTemporaryFile() - assert not fs.exists(real_temp_file.name) - assert os.path.exists(real_temp_file.name) - assert not os.path.exists(real_temp_file.name) - assert os.path.exists(fake_temp_file.name) + assert os.path.exists(fake_temp_file.name) + with Pause(fs): + assert fs.exists(fake_temp_file.name) + assert not os.path.exists(fake_temp_file.name) + real_temp_file = tempfile.NamedTemporaryFile() # noqa:SIM115 + assert not fs.exists(real_temp_file.name) + assert os.path.exists(real_temp_file.name) + assert not os.path.exists(real_temp_file.name) + assert os.path.exists(fake_temp_file.name) + with Pause(fs): + real_temp_file.close() def test_use_own_io_module(fs): diff --git a/pyfakefs/tests/all_tests.py b/pyfakefs/tests/all_tests.py index 00782e40..ff8967b2 100644 --- a/pyfakefs/tests/all_tests.py +++ b/pyfakefs/tests/all_tests.py @@ -19,7 +19,6 @@ from pyfakefs.tests import ( dynamic_patch_test, - fake_stat_time_test, example_test, fake_filesystem_glob_test, fake_filesystem_shutil_test, @@ -29,9 +28,10 @@ fake_open_test, fake_os_test, fake_pathlib_test, + fake_stat_time_test, fake_tempfile_test, - patched_packages_test, mox3_stubout_test, + patched_packages_test, ) diff --git a/pyfakefs/tests/example_test.py b/pyfakefs/tests/example_test.py index 1b7cc718..bdad7be2 100644 --- a/pyfakefs/tests/example_test.py +++ b/pyfakefs/tests/example_test.py @@ -34,7 +34,6 @@ from pyfakefs import fake_filesystem_unittest from pyfakefs.tests import example # The module under test - # Work around pyupgrade auto-rewriting `io.open()` to `open()`. io_open = io.open diff --git a/pyfakefs/tests/fake_filesystem_glob_test.py b/pyfakefs/tests/fake_filesystem_glob_test.py index 9edee3dc..3747e8af 100644 --- a/pyfakefs/tests/fake_filesystem_glob_test.py +++ b/pyfakefs/tests/fake_filesystem_glob_test.py @@ -28,9 +28,9 @@ def setUp(self): self.setUpPyfakefs() directory = "./xyzzy" self.fs.create_dir(directory) - self.fs.create_dir("%s/subdir" % directory) - self.fs.create_dir("%s/subdir2" % directory) - self.fs.create_file("%s/subfile" % directory) + self.fs.create_dir(f"{directory}/subdir") + self.fs.create_dir(f"{directory}/subdir2") + self.fs.create_file(f"{directory}/subfile") self.fs.create_file("[Temp]") def test_glob_empty(self): diff --git a/pyfakefs/tests/fake_filesystem_shutil_test.py b/pyfakefs/tests/fake_filesystem_shutil_test.py index 6f3b4235..25ee0ad2 100644 --- a/pyfakefs/tests/fake_filesystem_shutil_test.py +++ b/pyfakefs/tests/fake_filesystem_shutil_test.py @@ -27,7 +27,7 @@ from pathlib import Path from pyfakefs import fake_filesystem_unittest -from pyfakefs.helpers import get_uid, set_uid, is_root, IS_PYPY, IS_WIN +from pyfakefs.helpers import IS_PYPY, IS_WIN, get_uid, is_root, set_uid from pyfakefs.tests.test_utils import RealFsTestMixin, skip_if_symlink_not_supported is_windows = sys.platform == "win32" @@ -150,9 +150,8 @@ def test_rmtree_with_open_file_fails_under_windows(self): self.create_file(os.path.join(dir_path, "bar")) file_path = os.path.join(dir_path, "baz") self.create_file(file_path) - with open(file_path, encoding="utf8"): - with self.assertRaises(OSError): - shutil.rmtree(dir_path) + with open(file_path, encoding="utf8"), self.assertRaises(OSError): + shutil.rmtree(dir_path) self.assertTrue(os.path.exists(dir_path)) def test_rmtree_non_existing_dir(self): @@ -327,7 +326,7 @@ def test_copytree(self): src_directory = self.make_path("xyzzy") dst_directory = self.make_path("xyzzy_copy") self.create_dir(src_directory) - self.create_dir("%s/subdir" % src_directory) + self.create_dir(f"{src_directory}/subdir") self.create_file(os.path.join(src_directory, "subfile")) self.assertTrue(os.path.exists(src_directory)) self.assertFalse(os.path.exists(dst_directory)) diff --git a/pyfakefs/tests/fake_filesystem_test.py b/pyfakefs/tests/fake_filesystem_test.py index 97bcf5e1..5e1f510e 100644 --- a/pyfakefs/tests/fake_filesystem_test.py +++ b/pyfakefs/tests/fake_filesystem_test.py @@ -30,20 +30,20 @@ except ImportError: pytest = None -from pyfakefs import fake_filesystem, fake_os, fake_open +from pyfakefs import fake_filesystem, fake_open, fake_os from pyfakefs.fake_filesystem import ( - set_uid, - set_gid, + OSType, is_root, reset_ids, - OSType, + set_gid, + set_uid, ) -from pyfakefs.helpers import IS_WIN, IS_PYPY +from pyfakefs.helpers import IS_PYPY, IS_WIN from pyfakefs.tests.test_utils import ( - TestCase, RealFsTestCase, - time_mock, + TestCase, skip_if_symlink_not_supported, + time_mock, ) @@ -472,7 +472,7 @@ def test_remove_object_from_non_directory_error(self): with self.raises_os_error(errno.ENOTDIR): self.filesystem.remove_object( self.filesystem.joinpaths( - "%s" % self.fake_file.name, + self.fake_file.name, "file_does_not_matter_since_parent_not_a_directory", ) ) @@ -524,7 +524,7 @@ def test_create_directory(self): self.assertTrue(stat.S_IFDIR & new_dir.st_mode) # Create second directory to make sure first is OK. - path = "%s/quux" % path + path = f"{path}/quux" self.filesystem.create_dir(path) new_dir = self.filesystem.get_object(path) self.assertEqual(os.path.basename(path), new_dir.name) @@ -577,7 +577,7 @@ def test_create_file_in_current_directory(self): self.filesystem.create_file(path, contents=contents) self.assertTrue(self.filesystem.exists(path)) self.assertFalse(self.filesystem.exists(os.path.dirname(path))) - path = "./%s" % path + path = f"./{path}" self.assertTrue(self.filesystem.exists(os.path.dirname(path))) def test_create_file_in_root_directory(self): @@ -889,11 +889,11 @@ def test_create_top_level_directory(self): self.filesystem.create_dir(top_level_dir) self.assertTrue(self.filesystem.exists("/")) self.assertTrue(self.filesystem.exists(top_level_dir)) - self.filesystem.create_dir("%s/po" % top_level_dir) - self.filesystem.create_file("%s/po/control" % top_level_dir) - self.filesystem.create_file("%s/po/experiment" % top_level_dir) - self.filesystem.create_dir("%s/gv" % top_level_dir) - self.filesystem.create_file("%s/gv/control" % top_level_dir) + self.filesystem.create_dir(f"{top_level_dir}/po") + self.filesystem.create_file(f"{top_level_dir}/po/control") + self.filesystem.create_file(f"{top_level_dir}/po/experiment") + self.filesystem.create_dir(f"{top_level_dir}/gv") + self.filesystem.create_file(f"{top_level_dir}/gv/control") expected = [ ("/", ["x"], []), @@ -924,7 +924,7 @@ def check_abspath(self, is_windows): self.filesystem.create_file(abspath) self.assertEqual(abspath, self.path.abspath(abspath)) self.assertEqual(abspath, self.path.abspath(filename)) - self.assertEqual(abspath, self.path.abspath("..!%s" % filename)) + self.assertEqual(abspath, self.path.abspath(f"..!{filename}")) def test_abspath_windows(self): self.check_abspath(is_windows=True) @@ -1003,7 +1003,7 @@ def test_relpath(self): self.assertEqual("path!to!foo", self.path.relpath(path_foo)) self.assertEqual("..!foo", self.path.relpath(path_foo, path_bar)) self.assertEqual( - "..!..!..%s" % path_other, self.path.relpath(path_other, path_bar) + f"..!..!..{path_other}", self.path.relpath(path_other, path_bar) ) self.assertEqual(".", self.path.relpath(path_bar, path_bar)) @@ -1142,7 +1142,7 @@ def test_dirname_with_drive(self): def test_dirname(self): dirname = "foo!bar" - self.assertEqual(dirname, self.path.dirname("%s!baz" % dirname)) + self.assertEqual(dirname, self.path.dirname(f"{dirname}!baz")) def test_join_strings(self): components = ["foo", "bar", "baz"] @@ -1244,14 +1244,14 @@ def test_getsize_dir_empty(self): dir_path = "foo!bar" self.filesystem.create_dir(dir_path) size = self.path.getsize(dir_path) - self.assertFalse(int(size) < 0, "expected non-negative size; actual: %s" % size) + self.assertFalse(int(size) < 0, f"expected non-negative size; actual: {size}") def test_getsize_dir_non_zero_size(self): # For directories, only require that the size is non-negative. dir_path = "foo!bar" self.filesystem.create_file(self.filesystem.joinpaths(dir_path, "baz")) size = self.path.getsize(dir_path) - self.assertFalse(int(size) < 0, "expected non-negative size; actual: %s" % size) + self.assertFalse(int(size) < 0, f"expected non-negative size; actual: {size}") def test_isdir(self): self.filesystem.create_file("foo!bar") @@ -2031,11 +2031,13 @@ def test_disk_full_after_reopened(self): f.write("a" * 60) with self.open("bar.txt", encoding="utf8") as f: self.assertEqual("a" * 60, f.read()) - with self.raises_os_error(errno.ENOSPC): - with self.open("bar.txt", "w", encoding="utf8") as f: - f.write("b" * 110) - with self.raises_os_error(errno.ENOSPC): - f.flush() + with ( + self.raises_os_error(errno.ENOSPC), + self.open("bar.txt", "w", encoding="utf8") as f, + ): + f.write("b" * 110) + with self.raises_os_error(errno.ENOSPC): + f.flush() with self.open("bar.txt", encoding="utf8") as f: self.assertEqual("", f.read()) @@ -2045,11 +2047,13 @@ def test_disk_full_append(self): f.write("a" * 60) with self.open(file_path, encoding="utf8") as f: self.assertEqual("a" * 60, f.read()) - with self.raises_os_error(errno.ENOSPC): - with self.open(file_path, "a", encoding="utf8") as f: - f.write("b" * 41) - with self.raises_os_error(errno.ENOSPC): - f.flush() + with ( + self.raises_os_error(errno.ENOSPC), + self.open(file_path, "a", encoding="utf8") as f, + ): + f.write("b" * 41) + with self.raises_os_error(errno.ENOSPC): + f.flush() with self.open("bar.txt", encoding="utf8") as f: self.assertEqual(f.read(), "a" * 60) @@ -2058,12 +2062,14 @@ def test_disk_full_after_reopened_rplus_seek(self): f.write("a" * 60) with self.open("bar.txt", encoding="utf8") as f: self.assertEqual(f.read(), "a" * 60) - with self.raises_os_error(errno.ENOSPC): - with self.open("bar.txt", "r+", encoding="utf8") as f: - f.seek(50) - f.write("b" * 60) - with self.raises_os_error(errno.ENOSPC): - f.flush() + with ( + self.raises_os_error(errno.ENOSPC), + self.open("bar.txt", "r+", encoding="utf8") as f, + ): + f.seek(50) + f.write("b" * 60) + with self.raises_os_error(errno.ENOSPC): + f.flush() with self.open("bar.txt", encoding="utf8") as f: self.assertEqual(f.read(), "a" * 60) @@ -2243,23 +2249,20 @@ def test_existing_fake_directory_is_merged(self): def test_fake_files_cannot_be_overwritten(self): self.filesystem.create_file(os.path.join("/", "root", "foo", "test.txt")) - with self.create_real_paths() as root_dir: - with self.raises_os_error(errno.EEXIST): - self.filesystem.add_real_directory(root_dir, target_path="/root") + with self.create_real_paths() as root_dir, self.raises_os_error(errno.EEXIST): + self.filesystem.add_real_directory(root_dir, target_path="/root") def test_cannot_overwrite_file_with_dir(self): self.filesystem.create_file(os.path.join("/", "root", "foo")) - with self.create_real_paths() as root_dir: - with self.raises_os_error(errno.ENOTDIR): - self.filesystem.add_real_directory(root_dir, target_path="/root/") + with self.create_real_paths() as root_dir, self.raises_os_error(errno.ENOTDIR): + self.filesystem.add_real_directory(root_dir, target_path="/root/") def test_cannot_overwrite_symlink_with_dir(self): self.filesystem.create_symlink( os.path.join("/", "root", "foo"), os.path.join("/", "root", "link") ) - with self.create_real_paths() as root_dir: - with self.raises_os_error(errno.EEXIST): - self.filesystem.add_real_directory(root_dir, target_path="/root/") + with self.create_real_paths() as root_dir, self.raises_os_error(errno.EEXIST): + self.filesystem.add_real_directory(root_dir, target_path="/root/") def test_symlink_is_merged(self): skip_if_symlink_not_supported() diff --git a/pyfakefs/tests/fake_filesystem_unittest_test.py b/pyfakefs/tests/fake_filesystem_unittest_test.py index 73b37f9c..0106af6b 100644 --- a/pyfakefs/tests/fake_filesystem_unittest_test.py +++ b/pyfakefs/tests/fake_filesystem_unittest_test.py @@ -37,13 +37,13 @@ import pyfakefs.tests.import_as_example import pyfakefs.tests.logsio -from pyfakefs import fake_filesystem_unittest, fake_filesystem +from pyfakefs import fake_filesystem, fake_filesystem_unittest from pyfakefs.fake_filesystem import OSType from pyfakefs.fake_filesystem_unittest import ( Patcher, + PatchMode, Pause, patchfs, - PatchMode, ) from pyfakefs.helpers import IS_PYPY from pyfakefs.tests.fixtures import module_with_attributes @@ -85,11 +85,14 @@ def test_nested_invocation(self): def test_nested_invocation_with_args(self): with Patcher() as patcher: patcher.fs.create_file("/foo/bar", contents="test") - with self.assertWarnsRegex( - UserWarning, "Nested fake filesystem invocation using custom arguments" + with ( + self.assertWarnsRegex( + UserWarning, + "Nested fake filesystem invocation using custom arguments", + ), + Patcher(allow_root_user=False), ): - with Patcher(allow_root_user=False): - pass + pass class TestPatchfsArgumentOrder(TestCase): @@ -303,7 +306,7 @@ def test_attributes(self): self.assertEqual(module_with_attributes.io, "io attribute value") -import math as path # noqa: E402 wanted import not at top +import math as path class TestPathNotPatchedIfNotOsPath(TestPyfakefsUnittestBase): @@ -585,8 +588,8 @@ def test_non_root_behavior(self): file_path = "/baz" self.fs.create_file(file_path) os.chmod(file_path, 0o400) - with self.assertRaises(OSError): - open(file_path, "w", encoding="utf8") + with self.assertRaises(OSError), open(file_path, "w", encoding="utf8"): + pass class PauseResumeTest(fake_filesystem_unittest.TestCase): @@ -594,73 +597,69 @@ def setUp(self): self.setUpPyfakefs() def test_pause_resume(self): - fake_temp_file = tempfile.NamedTemporaryFile() - self.assertTrue(self.fs.exists(fake_temp_file.name)) - self.assertTrue(os.path.exists(fake_temp_file.name)) - self.pause() - self.assertTrue(self.fs.exists(fake_temp_file.name)) - self.assertFalse(os.path.exists(fake_temp_file.name)) - real_temp_file = tempfile.NamedTemporaryFile() - self.assertFalse(self.fs.exists(real_temp_file.name)) - self.assertTrue(os.path.exists(real_temp_file.name)) - self.resume() - self.assertFalse(os.path.exists(real_temp_file.name)) - self.assertTrue(os.path.exists(fake_temp_file.name)) - self.pause() - real_temp_file.close() - self.resume() + with tempfile.NamedTemporaryFile() as fake_temp_file: + self.assertTrue(self.fs.exists(fake_temp_file.name)) + self.assertTrue(os.path.exists(fake_temp_file.name)) + self.pause() + self.assertTrue(self.fs.exists(fake_temp_file.name)) + self.assertFalse(os.path.exists(fake_temp_file.name)) + with tempfile.NamedTemporaryFile() as real_temp_file: + self.assertFalse(self.fs.exists(real_temp_file.name)) + self.assertTrue(os.path.exists(real_temp_file.name)) + self.resume() + self.assertFalse(os.path.exists(real_temp_file.name)) + self.assertTrue(os.path.exists(fake_temp_file.name)) + self.pause() + self.resume() def test_pause_resume_fs(self): - fake_temp_file = tempfile.NamedTemporaryFile() - self.assertTrue(self.fs.exists(fake_temp_file.name)) - self.assertTrue(os.path.exists(fake_temp_file.name)) - # resume does nothing if not paused - self.fs.resume() - self.assertTrue(os.path.exists(fake_temp_file.name)) - self.fs.pause() - self.assertTrue(self.fs.exists(fake_temp_file.name)) - self.assertFalse(os.path.exists(fake_temp_file.name)) - real_temp_file = tempfile.NamedTemporaryFile() - self.assertFalse(self.fs.exists(real_temp_file.name)) - self.assertTrue(os.path.exists(real_temp_file.name)) - # pause does nothing if already paused - self.fs.pause() - self.assertFalse(self.fs.exists(real_temp_file.name)) - self.assertTrue(os.path.exists(real_temp_file.name)) - self.fs.resume() - self.assertFalse(os.path.exists(real_temp_file.name)) - self.assertTrue(os.path.exists(fake_temp_file.name)) - self.fs.pause() - real_temp_file.close() - self.fs.resume() + with tempfile.NamedTemporaryFile() as fake_temp_file: + self.assertTrue(self.fs.exists(fake_temp_file.name)) + self.assertTrue(os.path.exists(fake_temp_file.name)) + # resume does nothing if not paused + self.fs.resume() + self.assertTrue(os.path.exists(fake_temp_file.name)) + self.fs.pause() + self.assertTrue(self.fs.exists(fake_temp_file.name)) + self.assertFalse(os.path.exists(fake_temp_file.name)) + with tempfile.NamedTemporaryFile() as real_temp_file: + self.assertFalse(self.fs.exists(real_temp_file.name)) + self.assertTrue(os.path.exists(real_temp_file.name)) + # pause does nothing if already paused + self.fs.pause() + self.assertFalse(self.fs.exists(real_temp_file.name)) + self.assertTrue(os.path.exists(real_temp_file.name)) + self.fs.resume() + self.assertFalse(os.path.exists(real_temp_file.name)) + self.assertTrue(os.path.exists(fake_temp_file.name)) + self.fs.pause() + self.fs.resume() def test_pause_resume_contextmanager(self): - fake_temp_file = tempfile.NamedTemporaryFile() - self.assertTrue(self.fs.exists(fake_temp_file.name)) - self.assertTrue(os.path.exists(fake_temp_file.name)) - with Pause(self): + with tempfile.NamedTemporaryFile() as fake_temp_file: self.assertTrue(self.fs.exists(fake_temp_file.name)) - self.assertFalse(os.path.exists(fake_temp_file.name)) - real_temp_file = tempfile.NamedTemporaryFile() - self.assertFalse(self.fs.exists(real_temp_file.name)) - self.assertTrue(os.path.exists(real_temp_file.name)) - real_temp_file.close() - self.assertFalse(os.path.exists(real_temp_file.name)) - self.assertTrue(os.path.exists(fake_temp_file.name)) + self.assertTrue(os.path.exists(fake_temp_file.name)) + with Pause(self): + self.assertTrue(self.fs.exists(fake_temp_file.name)) + self.assertFalse(os.path.exists(fake_temp_file.name)) + with tempfile.NamedTemporaryFile() as real_temp_file: + self.assertFalse(self.fs.exists(real_temp_file.name)) + self.assertTrue(os.path.exists(real_temp_file.name)) + self.assertFalse(os.path.exists(real_temp_file.name)) + self.assertTrue(os.path.exists(fake_temp_file.name)) def test_pause_resume_fs_contextmanager(self): - fake_temp_file = tempfile.NamedTemporaryFile() - self.assertTrue(self.fs.exists(fake_temp_file.name)) - self.assertTrue(os.path.exists(fake_temp_file.name)) - with Pause(self.fs): + with tempfile.NamedTemporaryFile() as fake_temp_file: self.assertTrue(self.fs.exists(fake_temp_file.name)) - self.assertFalse(os.path.exists(fake_temp_file.name)) - real_temp_file = tempfile.NamedTemporaryFile() - self.assertFalse(self.fs.exists(real_temp_file.name)) - self.assertTrue(os.path.exists(real_temp_file.name)) - real_temp_file.close() - self.assertFalse(os.path.exists(real_temp_file.name)) - self.assertTrue(os.path.exists(fake_temp_file.name)) + self.assertTrue(os.path.exists(fake_temp_file.name)) + with Pause(self.fs): + self.assertTrue(self.fs.exists(fake_temp_file.name)) + self.assertFalse(os.path.exists(fake_temp_file.name)) + with tempfile.NamedTemporaryFile() as real_temp_file: + self.assertFalse(self.fs.exists(real_temp_file.name)) + self.assertTrue(os.path.exists(real_temp_file.name)) + self.assertFalse(os.path.exists(real_temp_file.name)) + self.assertTrue(os.path.exists(fake_temp_file.name)) def test_pause_resume_without_patcher(self): fs = fake_filesystem.FakeFilesystem() @@ -678,38 +677,34 @@ def test_that_tempfile_is_patched_after_resume(fs): class PauseResumePatcherTest(fake_filesystem_unittest.TestCase): def test_pause_resume(self): with Patcher() as p: - fake_temp_file = tempfile.NamedTemporaryFile() - self.assertTrue(p.fs.exists(fake_temp_file.name)) - self.assertTrue(os.path.exists(fake_temp_file.name)) - p.pause() - self.assertTrue(p.fs.exists(fake_temp_file.name)) - self.assertFalse(os.path.exists(fake_temp_file.name)) - real_temp_file = tempfile.NamedTemporaryFile() - self.assertFalse(p.fs.exists(real_temp_file.name)) - self.assertTrue(os.path.exists(real_temp_file.name)) - p.resume() - self.assertFalse(os.path.exists(real_temp_file.name)) - self.assertTrue(os.path.exists(fake_temp_file.name)) - fake_temp_file.close() - p.pause() - real_temp_file.close() + with tempfile.NamedTemporaryFile() as fake_temp_file: + self.assertTrue(p.fs.exists(fake_temp_file.name)) + self.assertTrue(os.path.exists(fake_temp_file.name)) + p.pause() + self.assertTrue(p.fs.exists(fake_temp_file.name)) + self.assertFalse(os.path.exists(fake_temp_file.name)) + with tempfile.NamedTemporaryFile() as real_temp_file: + self.assertFalse(p.fs.exists(real_temp_file.name)) + self.assertTrue(os.path.exists(real_temp_file.name)) + p.resume() + self.assertFalse(os.path.exists(real_temp_file.name)) + self.assertTrue(os.path.exists(fake_temp_file.name)) + fake_temp_file.close() + p.pause() p.resume() def test_pause_resume_contextmanager(self): - with Patcher() as p: - fake_temp_file = tempfile.NamedTemporaryFile() + with Patcher() as p, tempfile.NamedTemporaryFile() as fake_temp_file: self.assertTrue(p.fs.exists(fake_temp_file.name)) self.assertTrue(os.path.exists(fake_temp_file.name)) with Pause(p): self.assertTrue(p.fs.exists(fake_temp_file.name)) self.assertFalse(os.path.exists(fake_temp_file.name)) - real_temp_file = tempfile.NamedTemporaryFile() - self.assertFalse(p.fs.exists(real_temp_file.name)) - self.assertTrue(os.path.exists(real_temp_file.name)) - real_temp_file.close() + with tempfile.NamedTemporaryFile() as real_temp_file: + self.assertFalse(p.fs.exists(real_temp_file.name)) + self.assertTrue(os.path.exists(real_temp_file.name)) self.assertFalse(os.path.exists(real_temp_file.name)) self.assertTrue(os.path.exists(fake_temp_file.name)) - fake_temp_file.close() class TestPyfakefsTestCase(unittest.TestCase): @@ -973,8 +968,8 @@ def test_drivelike_path(self): def test_tempfile_access(self): # regression test for #912 self.fs.os = OSType.LINUX - tmp_file = tempfile.TemporaryFile() - assert tmp_file + with tempfile.TemporaryFile() as f: + assert f @unittest.skipIf(sys.platform != "win32", "Windows-specific behavior") diff --git a/pyfakefs/tests/fake_filesystem_vs_real_test.py b/pyfakefs/tests/fake_filesystem_vs_real_test.py index 32d475d9..bd0c5e51 100644 --- a/pyfakefs/tests/fake_filesystem_vs_real_test.py +++ b/pyfakefs/tests/fake_filesystem_vs_real_test.py @@ -22,7 +22,7 @@ import time import unittest -from pyfakefs import fake_filesystem, fake_os, fake_open +from pyfakefs import fake_filesystem, fake_open, fake_os from pyfakefs.tests.test_utils import skip_if_symlink_not_supported @@ -39,6 +39,7 @@ def _get_errno(raised_error): return raised_error.errno except AttributeError: pass + return None class FakeFilesystemVsRealTest(unittest.TestCase): @@ -63,20 +64,17 @@ def _create_test_file(self, file_type, path, contents=None): os.mkdir(real_path) self.fake_os.mkdir(fake_path) if file_type == "f": - fh = open(real_path, "w", encoding="utf8") - fh.write(contents or "") - fh.close() + with open(real_path, "w", encoding="utf8") as fh: + fh.write(contents or "") fh = self.fake_open(fake_path, "w", encoding="utf8") fh.write(contents or "") fh.close() # b for binary file if file_type == "b": - fh = open(real_path, "wb") - fh.write(contents or "") - fh.close() - fh = self.fake_open(fake_path, "wb") - fh.write(contents or "") - fh.close() + with open(real_path, "wb") as fh: + fh.write(contents or "") + with self.fake_open(fake_path, "wb") as fh: + fh.write(contents or "") # l for symlink, h for hard link if file_type in ("l", "h"): contents = sep(contents) @@ -96,7 +94,7 @@ def setUp(self): # Base paths in the real and test file systems. We keep them different # so that missing features in the fake don't fall through to the base # operations and magically succeed. - tsname = "fakefs.%s" % time.time() + tsname = f"fakefs.{time.time()}" self.cwd = os.getcwd() # Fully expand the base_path - required on OS X. self.real_base = os.path.realpath(os.path.join(tempfile.gettempdir(), tsname)) @@ -132,8 +130,7 @@ def tearDown(self): except OSError as e: if "Directory not empty" in e: self.fail( - "Real path %s not empty: %s : %s" - % (real_path, e, os.listdir(real_path)) + f"Real path {real_path} not empty: {e} : {os.listdir(real_path)}" ) else: raise @@ -190,48 +187,27 @@ def _error_class(exc): # is almost always different because of the file paths. if _error_class(real_err) != _error_class(fake_err): if real_err is None: - return "{}: real version returned {}, fake raised {}".format( - method_call, - real_value, - _error_class(fake_err), - ) + return f"{method_call}: real version returned {real_value}, fake raised {_error_class(fake_err)}" if fake_err is None: - return "{}: real version raised {}, fake returned {}".format( - method_call, - _error_class(real_err), - fake_value, - ) - return "{}: real version raised {}, fake raised {}".format( - method_call, - _error_class(real_err), - _error_class(fake_err), - ) + return f"{method_call}: real version raised {_error_class(real_err)}, fake returned {fake_value}" + return f"{method_call}: real version raised {_error_class(real_err)}, fake raised {_error_class(fake_err)}" real_errno = _get_errno(real_err) fake_errno = _get_errno(fake_err) if real_errno != fake_errno: - return "{}({}): both raised {}, real errno {}, fake errno {}".format( - method_name, - path, - _error_class(real_err), - real_errno, - fake_errno, - ) + return f"{method_name}({path}): both raised {_error_class(real_err)}, real errno {real_errno}, fake errno {fake_errno}" # If the method is supposed to return a full path AND both values # begin with the expected full path, then trim it off. - if method_returns_path: - if ( - real_value - and fake_value - and real_value.startswith(self.real_base) - and fake_value.startswith(self.fake_base) - ): - real_value = real_value[len(self.real_base) :] - fake_value = fake_value[len(self.fake_base) :] + if method_returns_path and ( + real_value + and fake_value + and real_value.startswith(self.real_base) + and fake_value.startswith(self.fake_base) + ): + real_value = real_value[len(self.real_base) :] + fake_value = fake_value[len(self.fake_base) :] if real_value != fake_value: - return "{}: real return {}, fake returned {}".format( - method_call, - real_value, - fake_value, + return ( + f"{method_call}: real return {real_value}, fake returned {fake_value}" ) return None @@ -249,7 +225,7 @@ def _get_fake_value(method_name, path, fake): fake_value = result.decode() else: fake_value = str(result) - except Exception as e: # pylint: disable-msg=W0703 + except Exception as e: # noqa: BLE001 fake_err = e return fake_err, fake_value @@ -257,7 +233,6 @@ def _get_fake_value(method_name, path, fake): def _get_real_value(method_name, path, real): real_value = None real_err = None - # Catching Exception below gives a lint warning, but it's what we need. try: args = [] if path == () else [path] real_method = real @@ -268,7 +243,7 @@ def _get_real_value(method_name, path, real): real_value = result.decode() else: real_value = str(result) - except Exception as e: # pylint: disable-msg=W0703 + except Exception as e: # noqa: BLE001 real_err = e return real_err, real_value @@ -319,11 +294,13 @@ def diff_open_method_behavior( kwargs = {} if "b" not in mode: kwargs["encoding"] = "utf8" - with open(path, mode, **kwargs) as real_fh: - with self.fake_open(path, mode, **kwargs) as fake_fh: - return self._compare_behaviors( - method_name, data, real_fh, fake_fh, method_returns_data - ) + with ( + open(path, mode, **kwargs) as real_fh, + self.fake_open(path, mode, **kwargs) as fake_fh, + ): + return self._compare_behaviors( + method_name, data, real_fh, fake_fh, method_returns_data + ) def diff_os_path_method_behavior( self, method_name, path, method_returns_path=False @@ -422,8 +399,7 @@ def assertAllOsBehaviorsMatch(self, path, excludes=None): differences.append(diff) if differences: self.fail( - "Behaviors do not match for %s:\n %s" - % (path, "\n ".join(differences)) + f"Behaviors do not match for {path}:\n " + "\n ".join(differences) ) def assertFileHandleBehaviorsMatch(self, path, mode, data): @@ -442,8 +418,7 @@ def assertFileHandleBehaviorsMatch(self, path, mode, data): differences.append(diff) if differences: self.fail( - "Behaviors do not match for %s:\n %s" - % (path, "\n ".join(differences)) + f"Behaviors do not match for {path}:\n " + "\n ".join(differences) ) def assertFileHandleOpenBehaviorsMatch(self, *args, **kwargs): @@ -466,13 +441,13 @@ def assertFileHandleOpenBehaviorsMatch(self, *args, **kwargs): try: with open(*args, **kwargs): pass - except Exception as e: # pylint: disable-msg=W0703 + except Exception as e: # noqa: BLE001 real_err = e try: with self.fake_open(*args, **kwargs): pass - except Exception as e: # pylint: disable-msg=W0703 + except Exception as e: # noqa: BLE001 fake_err = e # default equal in case one is None and other is not. @@ -484,12 +459,9 @@ def assertFileHandleOpenBehaviorsMatch(self, *args, **kwargs): ) if not is_exception_equal: - msg = "Behaviors don't match on open with args {} & kwargs {}.\n".format( - args, - kwargs, - ) - real_err_msg = "Real open results in: %s\n" % repr(real_err) - fake_err_msg = "Fake open results in: %s\n" % repr(fake_err) + msg = f"Behaviors don't match on open with args {args} & kwargs {kwargs}.\n" + real_err_msg = f"Real open results in: {real_err}\n" + fake_err_msg = f"Fake open results in: {fake_err}\n" self.fail(msg + real_err_msg + fake_err_msg) # Helpers for checks which are not straight method calls. @@ -501,7 +473,7 @@ def _access_fake(self, path): return self.fake_os.access(path, os.R_OK) def _stat_result_real(self, path, prop, support_dir=True): - real_path, unused_fake_path = self._paths(path) + real_path, _ = self._paths(path) # fake_filesystem.py does not implement stat().st_size for directories if not support_dir and os.path.isdir(real_path): return None @@ -514,26 +486,26 @@ def _stat_result_fake(self, path, prop, support_dir=True): return getattr(self.fake_os.stat(fake_path), prop) def _lstat_size_real(self, path): - real_path, unused_fake_path = self._paths(path) + real_path, _ = self._paths(path) if os.path.isdir(real_path): return None size = os.lstat(real_path).st_size # Account for the difference in the lengths of the absolute paths. - if os.path.islink(real_path): - if os.readlink(real_path).startswith(os.sep): - size -= len(self.real_base) + if os.path.islink(real_path) and os.readlink(real_path).startswith(os.sep): + size -= len(self.real_base) return size def _lstat_size_fake(self, path): - unused_real_path, fake_path = self._paths(path) + _, fake_path = self._paths(path) # size = 0 if self.fake_os.path.isdir(fake_path): return None size = self.fake_os.lstat(fake_path).st_size # Account for the difference in the lengths of the absolute paths. - if self.fake_os.path.islink(fake_path): - if self.fake_os.readlink(fake_path).startswith(os.sep): - size -= len(self.fake_base) + if self.fake_os.path.islink(fake_path) and self.fake_os.readlink( + fake_path + ).startswith(os.sep): + size -= len(self.fake_base) return size def test_isabs(self): diff --git a/pyfakefs/tests/fake_open_test.py b/pyfakefs/tests/fake_open_test.py index 1793a36c..3ed15444 100644 --- a/pyfakefs/tests/fake_open_test.py +++ b/pyfakefs/tests/fake_open_test.py @@ -24,9 +24,9 @@ import unittest from pyfakefs import fake_filesystem, helpers -from pyfakefs.helpers import is_root, IS_PYPY, get_locale_encoding +from pyfakefs.fake_filesystem_unittest import Patcher, PatchMode from pyfakefs.fake_io import FakeIoModule -from pyfakefs.fake_filesystem_unittest import PatchMode, Patcher +from pyfakefs.helpers import IS_PYPY, get_locale_encoding, is_root from pyfakefs.tests.skipped_pathlib import read_open from pyfakefs.tests.test_utils import RealFsTestCase, skip_if_symlink_not_supported @@ -602,24 +602,28 @@ def test_file_descriptors_for_different_files(self): third_path = self.make_path("some_file3") self.create_file(third_path, contents="contents here3") - with self.open(first_path, encoding="utf8") as fake_file1: - with self.open(second_path, encoding="utf8") as fake_file2: - with self.open(third_path, encoding="utf8") as fake_file3: - fileno2 = fake_file2.fileno() - self.assertGreater(fileno2, fake_file1.fileno()) - self.assertGreater(fake_file3.fileno(), fileno2) + with ( + self.open(first_path, encoding="utf8") as fake_file1, + self.open(second_path, encoding="utf8") as fake_file2, + self.open(third_path, encoding="utf8") as fake_file3, + ): + fileno2 = fake_file2.fileno() + self.assertGreater(fileno2, fake_file1.fileno()) + self.assertGreater(fake_file3.fileno(), fileno2) def test_file_descriptors_for_the_same_file_are_different(self): first_path = self.make_path("some_file1") self.create_file(first_path, contents="contents here1") second_path = self.make_path("some_file2") self.create_file(second_path, contents="contents here2") - with self.open(first_path, encoding="utf8") as fake_file1: - with self.open(second_path, encoding="utf8") as fake_file2: - with self.open(first_path, encoding="utf8") as fake_file1a: - fileno2 = fake_file2.fileno() - self.assertNotEqual(fileno2, fake_file1.fileno()) - self.assertNotEqual(fake_file1a.fileno(), fileno2) + with ( + self.open(first_path, encoding="utf8") as fake_file1, + self.open(second_path, encoding="utf8") as fake_file2, + self.open(first_path, encoding="utf8") as fake_file1a, + ): + fileno2 = fake_file2.fileno() + self.assertNotEqual(fileno2, fake_file1.fileno()) + self.assertNotEqual(fake_file1a.fileno(), fileno2) def test_reused_file_descriptors_do_not_affect_others(self): first_path = self.make_path("some_file1") @@ -629,21 +633,25 @@ def test_reused_file_descriptors_do_not_affect_others(self): third_path = self.make_path("some_file3") self.create_file(third_path, contents="contents here3") - with self.open(first_path, "r", encoding="utf8") as fake_file1: - with self.open(second_path, "r", encoding="utf8") as fake_file2: - fake_file3 = self.open(third_path, "r", encoding="utf8") - fake_file1a = self.open(first_path, "r", encoding="utf8") - fileno1 = fake_file1.fileno() - fileno2 = fake_file2.fileno() - fileno3 = fake_file3.fileno() - fileno4 = fake_file1a.fileno() - - with self.open(second_path, "r", encoding="utf8") as fake_file2: - with self.open(first_path, "r", encoding="utf8") as fake_file1b: - self.assertEqual(fileno1, fake_file2.fileno()) - self.assertEqual(fileno2, fake_file1b.fileno()) - self.assertEqual(fileno3, fake_file3.fileno()) - self.assertEqual(fileno4, fake_file1a.fileno()) + with ( + self.open(first_path, "r", encoding="utf8") as fake_file1, + self.open(second_path, "r", encoding="utf8") as fake_file2, + ): + fake_file3 = self.open(third_path, "r", encoding="utf8") + fake_file1a = self.open(first_path, "r", encoding="utf8") + fileno1 = fake_file1.fileno() + fileno2 = fake_file2.fileno() + fileno3 = fake_file3.fileno() + fileno4 = fake_file1a.fileno() + + with ( + self.open(second_path, "r", encoding="utf8") as fake_file2, + self.open(first_path, "r", encoding="utf8") as fake_file1b, + ): + self.assertEqual(fileno1, fake_file2.fileno()) + self.assertEqual(fileno2, fake_file1b.fileno()) + self.assertEqual(fileno3, fake_file3.fileno()) + self.assertEqual(fileno4, fake_file1a.fileno()) fake_file3.close() fake_file1a.close() @@ -651,55 +659,59 @@ def test_intertwined_read_write(self): file_path = self.make_path("some_file") self.create_file(file_path) - with self.open(file_path, "a", encoding="utf8") as writer: - with self.open(file_path, "r", encoding="utf8") as reader: - writes = [ - "hello", - "world\n", - "somewhere\nover", - "the\n", - "rainbow", - ] - reads = [] - # when writes are flushes, they are piped to the reader - for write in writes: - writer.write(write) - writer.flush() - reads.append(reader.read()) - reader.flush() - self.assertEqual(writes, reads) - writes = ["nothing", "to\nsee", "here"] - reads = [] - # when writes are not flushed, the reader doesn't read - # anything new - for write in writes: - writer.write(write) - reads.append(reader.read()) - self.assertEqual(["" for _ in writes], reads) + with ( + self.open(file_path, "a", encoding="utf8") as writer, + self.open(file_path, "r", encoding="utf8") as reader, + ): + writes = [ + "hello", + "world\n", + "somewhere\nover", + "the\n", + "rainbow", + ] + reads = [] + # when writes are flushes, they are piped to the reader + for write in writes: + writer.write(write) + writer.flush() + reads.append(reader.read()) + reader.flush() + self.assertEqual(writes, reads) + writes = ["nothing", "to\nsee", "here"] + reads = [] + # when writes are not flushed, the reader doesn't read + # anything new + for write in writes: + writer.write(write) + reads.append(reader.read()) + self.assertEqual(["" for _ in writes], reads) def test_intertwined_read_write_python3_str(self): file_path = self.make_path("some_file") self.create_file(file_path) - with self.open(file_path, "a", encoding="utf-8") as writer: - with self.open(file_path, "r", encoding="utf-8") as reader: - writes = ["привет", "мир\n", "где-то\nза", "радугой"] - reads = [] - # when writes are flushes, they are piped to the reader - for write in writes: - writer.write(write) - writer.flush() - reads.append(reader.read()) - reader.flush() - self.assertEqual(writes, reads) - writes = ["ничего", "не\nвидно"] - reads = [] - # when writes are not flushed, the reader doesn't - # read anything new - for write in writes: - writer.write(write) - reads.append(reader.read()) - self.assertEqual(["" for _ in writes], reads) + with ( + self.open(file_path, "a", encoding="utf-8") as writer, + self.open(file_path, "r", encoding="utf-8") as reader, + ): + writes = ["привет", "мир\n", "где-то\nза", "радугой"] + reads = [] + # when writes are flushes, they are piped to the reader + for write in writes: + writer.write(write) + writer.flush() + reads.append(reader.read()) + reader.flush() + self.assertEqual(writes, reads) + writes = ["ничего", "не\nвидно"] + reads = [] + # when writes are not flushed, the reader doesn't + # read anything new + for write in writes: + writer.write(write) + reads.append(reader.read()) + self.assertEqual(["" for _ in writes], reads) def test_open_io_errors(self): file_path = self.make_path("some_file") @@ -783,12 +795,14 @@ def test_truncate_flushes_contents(self): def test_update_other_instances_of_same_file_on_flush(self): # Regression test for #302 file_path = self.make_path("baz") - with self.open(file_path, "w", encoding="utf8") as f0: - with self.open(file_path, "w", encoding="utf8") as f1: - f0.write("test") - f0.truncate() - f1.flush() - self.assertEqual(4, self.os.path.getsize(file_path)) + with ( + self.open(file_path, "w", encoding="utf8") as f0, + self.open(file_path, "w", encoding="utf8") as f1, + ): + f0.write("test") + f0.truncate() + f1.flush() + self.assertEqual(4, self.os.path.getsize(file_path)) def test_getsize_after_truncate(self): # Regression test for #412 @@ -976,11 +990,13 @@ def test_closing_file_with_different_close_mode(self): def test_truncate_flushes_zeros(self): # Regression test for #301 file_path = self.make_path("baz") - with self.open(file_path, "w", encoding="utf8") as f0: - with self.open(file_path, encoding="utf8") as f1: - f0.seek(1) - f0.truncate() - self.assertEqual("\0", f1.read()) + with ( + self.open(file_path, "w", encoding="utf8") as f0, + self.open(file_path, encoding="utf8") as f1, + ): + f0.seek(1) + f0.truncate() + self.assertEqual("\0", f1.read()) def test_byte_filename(self): file_path = self.make_path(b"test") @@ -1011,9 +1027,8 @@ def test_pseudo_devices(self): with self.open("/dev/zero", "rb") as f: self.assertEqual(b"\0\0\0\0", f.read(4)) if sys.platform == "linux": - with self.raises_os_error(errno.ENOSPC): - with self.open("/dev/full", "wb") as f: - f.write(b"\0") + with self.raises_os_error(errno.ENOSPC), self.open("/dev/full", "wb") as f: + f.write(b"\0") def test_utf16_text(self): # regression test for #574 @@ -1535,9 +1550,11 @@ def test_write_str_read_bytes(self): def test_write_str_error_modes(self): str_contents = "علي بابا" - with self.open(self.file_path, "w", encoding="cyrillic") as f: - with self.assertRaises(UnicodeEncodeError): - f.write(str_contents) + with ( + self.open(self.file_path, "w", encoding="cyrillic") as f, + self.assertRaises(UnicodeEncodeError), + ): + f.write(str_contents) with self.open( self.file_path, "w", encoding="ascii", errors="xmlcharrefreplace" @@ -1567,9 +1584,11 @@ def test_read_str_error_modes(self): f.write(str_contents) # default strict encoding - with self.open(self.file_path, encoding="ascii") as f: - with self.assertRaises(UnicodeDecodeError): - f.read() + with ( + self.open(self.file_path, encoding="ascii") as f, + self.assertRaises(UnicodeDecodeError), + ): + f.read() with self.open(self.file_path, encoding="ascii", errors="replace") as f: contents = f.read() self.assertNotEqual(str_contents, contents) @@ -1954,12 +1973,12 @@ def test_write_binary(self): with self.write_and_reopen_file(f, mode="rb") as f1: self.assertEqual(self.file_contents, f1.read()) # Attempt to reopen the file in text mode - with self.open_file("wb") as f2: - with self.write_and_reopen_file( - f2, mode="r", encoding="ascii" - ) as f3: - with self.assertRaises(UnicodeDecodeError): - f3.read() + with ( + self.open_file("wb") as f2, + self.write_and_reopen_file(f2, mode="r", encoding="ascii") as f3, + self.assertRaises(UnicodeDecodeError), + ): + f3.read() def test_write_and_read_binary(self): with self.open_file_and_seek("w+b") as f: diff --git a/pyfakefs/tests/fake_os_test.py b/pyfakefs/tests/fake_os_test.py index da50645a..d9232598 100644 --- a/pyfakefs/tests/fake_os_test.py +++ b/pyfakefs/tests/fake_os_test.py @@ -21,17 +21,17 @@ import sys import unittest -from pyfakefs import fake_filesystem, fake_os, fake_open, fake_file +from pyfakefs import fake_file, fake_filesystem, fake_open, fake_os from pyfakefs.fake_filesystem import ( FakeFileOpen, is_root, - set_uid, set_gid, + set_uid, ) -from pyfakefs.helpers import IN_DOCKER, IS_PYPY, get_uid, get_gid, reset_ids, IS_WIN +from pyfakefs.helpers import IN_DOCKER, IS_PYPY, IS_WIN, get_gid, get_uid, reset_ids from pyfakefs.tests.test_utils import ( - TestCase, RealFsTestCase, + TestCase, skip_if_symlink_not_supported, ) @@ -315,7 +315,7 @@ def test_no_st_blocks_in_windows(self): file_path = self.make_path("foo") self.create_file(file_path, contents=b"") with self.assertRaises(AttributeError): - self.os.stat(file_path).st_blocks + _ = self.os.stat(file_path).st_blocks def test_stat_with_unc_path(self): self.skip_real_fs() @@ -649,6 +649,7 @@ def test_lexists_with_trailing_separator_macos(self): def test_islink_with_trailing_separator(self): skip_if_symlink_not_supported() + self.check_linux_and_windows() # unstable behavior under macOS file_path = self.make_path("foo") self.os.symlink(file_path, file_path) self.assertFalse(self.os.path.islink(file_path + self.os.sep)) @@ -738,6 +739,7 @@ def test_broken_symlink_with_trailing_separator_linux(self): self.check_linux_only() self.check_broken_symlink_with_trailing_separator(errno.EEXIST) + @unittest.skip(reason="Unstable behavior in newer macOS versions") def test_broken_symlink_with_trailing_separator_macos(self): # regression test for #371 self.check_macos_only() @@ -750,7 +752,7 @@ def test_broken_symlink_with_trailing_separator_windows(self): def test_circular_readlink_with_trailing_separator_posix(self): # Regression test for #372 - self.check_posix_only() + self.check_linux_only() # behavior unstable under macOS file_path = self.make_path("foo") self.os.symlink(file_path, file_path) self.assert_raises_os_error( @@ -1318,12 +1320,14 @@ def test_rename_symlink(self): def check_append_mode_tell_after_truncate(self, tell_result): file_path = self.make_path("baz") - with self.open(file_path, "w", encoding="utf8") as f0: - with self.open(file_path, "a", encoding="utf8") as f1: - f1.write("abcde") - f0.seek(2) - f0.truncate() - self.assertEqual(tell_result, f1.tell()) + with ( + self.open(file_path, "w", encoding="utf8") as f0, + self.open(file_path, "a", encoding="utf8") as f1, + ): + f1.write("abcde") + f0.seek(2) + f0.truncate() + self.assertEqual(tell_result, f1.tell()) with self.open(file_path, mode="rb") as f: self.assertEqual(b"\0\0abcde", f.read()) @@ -1547,10 +1551,10 @@ def test_removedirs_raises_if_cascade_removing_root(self): self.create_dir(directory) self.assertTrue(self.os.path.exists(directory)) self.assert_raises_os_error(errno.EBUSY, self.os.removedirs, directory) - head, unused_tail = self.os.path.split(directory) + head, _ = self.os.path.split(directory) while self.os.path.splitdrive(head)[1] != self.os.path.sep: self.assertFalse(self.os.path.exists(directory)) - head, unused_tail = self.os.path.split(head) + head, _ = self.os.path.split(head) def test_removedirs_with_trailing_slash(self): """removedirs works on directory names with trailing slashes.""" @@ -1589,13 +1593,13 @@ def test_mkdir(self): directory = "xyzzy" self.assertFalse(self.filesystem.exists(directory)) self.os.mkdir(directory) - self.assertTrue(self.filesystem.exists("/%s" % directory)) + self.assertTrue(self.filesystem.exists(f"/{directory}")) self.os.chdir(directory) self.os.mkdir(directory) self.assertTrue(self.filesystem.exists(f"/{directory}/{directory}")) self.os.chdir(directory) self.os.mkdir("../abccb") - self.assertTrue(self.os.path.exists("/%s/abccb" % directory)) + self.assertTrue(self.os.path.exists(f"/{directory}/abccb")) def test_mkdir_with_trailing_slash(self): """mkdir can create a directory named with a trailing slash.""" @@ -2226,9 +2230,11 @@ def test_fail_add_entry_to_readonly_dir(self): self.os.chown(ro_dir, 0, 0) # adding a new entry to the readonly subdirectory should fail - with self.assertRaises(PermissionError): - with self.open(f"{ro_dir}/file.txt", "w", encoding="utf8"): - pass + with ( + self.assertRaises(PermissionError), + self.open(f"{ro_dir}/file.txt", "w", encoding="utf8"), + ): + pass file_path = self.make_path("file.txt") self.create_file(file_path) with self.assertRaises(PermissionError): @@ -3127,9 +3133,11 @@ def test_listdir_possible_without_exe_permission(self): # even if we have read access to the file with self.assertRaises(PermissionError): self.os.stat(file_path) - with self.assertRaises(PermissionError): - with self.open(file_path, encoding="utf8") as f: - f.read() + with ( + self.assertRaises(PermissionError), + self.open(file_path, encoding="utf8") as f, + ): + f.read() def test_listdir_impossible_without_read_permission(self): # regression test for #960 @@ -4675,9 +4683,9 @@ class FakeOsModuleWalkTest(FakeOsModuleTestBase): def assertWalkResults(self, expected, top, topdown=True, followlinks=False): # as the result of walk is unsorted, we have to check against # sorted results - result = list( + result = [ step for step in self.os.walk(top, topdown=topdown, followlinks=followlinks) - ) + ] result = sorted(result, key=lambda lst: lst[0]) expected = sorted(expected, key=lambda lst: lst[0]) self.assertEqual(len(expected), len(result)) diff --git a/pyfakefs/tests/fake_pathlib_test.py b/pyfakefs/tests/fake_pathlib_test.py index 22e8a247..aea2f658 100644 --- a/pyfakefs/tests/fake_pathlib_test.py +++ b/pyfakefs/tests/fake_pathlib_test.py @@ -30,8 +30,8 @@ from unittest import mock from unittest.mock import patch -from pyfakefs import fake_pathlib, fake_filesystem, fake_filesystem_unittest, fake_os -from pyfakefs.fake_filesystem import OSType, FakeFilesystem +from pyfakefs import fake_filesystem, fake_filesystem_unittest, fake_os, fake_pathlib +from pyfakefs.fake_filesystem import FakeFilesystem, OSType from pyfakefs.fake_pathlib import FakePathlibModule from pyfakefs.helpers import IS_PYPY, is_root from pyfakefs.tests.skipped_pathlib import ( @@ -682,7 +682,7 @@ def test_iterdir_in_unreadable_dir(self): self.assert_raises_os_error(errno.EACCES, list, it) else: it = self.path(dir_path).iterdir() - path = str(list(it)[0]) + path = str(next(iter(it))) self.assertTrue(path.endswith("some_file")) def test_iterdir_and_glob_without_exe_permission(self): @@ -701,9 +701,9 @@ def test_iterdir_and_glob_without_exe_permission(self): self.os.link(another_file, directory / "link.txt") # We can enumerate the directory using iterdir and glob: assert len(list(directory.iterdir())) == 1 - assert list(directory.iterdir())[0] == file_path + assert next(iter(directory.iterdir())) == file_path assert len(list(directory.glob("*.txt"))) == 1 - assert list(directory.glob("*.txt"))[0] == file_path + assert next(iter(directory.glob("*.txt"))) == file_path # We cannot read files inside the directory, # even if we have read access to the file @@ -1463,10 +1463,12 @@ def fake_getgrgid(uid): path = self.make_path("some_file") self.create_file(path) self.os.chown(path, 42, 5) - with mock.patch("pwd.getpwuid", fake_getpwuid): - with mock.patch("grp.getgrgid", fake_getgrgid): - self.assertEqual("NewUser", self.path(path).owner()) - self.assertEqual("NewGroup", self.path(path).group()) + with ( + mock.patch("pwd.getpwuid", fake_getpwuid), + mock.patch("grp.getgrgid", fake_getgrgid), + ): + self.assertEqual("NewUser", self.path(path).owner()) + self.assertEqual("NewGroup", self.path(path).group()) def test_owner_and_group_windows(self): self.check_windows_only() @@ -1585,7 +1587,7 @@ def test_walk(self): self.create_dir(base_path) self.create_file(base_path / "1.txt") self.create_file(base_path / "bar" / "2.txt") - result = list(step for step in self.os.walk(base_path)) + result = [step for step in self.os.walk(base_path)] assert len(result) == 2 assert result[0] == (base_dir, ["bar"], ["1.txt"]) assert result[1] == (self.os.path.join(base_dir, "bar"), [], ["2.txt"]) diff --git a/pyfakefs/tests/fake_stat_time_test.py b/pyfakefs/tests/fake_stat_time_test.py index 2602d1ae..7a950059 100644 --- a/pyfakefs/tests/fake_stat_time_test.py +++ b/pyfakefs/tests/fake_stat_time_test.py @@ -411,9 +411,11 @@ def test_open_write_flush_close(self): self.check_open_write_flush_close_w_mode() def test_read_raises(self): - with self.open(self.file_path, "w", encoding="utf8") as f: - with self.assertRaises(OSError): - f.read() + with ( + self.open(self.file_path, "w", encoding="utf8") as f, + self.assertRaises(OSError), + ): + f.read() class TestRealModeW(TestFakeModeW): @@ -498,9 +500,11 @@ def test_open_write_flush_close(self): self.check_open_write_flush_close_non_w_mode() def test_read_raises(self): - with self.open(self.file_path, "a", encoding="utf8") as f: - with self.assertRaises(OSError): - f.read() + with ( + self.open(self.file_path, "a", encoding="utf8") as f, + self.assertRaises(OSError), + ): + f.read() class TestRealModeA(TestFakeModeA): @@ -580,9 +584,8 @@ def test_open_read_flush_close(self): self.assertEqual(flushed.st_mtime, closed.st_mtime) def test_open_not_existing_raises(self): - with self.assertRaises(OSError): - with self.open(self.file_path, "r"): - pass + with self.assertRaises(OSError), self.open(self.file_path, "r"): + pass class TestRealModeR(TestFakeModeR): @@ -611,9 +614,8 @@ def test_open_write_flush_close(self): self.check_open_write_flush_close_non_w_mode() def test_open_not_existing_raises(self): - with self.assertRaises(OSError): - with self.open(self.file_path, "r+"): - pass + with self.assertRaises(OSError), self.open(self.file_path, "r+"): + pass class TestRealModeRPlus(TestFakeModeRPlus): diff --git a/pyfakefs/tests/fake_tempfile_test.py b/pyfakefs/tests/fake_tempfile_test.py index 09d6a4fe..6e3fd8b8 100644 --- a/pyfakefs/tests/fake_tempfile_test.py +++ b/pyfakefs/tests/fake_tempfile_test.py @@ -31,23 +31,20 @@ def setUp(self): self.setUpPyfakefs() def test_named_temporary_file(self): - obj = tempfile.NamedTemporaryFile() - self.assertTrue(self.fs.get_object(obj.name)) - obj.close() + with tempfile.NamedTemporaryFile() as f: + self.assertTrue(self.fs.get_object(f.name)) with self.assertRaises(OSError): - self.fs.get_object(obj.name) + self.fs.get_object(f.name) def test_named_temporary_file_no_delete(self): - obj = tempfile.NamedTemporaryFile(delete=False) - obj.write(b"foo") - obj.close() - file_obj = self.fs.get_object(obj.name) + with tempfile.NamedTemporaryFile(delete=False) as f: + f.write(b"foo") + file_obj = self.fs.get_object(f.name) contents = file_obj.contents self.assertEqual("foo", contents) - obj = tempfile.NamedTemporaryFile(mode="w", encoding="utf8", delete=False) - obj.write("foo") - obj.close() - file_obj = self.fs.get_object(obj.name) + with tempfile.NamedTemporaryFile(mode="w", encoding="utf8", delete=False) as f: + f.write("foo") + file_obj = self.fs.get_object(f.name) self.assertEqual("foo", file_obj.contents) def test_mkstemp(self): @@ -101,8 +98,11 @@ def test_temporary_file(self): self.assertEqual(b"test", f.read()) def test_temporay_file_with_dir(self): - with self.assertRaises(FileNotFoundError): - tempfile.TemporaryFile(dir="/parent") + with ( + self.assertRaises(FileNotFoundError), + tempfile.TemporaryFile(dir="/parent"), + ): + pass os.mkdir("/parent") with tempfile.TemporaryFile() as f: f.write(b"test") diff --git a/pyfakefs/tests/import_as_example.py b/pyfakefs/tests/import_as_example.py index 835a2c4d..556b4921 100644 --- a/pyfakefs/tests/import_as_example.py +++ b/pyfakefs/tests/import_as_example.py @@ -19,11 +19,9 @@ import pathlib import sys from builtins import open as bltn_open -from io import open as io_open -from os import path -from os import stat +from os import path, stat from os import stat as my_stat -from os.path import exists, isfile, isdir, islink +from os.path import exists, isdir, isfile, islink from os.path import exists as my_exists from pathlib import Path @@ -101,7 +99,7 @@ def file_contents1(filepath): def file_contents2(filepath): - with io_open(filepath, encoding="utf8") as f: + with open(filepath, encoding="utf8") as f: return f.read() diff --git a/pyfakefs/tests/mox3_stubout_example.py b/pyfakefs/tests/mox3_stubout_example.py index 15aac940..2104fc46 100644 --- a/pyfakefs/tests/mox3_stubout_example.py +++ b/pyfakefs/tests/mox3_stubout_example.py @@ -29,4 +29,4 @@ def fabs(x): def tomorrow(): - return datetime.date.today() + datetime.timedelta(days=1) + return datetime.date.today() + datetime.timedelta(days=1) # noqa: DTZ011 diff --git a/pyfakefs/tests/performance_test.py b/pyfakefs/tests/performance_test.py index 56ad78b6..9b32cd74 100644 --- a/pyfakefs/tests/performance_test.py +++ b/pyfakefs/tests/performance_test.py @@ -29,9 +29,7 @@ def setUpClass(cls) -> None: def tearDownClass(cls) -> None: cls.elapsed_time = time.time() - cls.start_time print( - "Elapsed time per test for cached setup: {:.3f} ms".format( - cls.elapsed_time * 10 - ) + f"Elapsed time per test for cached setup: {cls.elapsed_time * 10:.3f} ms" ) def setUp(self) -> None: @@ -46,9 +44,7 @@ def setUpClass(cls) -> None: def tearDownClass(cls) -> None: cls.elapsed_time = time.time() - cls.start_time print( - "Elapsed time per test for uncached setup: {:.3f} ms".format( - cls.elapsed_time * 10 - ) + f"Elapsed time per test for uncached setup: {cls.elapsed_time * 10:.3f} ms" ) def setUp(self) -> None: diff --git a/pyfakefs/tests/test_utils.py b/pyfakefs/tests/test_utils.py index 04c94aa2..dbf4dc08 100644 --- a/pyfakefs/tests/test_utils.py +++ b/pyfakefs/tests/test_utils.py @@ -27,7 +27,7 @@ from unittest import mock from pyfakefs import fake_filesystem, fake_open, fake_os -from pyfakefs.helpers import is_byte_string, to_string, is_root +from pyfakefs.helpers import is_byte_string, is_root, to_string class DummyTime: