From 75725a8148d647b5524d1381758e6c23f586a99e Mon Sep 17 00:00:00 2001 From: Joshua Oreman Date: Tue, 5 Feb 2019 13:18:58 -0800 Subject: [PATCH 1/2] Cancel a cancel scope upon entry if its deadline is in the past Fixes #320. Now that #901 is implemented, the concerns discussed in #835 don't apply. --- newsfragments/320.misc.rst | 4 ++++ trio/_core/_run.py | 2 ++ trio/_core/tests/test_run.py | 15 ++++++++------- trio/_core/tests/tutil.py | 2 +- 4 files changed, 15 insertions(+), 8 deletions(-) create mode 100644 newsfragments/320.misc.rst diff --git a/newsfragments/320.misc.rst b/newsfragments/320.misc.rst new file mode 100644 index 0000000000..3f799b9eb0 --- /dev/null +++ b/newsfragments/320.misc.rst @@ -0,0 +1,4 @@ +Entering a cancel scope whose deadline is in the past now immediately +cancels it, so :exc:`~trio.Cancelled` will be raised by the first +checkpoint in the cancel scope rather than the second one. +This also affects constructs like ``with trio.move_on_after(0):``. diff --git a/trio/_core/_run.py b/trio/_core/_run.py index e00295a1ca..6faeced12f 100644 --- a/trio/_core/_run.py +++ b/trio/_core/_run.py @@ -201,6 +201,8 @@ def __enter__(self): ) self._scope_task = task self.cancelled_caught = False + if current_time() >= self._deadline: + self.cancel_called = True with self._might_change_effective_deadline(): self._add_task(task) return self diff --git a/trio/_core/tests/test_run.py b/trio/_core/tests/test_run.py index e03f6da03a..a6ed154ab0 100644 --- a/trio/_core/tests/test_run.py +++ b/trio/_core/tests/test_run.py @@ -407,12 +407,13 @@ async def main(): _core.run(main, instruments=[r1, r2]) - # It sleeps 5 times, so it runs 6 times + # It sleeps 5 times, so it runs 6 times. Note that checkpoint() + # reschedules the task immediately upon yielding, before the + # after_task_step event fires. expected = ( - [("before_run",)] + - 6 * [("schedule", task), - ("before", task), - ("after", task)] + [("after_run",)] + [("before_run",), ("schedule", task)] + + [("before", task), ("schedule", task), ("after", task)] * 5 + + [("before", task), ("after", task), ("after_run",)] ) assert len(r1.record) > len(r2.record) > len(r3.record) assert r1.record == r2.record + r3.record @@ -444,15 +445,15 @@ async def main(): ("schedule", tasks["t2"]), { ("before", tasks["t1"]), + ("schedule", tasks["t1"]), ("after", tasks["t1"]), ("before", tasks["t2"]), + ("schedule", tasks["t2"]), ("after", tasks["t2"]) }, { - ("schedule", tasks["t1"]), ("before", tasks["t1"]), ("after", tasks["t1"]), - ("schedule", tasks["t2"]), ("before", tasks["t2"]), ("after", tasks["t2"]) }, diff --git a/trio/_core/tests/tutil.py b/trio/_core/tests/tutil.py index dc93794bef..d5d22d525e 100644 --- a/trio/_core/tests/tutil.py +++ b/trio/_core/tests/tutil.py @@ -52,7 +52,7 @@ def gc_collect_harder(): # template is like: -# [1, {2.1, 2.2}, 3] -> matches [1, 2.1, 3] or [1, 2.2, 3] +# [1, {2.1, 2.2}, 3] -> matches [1, 2.1, 2.2, 3] or [1, 2.2, 2.1, 3] def check_sequence_matches(seq, template): i = 0 for pattern in template: From 0f90296fe4617e8d4565553cec47f3a630bc9670 Mon Sep 17 00:00:00 2001 From: Joshua Oreman Date: Tue, 5 Feb 2019 13:42:43 -0800 Subject: [PATCH 2/2] yapf --- trio/_core/tests/test_run.py | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/trio/_core/tests/test_run.py b/trio/_core/tests/test_run.py index a6ed154ab0..c6d3298bcd 100644 --- a/trio/_core/tests/test_run.py +++ b/trio/_core/tests/test_run.py @@ -411,9 +411,14 @@ async def main(): # reschedules the task immediately upon yielding, before the # after_task_step event fires. expected = ( - [("before_run",), ("schedule", task)] + - [("before", task), ("schedule", task), ("after", task)] * 5 + - [("before", task), ("after", task), ("after_run",)] + [("before_run",), + ("schedule", task)] + + [("before", task), + ("schedule", task), + ("after", task)] * 5 + [ + ("before", task), + ("after", task), ("after_run",) + ] ) assert len(r1.record) > len(r2.record) > len(r3.record) assert r1.record == r2.record + r3.record