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

How to trigger a PermissionError on pathlib.Path.is_file on Windows? #720

Closed
jaraco opened this issue Sep 29, 2022 · 11 comments
Closed

How to trigger a PermissionError on pathlib.Path.is_file on Windows? #720

jaraco opened this issue Sep 29, 2022 · 11 comments

Comments

@jaraco
Copy link

jaraco commented Sep 29, 2022

In pypa/distutils#181, I'm trying to simulate a PermissionError when pathlib.Path.is_file() is called. I've been able to achieve this on Unix with path.chmod(0), but that has no effect on Windows. Can you suggest a change that would similarly trigger a PermissionError for is_file on Windows?

@mrbean-bremen
Copy link
Member

Good question. I would say this will not happen under Windows, at least I can't think of a matching scenario. Are you sure that this isn't a Posix problem (e.g. PosixPath problem)?

@mrbean-bremen
Copy link
Member

I had looked a bit further, and really couldn't find a possibility to achieve this under Windows, so I'm giving up on this.
Closing the issue.

@jaraco
Copy link
Author

jaraco commented Oct 16, 2022

Are you sure that this isn't a Posix problem (e.g. PosixPath problem)?

I'm not sure what you're asking.

Are you saying that PermissionErrors only occur on PosixPaths? Maybe. It does appear from this question that it's possible to get a PermisionError on Windows, so I'd expect to be able to trigger one using a WindowsPath.

Are you saying the problem is that the code is assuming PosixPath on Windows? No. The code uses pathlib.Path, which will adapt to the platform as appropriate.


I'll keep investigating to see if I can't create a file on Windows that naturally creates a permission error, and then see if pyfakefs can simulate that behavior.

@jaraco
Copy link
Author

jaraco commented Oct 16, 2022

I did find that I was able to edit the ACLs of a folder to Deny read/write access to a folder, and thereafter, attempting to access a file in that folder caused a PermissionError.

I found this answer provides on way to apply ACLs in Windows, though it requires a third-party library (pywin32/win32security) to enact the changes.

I suspect you're not going to want to model Windows file system ACLs in pyfakefs, but would you consider giving the user an API to force/simulate a PermissionError on read/write/list?

Something like:

fs.make_unreadable(path) and fs.make_unwritable(path) and fs.make_unlistable(dir)

On Linux, it could continue to enact 'chmod' on the path, but on Windows, it would annotate the fs with enough information to know to raise a PermissionError whenever an appropriate open or listdir is called on it.

Is it possible? Would this project consider something like that?

@mrbean-bremen mrbean-bremen reopened this Oct 17, 2022
@mrbean-bremen
Copy link
Member

mrbean-bremen commented Oct 17, 2022

Are you saying that PermissionErrors only occur on PosixPaths?

No, generally there are permission errors, I just couldn't create one that was raised on calling Path.is_file under Windows.

Are you saying the problem is that the code is assuming PosixPath on Windows?

No, I just thought that your specific problem may not occur under Windows (e.g. with WindowsPath instead of PosixPath), but I might have misunderstood this, if you did reproduce this under Windows.

Editing the ACLs is indeed a possibility. I tried to re-create the problem with standard Python filesystem functions, because pyfakefs generally does not handle OS-specific functions, as it cannot patch them. And you are right, we are not going to model ACLs in pyfakefs, this would indeed be out of scope.

That being said, your suggestion may make sense to help with such problems, so I definitely will look into it. Can't promise anything in terms of time - if I don't get to do this in the next 2 days (unlikely nope), I won't be available for a couple of weeks, so this may take some time...

@buhtz
Copy link

buhtz commented Dec 9, 2022

I have some experience in file testing things. I wouldn't say that is a job for pyfakefs.

You don't have use a fake filesystem or a fake file for that. Mock is_file() yourself and use the side_effects argument to make sure that a PermissonError (or OSError?) is raised.

@jaraco
Copy link
Author

jaraco commented Dec 11, 2022

I have some experience in file testing things. I wouldn't say that is a job for pyfakefs.

You don't have use a fake filesystem or a fake file for that. Mock is_file() yourself and use the side_effects argument to make sure that a PermissonError (or OSError?) is raised.

You're right. I could just not use pyfakefs and instead attempt to mock the file system operations myself. Originally, I began with that approach when I asked myself, surely someone else has built a library to aid with mocking file system operations, which is what led me to pyfakefs.

Writing selective mocks has its own problems. As described, the mocks are too specific to the implementation (only mocking individual calls like os.path.isfile or pathlib.Path.isfile) but also too broad (affecting all "is file" checks for the duration of the mock).

What I'm really aiming to do is simulate the conditions under which the failure occurred and not just exercise that the implementation does what it says it does. To do that effectively, I need a sophisticated solution like pyfakefs. I'd also like to have a generalizable approach that I can apply to other projects.

That's my rationale for why pyfakefs is a good home for this behavior.

Why do you say that pyfakefs shouldn't concern itself with permissions issues on a file system?

@mrbean-bremen
Copy link
Member

I have to admit that I neglected this issue. I started to work on it some time ago and then left it... I still think it would make sense to have this, and I'll try to get back to it in the near future.

@buhtz
Copy link

buhtz commented Dec 11, 2022

@jaraco Thanks for explaining. I think I got your point and understand that your use/test case is much more then I can see here and that such future would be very helpful for you.
I do think that pyfakefs should be able to handle permission issues. :)

mrbean-bremen added a commit to mrbean-bremen/pyfakefs that referenced this issue Jan 23, 2023
- makes it possible to simulate inaccessible paths under Windows
- see pytest-dev#720
@mrbean-bremen
Copy link
Member

mrbean-bremen commented Jan 23, 2023

@jaraco - Sorry that it took me ages to get back to this - it turned out that I actually didn't understand correctly what was needed (I made some incorrect assumption). I actually remembered to look at it again when I made a (completely unrelated) small PR in distutils...
After having a fresh look at this, it turned out that there is a very easy way to do this. I just made a respective PR, which I will merge soon if nothing comes up (EDIT: done).

I also tested this using the related test in distutils, where it would look like this:

    def test_find_config_files_permission_error(self, fake_home, fs):
        """
        Finding config files should not fail when directory is inaccessible.
        """
        fake_home.joinpath(pydistutils_cfg).write_text('')
        fs.chmod(fake_home, 0o000, force_unix_mode=True)
        Distribution().find_config_files()

It is a bit inconvenient, as you need to access the fake fs, but I think that this is acceptable in this case.

mrbean-bremen added a commit that referenced this issue Jan 24, 2023
- makes it possible to simulate inaccessible paths under Windows
- see #720
@mrbean-bremen
Copy link
Member

Closing as fixed in latest release (5.2.0). Feel free to reopen if it does not work for you.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants