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 PYTEST_TMPDIR_FILE_MASK environment variable #10786
Add PYTEST_TMPDIR_FILE_MASK environment variable #10786
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks @BeyondEvil!
Other than my comments, why did you decide on using an environment variable rather than a configuration option? I suspect because one would use this only when running external code in containers, so it makes sense for it to be configured in the environment, just wanted to make sure.
The original fix of setting mode to |
7ef00db
to
5067e75
Compare
I think I've adressed all your comments @nicoddemus, thanks for reviewing! 🙇 Github Actions were having issues yesterday, so I expect tests to pass today. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks @BeyondEvil!
The test failure will be fixed by #10788. |
5067e75
to
65fb513
Compare
Took the liberty of rebasing on |
Thanks, appreciate it! 🙏 Anything else needed from me at this time? |
Not from my POV, let's see if other maintainers want to chime in before getting this in. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No comment on whether this is a good idea or not (unfortunately don't have time to think it through ATM), but a couple of smaller comments.
src/_pytest/pathlib.py
Outdated
@@ -51,6 +51,8 @@ | |||
1921, # ERROR_CANT_RESOLVE_FILENAME - fix for broken symlink pointing to itself | |||
) | |||
|
|||
TMPDIR_FILE_MODE = int(os.getenv("PYTEST_TMPDIR_FILE_MODE", "0o700"), 8) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you specify base 8, then you can drop the 0o
prefix.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I can, but should I?
I felt it was clearer this way. But happy to remove it if you think it's better.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To me the 0o
means that the field doesn't specify a base, i.e. 123
is decimal, 0x123
would work, etc. I think the base 8 is good, but then we should drop the 0o
src/_pytest/pathlib.py
Outdated
@@ -51,6 +51,8 @@ | |||
1921, # ERROR_CANT_RESOLVE_FILENAME - fix for broken symlink pointing to itself | |||
) | |||
|
|||
TMPDIR_FILE_MODE = int(os.getenv("PYTEST_TMPDIR_FILE_MODE", "0o700"), 8) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You've chosen to grab the envvar once during import. Other alternatives are to grab it during initialization, and to grab it each time. Any particular reason you chose this way?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No particular reason. Preferably I would want to grab it in one place and then share it.
But I'm not versed enough in core to know where and how to do that.
Happy to take some guidance! 🙏
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
IMO (although again, I didn't think it through)
each-time > init > import
init > import because import is not great for this getenv, since then the user doesn't really get a chance to setenv from within python (when using pytest.main
etc).
each-time > init is more debatable, but each-time allows a user to setenv whenever and it would take effect -- is there any reason to disallow that?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
each-time > init is more debatable, but each-time allows a user to setenv whenever and it would take effect -- is there any reason to disallow that?
Not really, I think maximum flexibility is allowed here. I don't think it's our business to protect users from themselves. Especially since the default is more or less the most restrictive.
So would you recommend a small static method somewhere to get the user defined file mode? If so, where should I put such (static) method?
Something like:
def file_mode() -> int:
return int(os.getenv("PYTEST_TMPDIR_FILE_MODE", "700"), 8)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just a note that if we change the default (and remove the 0o
), we should update the docs too. 👍
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So would you recommend a small static method somewhere to get the user defined file mode
Yes. Though I'd call it tmpdir_file_mode
.
If so, where should I put such (static) method?
I'd say best place for it is src/_pytest/pathlib.py
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Updated accordingly @bluetech 🙇
fab22c9
to
c83aafe
Compare
@bluetech would you like to take a final review? |
I'm sorry to raise this so late in the process, but I'm quite strongly against this change. File permissions for the temporary directories were restricted for security reasons, and allowing that to be adjusted by an environment variable weakens those defenses considerably. Instead, I'd want to use an approach which is clearly visible in the source code, such as by adding a config option, or an explicit fixture for |
@BeyondEvil would you like to argue in favor of this change with @Zac-HD? |
No, lol. I'm fine with changing the implementation, but I think it's sort of semantics or security by obscurity. If I have access to modifying the environment variables, it's likely that I can change the test code as well. Meaning I can work around the "restriction" anyway: # Begin workaround
# See: https://github.com/pytest-dev/pytest/issues/10738
path.chmod(0o755)
for parent in path.parents:
try:
os.chmod(parent, 0o755)
except PermissionError:
continue
# End workaround That said, I have a limited understanding of all the use cases of pytest and in what environments it's running. Hence, I'm happy to implement a fixture instead. In my particular use case tho, I don't think a "chown" will work (as evident by the mask above I have to use to make it work). So I would suggest a file mode fixture, one that potentially could warn on too loose permissions. |
Let's close this then. Thanks a lot @BeyondEvil for the PR, sorry it did not ended up being included! 👍 |
Sorry, I don't follow the logic of closing this. 🤔 |
From:
I understand the environment variable implementation will be dropped, and potentially a new PR will be opened? |
Ah, I get it.
That confused me a little. But yes, I'll open a new PR with a fixture-based solution instead. |
Fixes: #10738