-
Notifications
You must be signed in to change notification settings - Fork 2.3k
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
fix: fix race condition on namespace package installation #9159
base: main
Are you sure you want to change the base?
fix: fix race condition on namespace package installation #9159
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.
Test is needed.
Can you give some pointers on how to achieve this then? As I see it I will have to manually create two wheels and then somehow force the race condition to happen. I'm not sure what a feasible way to do this would be, and if it's even safe to allow me to include wheels in the test suite. |
Testing the race condition might not be feasible but maybe testing the changed behavior if the path already exists? |
I can make a test that verifies that the path is hit, doesn't throw an error and that the output file is as expected, would that be enough? Right now the path is not being hit in any test, so it's still an improvement. However it requires me to include wheels. Is that okay? Or do I need to make a fixture that builds the wheels from some source data that you can approve? |
+ checking the
I suppose small wheels built specifically for the test are ok. We already have some wheels in tests/fixtures/distributions but I suppose you will not find two matching wheels that fulfill the requirements for the tests. |
I've just found a TOCTOU - two threads can hit the It's also a problem for creating the tests, since we can still get hit by the original race condition. Annoyingly we hit the race condition pretty often in my test case, since the wheels only have two files. I'm not sure what you would like here. I can add the test still, and make it succeed even if we hit the race condition. That way there issue is a bit more transparent. I can't even make a xfail test, since it will only fail sometimes. |
perhaps the suggestion here was a good idea all along |
Seems like it yes. I'll try it out and see what the performance hit is. |
This benchmarkes the original implementation versus an implementation that creates a temporary file and then uses Is this acceptable? I don't know how large a part of actual installation part this is. |
am I reading right that the units there are microseconds? I would find it hard to get excited over a few hundred microseconds (though you didn't say what it was that you are measuring. Is that per-file? per-wheel? something else? maybe a millisecond per file would be approaching noticeable...) |
Pull Request Check List
Resolves: #9158
There doesn't seem to be any tests that trigger the behavior. I tried raising an error instead of logging a warning and no test failed. Since it's a race condition and requires specific wheels to test, setting up a test wasn't trivial and I just left it in the current untested state. I tested it manually with the reproduction pyproject.toml in the linked issue and it worked fine though.
I think ideally we would raise a
FileAlreadyExistsError
and handle that accordingly, but sinceWheelDestination
is being used byinstaller
I couldn't see any nice way to do this.I'm not sure if it was better to copy in the hashing code from
installer.utils.copyfileobj_with_hashing
as I did or give it an temporaryBinaryIO
as destination that we would just discard.