diff --git a/newsfragments/3403.deprecated.rst b/newsfragments/3403.deprecated.rst new file mode 100644 index 000000000..4efb61bc7 --- /dev/null +++ b/newsfragments/3403.deprecated.rst @@ -0,0 +1,6 @@ +Trying to use absolute deadlines on a `trio.CancelScope` constructed +with a relative deadline now raises, after being deprecated since Trio +0.27.0. + +You can still set absolute deadlines or relative deadlines to change +the kind of `trio.CancelScope` you have. diff --git a/src/trio/_core/_run.py b/src/trio/_core/_run.py index 2d649d291..ffd839406 100644 --- a/src/trio/_core/_run.py +++ b/src/trio/_core/_run.py @@ -808,29 +808,17 @@ def deadline(self) -> float: """ if self._relative_deadline != inf: assert self._deadline == inf - warnings.warn( - DeprecationWarning( - "unentered relative cancel scope does not have an absolute deadline. Use `.relative_deadline`", - ), - stacklevel=2, + raise RuntimeError( + "Unentered relative cancel scope does not have an absolute deadline." ) - return current_time() + self._relative_deadline return self._deadline @deadline.setter def deadline(self, new_deadline: float) -> None: if isnan(new_deadline): raise ValueError("deadline must not be NaN") - if self._relative_deadline != inf: - assert self._deadline == inf - warnings.warn( - DeprecationWarning( - "unentered relative cancel scope does not have an absolute deadline. Transforming into an absolute cancel scope. First set `.relative_deadline = math.inf` if you do want an absolute cancel scope.", - ), - stacklevel=2, - ) - self._relative_deadline = inf with self._might_change_registered_deadline(): + self._relative_deadline = inf self._deadline = float(new_deadline) @property @@ -852,7 +840,7 @@ def relative_deadline(self) -> float: elif self._deadline != inf: assert self._relative_deadline == inf raise RuntimeError( - "unentered non-relative cancel scope does not have a relative deadline", + "Unentered non-relative cancel scope does not have a relative deadline", ) return self._relative_deadline @@ -865,13 +853,10 @@ def relative_deadline(self, new_relative_deadline: float) -> None: if self._has_been_entered: with self._might_change_registered_deadline(): self._deadline = current_time() + float(new_relative_deadline) - elif self._deadline != inf: - assert self._relative_deadline == inf - raise RuntimeError( - "unentered non-relative cancel scope does not have a relative deadline", - ) else: - self._relative_deadline = new_relative_deadline + with self._might_change_registered_deadline(): + self._deadline = inf + self._relative_deadline = new_relative_deadline @property def is_relative(self) -> bool | None: diff --git a/src/trio/_tests/test_timeouts.py b/src/trio/_tests/test_timeouts.py index ff62a0708..3eb545002 100644 --- a/src/trio/_tests/test_timeouts.py +++ b/src/trio/_tests/test_timeouts.py @@ -243,34 +243,31 @@ async def test_timeout_deadline_on_entry(mock_clock: _core.MockClock) -> None: assert rcs is cs -async def test_invalid_access_unentered(mock_clock: _core.MockClock) -> None: +def test_invalid_access_unentered() -> None: cs = move_on_after(5) - mock_clock.jump(3) - start = _core.current_time() - match_str = "^unentered relative cancel scope does not have an absolute deadline" - with pytest.warns(DeprecationWarning, match=match_str): - assert cs.deadline == start + 5 - mock_clock.jump(1) - # this is hella sketchy, but they *have* been warned - with pytest.warns(DeprecationWarning, match=match_str): - assert cs.deadline == start + 6 - - with pytest.warns(DeprecationWarning, match=match_str): - cs.deadline = 7 - # now transformed into absolute + match_str = "^Unentered relative cancel scope does not have an absolute deadline" + with pytest.raises(RuntimeError, match=match_str): + assert cs.deadline + with pytest.raises(RuntimeError, match=match_str): + cs.deadline += 5 + + # switch from relative to absolute + cs.deadline = 7 assert cs.deadline == 7 assert not cs.is_relative - cs = move_on_at(5) - match_str = ( - "^unentered non-relative cancel scope does not have a relative deadline$" + "^Unentered non-relative cancel scope does not have a relative deadline$" ) with pytest.raises(RuntimeError, match=match_str): assert cs.relative_deadline with pytest.raises(RuntimeError, match=match_str): - cs.relative_deadline = 7 + cs.relative_deadline += 5 + + cs.relative_deadline = 9 + assert cs.relative_deadline == 9 + assert cs.is_relative @pytest.mark.xfail(reason="not implemented")