pytest-dev / pyfakefs

Provides a fake file system that mocks the Python file system modules.
https://pytest-pyfakefs.readthedocs.io
Apache License 2.0
645 stars 89 forks source link

Path.exists is not patched #1021

Closed sassanh closed 4 months ago

sassanh commented 4 months ago

Describe the bug I call Path().exists immediately after shutil.copyfile and it returns False while os.path.exists returns True. I guess Path().exists is using the real filesystem.

How To Reproduce

Path('/tmp/test').write_text('test')
print(Path('/tmp/test').exists())
print(os.path.exists('/tmp/test'))

Your environment

macOS-14.5-arm64-arm-64bit
Python 3.12.3 (main, Apr  9 2024, 08:09:14) [Clang 15.0.0 (clang-1500.3.9.4)]
pyfakefs 5.5.0
pytest 8.2.1
sassanh commented 4 months ago

I also noticed Path().unlink doesn't work (maybe it is working on the real filesystem) while os.remove works.

mrbean-bremen commented 4 months ago

Can you please show how you call that code? E.g. a reproducible example, if possible.

mrbean-bremen commented 4 months ago

For illustration - the following test passes:

def test_fakefs(fs):
    fs.os = OSType.LINUX
    path = Path('/tmp/test')
    path.parent.mkdir(exist_ok=True)
    path.touch()
    path.write_text('test')
    assert path.exists()
    assert os.path.exists('/tmp/test')
    path.unlink()
    assert not path.exists()

So you must be doing something different.

sassanh commented 4 months ago

Thanks for investigating it! I probably did something wrong, I will check it when I get back to my desk.

In the future I will add reproduction snippets with my reports.

sassanh commented 4 months ago

It was an issue on my side, I had pathlib in additional_skip_names from the past 🙈 I will make sure to create simple reproduction steps before reporting any issues in the future.

sassanh commented 4 months ago

@mrbean-bremen Quick question, are Path().exists and Path().unlink expected to respect additional_skip_names?

mrbean-bremen commented 4 months ago

Well... I had hoped you won't ask :)

The truth is that I did want to implement a more generic solution for the handling of additional_skip_names in pathlib, but couldn't get it to work. The current implementation is incomplete (yes, actually all methods should respect additional_skip_names) and ugly (using the callstack). I had hoped that it will sufficient until I get back to it, but obviously I was wrong.

Feel free to write a new issue. Maybe you even have an idea on how to implement this in a better way...