Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add basic patching of fcntl module #646

Merged
merged 1 commit into from
Nov 7, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@ The released versions correspond to PyPi releases.
### Changes
* `os.listdir`, `os.scandir` and `pathlib.Path.listdir` now return the
directory list in a random order (see [#638](../../issues/638))
* the `fcntl` module under Unix is now mocked, e.g. all functions have no
effect (this may be changed in the future if needed,
see [#645](../../issues/645))

### Fixes
* fixed handling of alternative path separator in `os.path.split`,
Expand Down
43 changes: 43 additions & 0 deletions pyfakefs/fake_filesystem.py
Original file line number Diff line number Diff line change
Expand Up @@ -4864,6 +4864,49 @@ def __getattr__(self, name):
return getattr(self._io_module, name)


if sys.platform != 'win32':
import fcntl

class FakeFcntlModule:
"""Replaces the fcntl module. Only valid under Linux/MacOS,
currently just mocks the functionality away.
"""

@staticmethod
def dir() -> List[str]:
"""Return the list of patched function names. Used for patching
functions imported from the module.
"""
return ['fcntl', 'ioctl', 'flock', 'lockf']

def __init__(self, filesystem: FakeFilesystem):
"""
Args:
filesystem: FakeFilesystem used to provide file system
information (currently not used).
"""
self.filesystem = filesystem
self._fcntl_module = fcntl

def fcntl(self, fd: int, cmd: int, arg: int = 0) -> Union[int, bytes]:
return 0

def ioctl(self, fd: int, request: int, arg: int = 0,
mutate_flag: bool = True) -> Union[int, bytes]:
return 0

def flock(self, fd: int, operation: int) -> None:
pass

def lockf(self, fd: int, cmd: int, len: int = 0,
start: int = 0, whence=0) -> Any:
pass

def __getattr__(self, name):
"""Forwards any unfaked calls to the standard fcntl module."""
return getattr(self._fcntl_module, name)


class FakeFileWrapper:
"""Wrapper for a stream object for use by a FakeFile object.

Expand Down
6 changes: 5 additions & 1 deletion pyfakefs/fake_filesystem_unittest.py
Original file line number Diff line number Diff line change
Expand Up @@ -391,7 +391,8 @@ class Patcher:

IS_WINDOWS = sys.platform in ('win32', 'cygwin')

SKIPNAMES = {'os', 'path', 'io', 'genericpath', OS_MODULE, PATH_MODULE}
SKIPNAMES = {'os', 'path', 'io', 'genericpath', 'fcntl',
OS_MODULE, PATH_MODULE}

# hold values from last call - if changed, the cache has to be invalidated
PATCHED_MODULE_NAMES: Set[str] = set()
Expand Down Expand Up @@ -537,6 +538,9 @@ def _init_fake_module_classes(self) -> None:
if IS_PYPY:
# in PyPy io.open, the module is referenced as _io
self._fake_module_classes['_io'] = fake_filesystem.FakeIoModule
if sys.platform != 'win32':
self._fake_module_classes[
'fcntl'] = fake_filesystem.FakeFcntlModule

# class modules maps class names against a list of modules they can
# be contained in - this allows for alternative modules like
Expand Down