-
-
Notifications
You must be signed in to change notification settings - Fork 25
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
Deterministic scheduling via Hypothesis #73
Conversation
7f78d30
to
62b33b4
Compare
Codecov Report
@@ Coverage Diff @@
## master #73 +/- ##
==========================================
+ Coverage 99.56% 99.78% +0.22%
==========================================
Files 19 19
Lines 461 476 +15
Branches 43 41 -2
==========================================
+ Hits 459 475 +16
+ Misses 2 1 -1
|
The other Trio part is python-trio/trio#840 which is merged and should be released as part of 0.10.0 any moment now. |
37db51c
to
2becc5d
Compare
2becc5d
to
3775f98
Compare
Ping @njsmith, we've just released the Hypothesis end of this 😃 |
CC @pquentin, @touilleMan ? |
Sorry, I'm not familiar with Hypothesis. Is there a way to test manually that this integration between pytest-trio and Hypothesis is now working? eg. a test somewhere that is only deterministic after those register_random PRs. Thanks! |
Hmm, I don't actually know the Trio internals well enough to say! We would need a test that depends on the ordering of a batch of tasks. Alternatively it would be easy but not that meaningful to test that the random instance in question is in fact seeded by Hypothesis... |
I guess what I'd do is write some code like: async def scheduler_trace():
trace = []
async def tracer(name):
for i in range(10):
trace.append([(name, i)])
await trio.sleep(0)
async with trio.open_nursery() as nursery:
for i in range(5):
nursery.start_soon(tracer, i)
return trace And then run this code 3-4 times and check that |
I did not manage to make this work with hypothesis, and in fact I have not managed to prove that import trio
async def scheduler_trace():
trace = []
async def tracer(name):
for i in range(10):
trace.append([(name, i)])
await trio.sleep(0)
async with trio.open_nursery() as nursery:
for i in range(5):
nursery.start_soon(tracer, i)
print(trace)
async def run5():
for _ in range(5):
await scheduler_trace()
if __name__ == "__main__":
print(trio.__version__)
trio.run(run5) |
...huh. I have no idea why that would be. Sounds like you were absolutely right to ask for a test here! I probably would have let it slide, shows what I know... |
Oh you know what, I bet it's because when cancel scopes put themselves into the global deadline list, it's sorted by deadline... but if two scopes have the exact same deadline, then huh, guaranteeing deterministic scheduling in the presence of multiple tasks with identical timeouts seems pretty non-trivial! |
It goes deeper - Unfortunately I don't have the time to take this on at the moment, but I could open an issue to make scheduling deterministic-except-for-shuffling if you agree this would be useful? |
I'm a bit wary of adding complexity to the core loop for this, for maintenance and speed reasons, but the use case does make sense, so I guess it depends on how unobtrusive we can make it. I guess one idea would be to assign each |
OK, trio 0.11.0 is out. Let's cycle this pull request. |
@Zac-HD There's a yapf formatting issue left, but otherwise CI is now passing! Oh, and it would be nice to require trio >= 0.11.0. |
To support determinism under Hypothesis.
a55596f
to
414ec14
Compare
And it's passing 🚀:sparkles: |
This is reeeally cool, thanks a lot @Zac-HD ;-) |
Thank you for your |
I'm pretty pleased with the end result, but also happy to be finished! It's lovely to work with projects that care so much about both correctness and usability 😄 |
Related to HypothesisWorks/hypothesis#1709 and python-trio/trio#239.
And now that HypothesisWorks/hypothesis#1741 has been released, this actually works and is ready to merge 🎉