From fd22210fa2381c3048654cc865c0a492d65bf517 Mon Sep 17 00:00:00 2001 From: Davis Vaughan Date: Fri, 3 Oct 2025 12:48:27 -0400 Subject: [PATCH 1/2] Warn once per session, not once every 8 hours within a session --- NEWS.md | 2 +- R/deprecate.R | 30 +++++++----------------------- R/expect.R | 2 +- R/verbosity.R | 2 +- man/deprecate_soft.Rd | 6 +++--- man/expect_deprecated.Rd | 2 +- man/verbosity.Rd | 2 +- tests/testthat/_snaps/deprecate.md | 6 ------ tests/testthat/test-deprecate.R | 9 +-------- tests/testthat/test-lifecycle.R | 8 ++++---- 10 files changed, 20 insertions(+), 49 deletions(-) diff --git a/NEWS.md b/NEWS.md index 05d1bfa..b4cd1d5 100644 --- a/NEWS.md +++ b/NEWS.md @@ -4,7 +4,7 @@ * `deprecate_soft()` and `deprecate_warn()` are faster thanks to some internal refactoring. -* `deprecate_soft()` now actually warns after every 8 hours. +* `deprecate_soft()` and `deprecate_warn()` now only warn once per session rather than attempting to warn once every 8 hours. * Improvements to `lint_lifecycle()` and `lint_tidyverse_lifecycle()` (@AshesITR): * Updated to support lintr >= 3.0.0 (#178). diff --git a/R/deprecate.R b/R/deprecate.R index 8888c90..2b6f5a8 100644 --- a/R/deprecate.R +++ b/R/deprecate.R @@ -14,7 +14,7 @@ #' #' * `deprecate_stop()` fails unconditionally. #' -#' Warnings are only issued once every 8 hours to avoid overwhelming +#' Warnings are only issued once per session to avoid overwhelming #' the user. Control with [`options(lifecycle_verbosity)`][verbosity]. #' #' @section Conditions: @@ -139,9 +139,9 @@ deprecate_soft <- function( } #' @rdname deprecate_soft -#' @param always If `FALSE`, the default, will warn every 8 hours. If +#' @param always If `FALSE`, the default, will warn once per session. If #' `TRUE`, will always warn in direct usages. Indirect usages keep -#' warning every 8 hours to avoid disrupting users who can't fix the +#' warning once per session to avoid disrupting users who can't fix the #' issue. Only use `always = TRUE` after at least one release with #' the default. #' @export @@ -229,8 +229,8 @@ deprecate_warn0 <- function( return() } - # Prevent warning from being displayed again - env_poke(deprecation_env, id, Sys.time()) + # Prevent warning from being displayed again this session + env_poke(deprecation_env, id, TRUE) footer <- function(...) { footer <- NULL @@ -266,7 +266,7 @@ deprecate_warn0 <- function( if (is_interactive()) { footer <- c( footer, - if (!always) silver("This warning is displayed once every 8 hours."), + if (!always) silver("This warning is displayed once per session."), silver( "Call `lifecycle::last_lifecycle_warnings()` to see where this warning was generated." ) @@ -458,21 +458,5 @@ from_testthat <- function(env) { needs_warning <- function(id, call = caller_env()) { check_string(id, call = call) - - last <- deprecation_env[[id]] - if (is_null(last)) { - return(TRUE) - } - - if (!inherits(last, "POSIXct")) { - abort( - "Expected `POSIXct` value in `needs_warning()`.", - .internal = TRUE - ) - } - - # Warn every 8 hours - # Must unclass to ensure we always compare in units of seconds, also much - # faster this way. - (unclass(Sys.time()) - unclass(last)) > (8 * 60 * 60) + is_null(deprecation_env[[id]]) } diff --git a/R/expect.R b/R/expect.R index 63224d7..0057330 100644 --- a/R/expect.R +++ b/R/expect.R @@ -25,7 +25,7 @@ #' @details #' `expect_deprecated()` sets the [lifecycle_verbosity][verbosity] #' option to `"warning"` to enforce deprecation warnings which are -#' otherwise only shown once every 8 hours. +#' otherwise only shown once per session. #' #' @export expect_deprecated <- function(expr, regexp = NULL, ...) { diff --git a/R/verbosity.R b/R/verbosity.R index b379d39..dbf61d0 100644 --- a/R/verbosity.R +++ b/R/verbosity.R @@ -14,7 +14,7 @@ #' `lifecycle_verbosity`. It can be set to: #' #' * `"quiet"` to suppress all deprecation messages. -#' * `"default"` or `NULL` to warn once every 8 hours. +#' * `"default"` or `NULL` to warn once per session. #' * `"warning"` to warn every time. #' * `"error"` to error instead of warning. #' diff --git a/man/deprecate_soft.Rd b/man/deprecate_soft.Rd index 804accb..c933121 100644 --- a/man/deprecate_soft.Rd +++ b/man/deprecate_soft.Rd @@ -71,9 +71,9 @@ These are only needed if you're calling \verb{deprecate_*()} from an internal helper, in which case you should forward \code{env = caller_env()} and \code{user_env = caller_env(2)}.} -\item{always}{If \code{FALSE}, the default, will warn every 8 hours. If +\item{always}{If \code{FALSE}, the default, will warn once per session. If \code{TRUE}, will always warn in direct usages. Indirect usages keep -warning every 8 hours to avoid disrupting users who can't fix the +warning once per session to avoid disrupting users who can't fix the issue. Only use \code{always = TRUE} after at least one release with the default.} } @@ -93,7 +93,7 @@ you don't control. \item \code{deprecate_stop()} fails unconditionally. } -Warnings are only issued once every 8 hours to avoid overwhelming +Warnings are only issued once per session to avoid overwhelming the user. Control with \code{\link[=verbosity]{options(lifecycle_verbosity)}}. } \section{Conditions}{ diff --git a/man/expect_deprecated.Rd b/man/expect_deprecated.Rd index 9987a1c..e762a8d 100644 --- a/man/expect_deprecated.Rd +++ b/man/expect_deprecated.Rd @@ -42,5 +42,5 @@ deprecation warning, set the \code{lifecycle_verbosity} option to \details{ \code{expect_deprecated()} sets the \link[=verbosity]{lifecycle_verbosity} option to \code{"warning"} to enforce deprecation warnings which are -otherwise only shown once every 8 hours. +otherwise only shown once per session. } diff --git a/man/verbosity.Rd b/man/verbosity.Rd index aaee23b..e78b3c6 100644 --- a/man/verbosity.Rd +++ b/man/verbosity.Rd @@ -16,7 +16,7 @@ You can control the level of verbosity with the global option \code{lifecycle_verbosity}. It can be set to: \itemize{ \item \code{"quiet"} to suppress all deprecation messages. -\item \code{"default"} or \code{NULL} to warn once every 8 hours. +\item \code{"default"} or \code{NULL} to warn once per session. \item \code{"warning"} to warn every time. \item \code{"error"} to error instead of warning. } diff --git a/tests/testthat/_snaps/deprecate.md b/tests/testthat/_snaps/deprecate.md index 9e62844..f696ff8 100644 --- a/tests/testthat/_snaps/deprecate.md +++ b/tests/testthat/_snaps/deprecate.md @@ -194,9 +194,3 @@ Error: ! `id` must be a single string, not a number. ---- - - Expected `POSIXct` value in `needs_warning()`. - i This is an internal error that was detected in the lifecycle package. - Please report it at with a reprex () and the full backtrace. - diff --git a/tests/testthat/test-deprecate.R b/tests/testthat/test-deprecate.R index 5d974ca..c8c24f1 100644 --- a/tests/testthat/test-deprecate.R +++ b/tests/testthat/test-deprecate.R @@ -228,13 +228,6 @@ test_that("needs_warning works as expected", { expect_snapshot(needs_warning(1), error = TRUE) expect_true(needs_warning("test")) - env_poke(deprecation_env, "test", Sys.time()) + env_poke(deprecation_env, "test", TRUE) expect_false(needs_warning("test")) - - # More than 8 hours - env_poke(deprecation_env, "test", Sys.time() - 9 * 60 * 60) - expect_true(needs_warning("test")) - - env_poke(deprecation_env, "test", "x") - expect_snapshot_error(needs_warning("test")) }) diff --git a/tests/testthat/test-lifecycle.R b/tests/testthat/test-lifecycle.R index d9d56d7..8a3efff 100644 --- a/tests/testthat/test-lifecycle.R +++ b/tests/testthat/test-lifecycle.R @@ -61,20 +61,20 @@ test_that("deprecation warnings are not displayed again", { local_interactive() wrn <- catch_cnd( - deprecate_warn("1.0.0", "foo()", id = "once-every-8-hours-note"), + deprecate_warn("1.0.0", "foo()", id = "once-per-session-note"), classes = "warning" ) footer <- cnd_footer(wrn) - expect_true(is_character(footer) && any(grepl("once every 8 hours", footer))) + expect_true(is_character(footer) && any(grepl("once per session", footer))) local_options(lifecycle_verbosity = "warning") wrn <- catch_cnd(deprecate_warn( "1.0.0", "foo()", - id = "once-every-8-hours-no-note" + id = "once-per-session-no-note" )) - expect_false(grepl("once every 8 hours", conditionMessage(wrn))) + expect_false(grepl("once per session", conditionMessage(wrn))) }) test_that("the topenv of the empty env is not the global env", { From 3bc077cbe930295b2f8b02a4b2c676d73bda175d Mon Sep 17 00:00:00 2001 From: Davis Vaughan Date: Fri, 3 Oct 2025 13:18:05 -0400 Subject: [PATCH 2/2] Update NEWS.md Co-authored-by: Hadley Wickham --- NEWS.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/NEWS.md b/NEWS.md index b4cd1d5..e80ac1a 100644 --- a/NEWS.md +++ b/NEWS.md @@ -4,7 +4,7 @@ * `deprecate_soft()` and `deprecate_warn()` are faster thanks to some internal refactoring. -* `deprecate_soft()` and `deprecate_warn()` now only warn once per session rather than attempting to warn once every 8 hours. +* `deprecate_soft()` and `deprecate_warn()` now only warn once per session rather than attempting to warn once every 8 hours. This never actually worked. * Improvements to `lint_lifecycle()` and `lint_tidyverse_lifecycle()` (@AshesITR): * Updated to support lintr >= 3.0.0 (#178).