diff --git a/NEWS.md b/NEWS.md index f02f424..2a7f6ef 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,6 +1,6 @@ # lifecycle (development version) -* The condition generated by `signal_stage()` no longer directly exposes fields such as `cnd$package` and `cnd$function_nm` (#195). +* `signal_stage()` is now deprecated. This was never hooked up to anything, and our original ideas for it never panned out, so the overhead it entails no longer feels worth it. * `deprecate_soft()` and `deprecate_warn()` are faster thanks to some internal refactoring (#191, #194, #195, #201). diff --git a/R/deprecate.R b/R/deprecate.R index 1c9910b..fd3e17c 100644 --- a/R/deprecate.R +++ b/R/deprecate.R @@ -122,8 +122,6 @@ deprecate_soft <- function( ) ) - signal_stage("deprecated", what) - verbosity <- lifecycle_verbosity() direct <- is_direct(user_env) @@ -180,8 +178,6 @@ deprecate_warn <- function( ) ) - signal_stage("deprecated", what) - verbosity <- lifecycle_verbosity() invisible(switch( @@ -223,7 +219,6 @@ deprecate_stop <- function( env, signaller = "deprecate_stop" ) - signal_stage("deprecated", what) deprecate_stop0(msg) } @@ -238,6 +233,12 @@ deprecate_warn0 <- function( trace_env = caller_env(), user_env = caller_env(2) ) { + # declare( + # params(msg = lazy) + # ) + + # `msg` is passed lazily for performance reasons! Avoid evaluating it before + # checking if we can early exit using the `id`. id <- id %||% paste_line(msg) if (!always && !needs_warning(id, call = call)) { return() diff --git a/R/signal.R b/R/deprecated-signal.R similarity index 59% rename from R/signal.R rename to R/deprecated-signal.R index d26029f..44d32a0 100644 --- a/R/signal.R +++ b/R/deprecated-signal.R @@ -1,29 +1,45 @@ -#' Signal other experimental or superseded features +#' Deprecated functions for signalling lifecycle stages #' #' @description -#' `r badge("experimental")` -#' -#' `signal_stage()` allows you to signal life cycle stages other than -#' deprecation (for which you should use [deprecate_warn()] and friends). -#' There is no behaviour associated with this signal, but in the future -#' we will provide tools to log and report on usage of experimental and -#' superseded functions. -#' -#' @param stage Life cycle stage, either "experimental" or "superseded". -#' @param what String describing what feature the stage applies too, using -#' the same syntax as [deprecate_warn()]. -#' @param with An optional string giving a recommended replacement for -#' a superseded function. -#' @param env Environment used to determine where `signal_stage()` -#' was called, used to determine the package name). +#' `r badge("deprecated")` +#' @name deprecated-signallers +#' @keywords internal +NULL + +#' @rdname deprecated-signallers #' @export -#' @examples -#' foofy <- function(x, y, z) { -#' signal_stage("experimental", "foofy()") -#' x + y / z -#' } -#' foofy(1, 2, 3) signal_stage <- function(stage, what, with = NULL, env = caller_env()) { + deprecate_soft( + "1.1.0", + what = "signal_stage()", + id = "lifecycle_signal_stage" + ) + signal_stage_impl(stage, what, with, env) +} + +#' @rdname deprecated-signallers +#' @export +signal_experimental <- function(when, what, env = caller_env()) { + deprecate_soft( + "1.1.0", + what = "signal_experimental()", + id = "lifecycle_signal_experimental" + ) + signal_stage_impl("experimental", what, with = NULL, env = env) +} + +#' @rdname deprecated-signallers +#' @export +signal_superseded <- function(when, what, env = caller_env()) { + deprecate_soft( + "1.1.0", + what = "signal_superseded()", + id = "lifecycle_signal_superseded" + ) + signal_stage_impl("superseded", what, with = NULL, env = env) +} + +signal_stage_impl <- function(stage, what, with, env) { stage <- arg_match0(stage, c("experimental", "superseded", "deprecated")) cnd <- new_lifecycle_stage_cnd(stage, what, with, env) cnd_signal(cnd) @@ -35,8 +51,6 @@ new_lifecycle_stage_cnd <- function(stage, what, with, env) { out } -# We could export this if packages have a need to capture a lifecycle -# condition and manipulate this data to generate their own custom message lifecycle_stage_cnd_data <- function(cnd) { stage <- cnd$stage what <- cnd$what @@ -77,19 +91,3 @@ lifecycle_stage_cnd_data <- function(cnd) { conditionMessage.lifecycle_stage <- function(c) { lifecycle_stage_cnd_data(c)$message } - -#' Deprecated functions for signalling experimental and lifecycle stages -#' -#' @description -#' `r badge("deprecated")` -#' Please use [signal_stage()] instead -#' @keywords internal -#' @export -signal_experimental <- function(when, what, env = caller_env()) { - signal_stage("experimental", what, env = env) -} -#' @rdname signal_experimental -#' @export -signal_superseded <- function(when, what, env = caller_env()) { - signal_stage("superseded", what, env = env) -} diff --git a/man/signal_experimental.Rd b/man/deprecated-signallers.Rd similarity index 62% rename from man/signal_experimental.Rd rename to man/deprecated-signallers.Rd index f539f78..ae0ecee 100644 --- a/man/signal_experimental.Rd +++ b/man/deprecated-signallers.Rd @@ -1,16 +1,19 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in R/signal.R -\name{signal_experimental} +% Please edit documentation in R/deprecated-signal.R +\name{deprecated-signallers} +\alias{deprecated-signallers} +\alias{signal_stage} \alias{signal_experimental} \alias{signal_superseded} -\title{Deprecated functions for signalling experimental and lifecycle stages} +\title{Deprecated functions for signalling lifecycle stages} \usage{ +signal_stage(stage, what, with = NULL, env = caller_env()) + signal_experimental(when, what, env = caller_env()) signal_superseded(when, what, env = caller_env()) } \description{ \ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#deprecated}{\figure{lifecycle-deprecated.svg}{options: alt='[Deprecated]'}}}{\strong{[Deprecated]}} -Please use \code{\link[=signal_stage]{signal_stage()}} instead } \keyword{internal} diff --git a/man/signal_stage.Rd b/man/signal_stage.Rd deleted file mode 100644 index 404aae3..0000000 --- a/man/signal_stage.Rd +++ /dev/null @@ -1,36 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/signal.R -\name{signal_stage} -\alias{signal_stage} -\title{Signal other experimental or superseded features} -\usage{ -signal_stage(stage, what, with = NULL, env = caller_env()) -} -\arguments{ -\item{stage}{Life cycle stage, either "experimental" or "superseded".} - -\item{what}{String describing what feature the stage applies too, using -the same syntax as \code{\link[=deprecate_warn]{deprecate_warn()}}.} - -\item{with}{An optional string giving a recommended replacement for -a superseded function.} - -\item{env}{Environment used to determine where \code{signal_stage()} -was called, used to determine the package name).} -} -\description{ -\ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#experimental}{\figure{lifecycle-experimental.svg}{options: alt='[Experimental]'}}}{\strong{[Experimental]}} - -\code{signal_stage()} allows you to signal life cycle stages other than -deprecation (for which you should use \code{\link[=deprecate_warn]{deprecate_warn()}} and friends). -There is no behaviour associated with this signal, but in the future -we will provide tools to log and report on usage of experimental and -superseded functions. -} -\examples{ -foofy <- function(x, y, z) { - signal_stage("experimental", "foofy()") - x + y / z -} -foofy(1, 2, 3) -} diff --git a/tests/testthat/_snaps/deprecate.md b/tests/testthat/_snaps/deprecate.md index d1bc723..24eacbc 100644 --- a/tests/testthat/_snaps/deprecate.md +++ b/tests/testthat/_snaps/deprecate.md @@ -189,14 +189,14 @@ # lifecycle message is never generated when an `id` is supplied and we've already warned Code - deprecate_soft(when = stop("when"), what = I("needed by signal_stage()"), with = stop( - "with"), details = stop("details"), env = stop("env"), id = "test") + deprecate_soft(when = stop("when"), what = stop("what"), with = stop("with"), + details = stop("details"), env = stop("env"), id = "test") --- Code - deprecate_warn(when = stop("when"), what = I("needed by signal_stage()"), with = stop( - "with"), details = stop("details"), env = stop("env"), id = "test") + deprecate_warn(when = stop("when"), what = stop("what"), with = stop("with"), + details = stop("details"), env = stop("env"), id = "test") # needs_warning works as expected diff --git a/tests/testthat/_snaps/signal.md b/tests/testthat/_snaps/deprecated-signal.md similarity index 58% rename from tests/testthat/_snaps/signal.md rename to tests/testthat/_snaps/deprecated-signal.md index 2fe244c..f1b5e3c 100644 --- a/tests/testthat/_snaps/signal.md +++ b/tests/testthat/_snaps/deprecated-signal.md @@ -22,3 +22,27 @@ +# `signal_stage()` and friends are deprecated + + Code + signal_stage("superseded", "foo()", "bar()") + Condition + Warning: + `signal_stage()` was deprecated in lifecycle 1.1.0. + +--- + + Code + signal_experimental("1.1.0", "foo()") + Condition + Warning: + `signal_experimental()` was deprecated in lifecycle 1.1.0. + +--- + + Code + signal_superseded("1.1.0", "foo()") + Condition + Warning: + `signal_superseded()` was deprecated in lifecycle 1.1.0. + diff --git a/tests/testthat/_snaps/lifecycle.md b/tests/testthat/_snaps/lifecycle.md new file mode 100644 index 0000000..6518108 --- /dev/null +++ b/tests/testthat/_snaps/lifecycle.md @@ -0,0 +1,31 @@ +# deprecation warnings are not displayed again + + Code + wrn + Output + + Warning: + `foo()` was deprecated in lifecycle 1.0.0. + This warning is displayed once per session. + Call `lifecycle::last_lifecycle_warnings()` to see where this warning was generated. + +--- + + Code + wrn + Output + + Warning: + `foo()` was deprecated in lifecycle 1.0.0. + Call `lifecycle::last_lifecycle_warnings()` to see where this warning was generated. + +--- + + Code + wrn + Output + + Warning: + `foo()` was deprecated in lifecycle 1.0.0. + Call `lifecycle::last_lifecycle_warnings()` to see where this warning was generated. + diff --git a/tests/testthat/test-deprecate.R b/tests/testthat/test-deprecate.R index 410a82f..aa9f6f1 100644 --- a/tests/testthat/test-deprecate.R +++ b/tests/testthat/test-deprecate.R @@ -229,7 +229,7 @@ test_that("lifecycle message is never generated when an `id` is supplied and we' expect_snapshot({ deprecate_soft( when = stop("when"), - what = I("needed by signal_stage()"), + what = stop("what"), with = stop("with"), details = stop("details"), env = stop("env"), @@ -239,7 +239,7 @@ test_that("lifecycle message is never generated when an `id` is supplied and we' expect_snapshot({ deprecate_warn( when = stop("when"), - what = I("needed by signal_stage()"), + what = stop("what"), with = stop("with"), details = stop("details"), env = stop("env"), diff --git a/tests/testthat/test-signal.R b/tests/testthat/test-deprecated-signal.R similarity index 67% rename from tests/testthat/test-signal.R rename to tests/testthat/test-deprecated-signal.R index 7c4542c..3b21e21 100644 --- a/tests/testthat/test-signal.R +++ b/tests/testthat/test-deprecated-signal.R @@ -1,4 +1,6 @@ test_that("signal stage captures desired data", { + local_options(lifecycle_verbosity = "quiet") + f <- function() { signal_stage("experimental", "pkg::foo(bar = 'baz')") } @@ -13,6 +15,8 @@ test_that("signal stage captures desired data", { }) test_that("signal generates user friendly message", { + local_options(lifecycle_verbosity = "quiet") + expect_snapshot({ (expect_condition(signal_stage("experimental", "foo()"))) (expect_condition(signal_stage("superseded", "foo(bar)"))) @@ -20,8 +24,22 @@ test_that("signal generates user friendly message", { }) test_that("signal_stage supports with", { + local_options(lifecycle_verbosity = "quiet") + expect_snapshot({ (expect_condition(signal_stage("superseded", "foo()", "bar()"))) (expect_condition(signal_stage("superseded", "foo(bar=)", "foo(baz=)"))) }) }) + +test_that("`signal_stage()` and friends are deprecated", { + expect_snapshot({ + signal_stage("superseded", "foo()", "bar()") + }) + expect_snapshot({ + signal_experimental("1.1.0", "foo()") + }) + expect_snapshot({ + signal_superseded("1.1.0", "foo()") + }) +}) diff --git a/tests/testthat/test-lifecycle.R b/tests/testthat/test-lifecycle.R index 8a3efff..64fc0ca 100644 --- a/tests/testthat/test-lifecycle.R +++ b/tests/testthat/test-lifecycle.R @@ -57,24 +57,41 @@ test_that("soft-deprecation warnings are issued when called from child of global }) test_that("deprecation warnings are not displayed again", { - local_options(lifecycle_verbosity = NULL) local_interactive() + on.exit(env_unbind(deprecation_env, c("once-per-session", "unconditional"))) - wrn <- catch_cnd( - 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 per session", footer))) + # With `"default"` - warning only shown once per session + local_options(lifecycle_verbosity = "default") + + retired <- function() { + deprecate_warn("1.0.0", "foo()", id = "once-per-session") + } + + # First and only time shows "once per session" message + wrn <- catch_cnd(retired(), classes = "lifecycle_warning_deprecated") + expect_s3_class(wrn, "lifecycle_warning_deprecated") + expect_snapshot(wrn) + + # Calling it again gives no warning at all + wrn <- catch_cnd(retired(), classes = "lifecycle_warning_deprecated") + expect_null(wrn) + # With `"warning"` - warning shows unconditionally local_options(lifecycle_verbosity = "warning") - wrn <- catch_cnd(deprecate_warn( - "1.0.0", - "foo()", - id = "once-per-session-no-note" - )) - expect_false(grepl("once per session", conditionMessage(wrn))) + retired <- function() { + deprecate_warn("1.0.0", "foo()", id = "unconditional") + } + + # First time doesn't show "once per session" message because we always warn + wrn <- catch_cnd(retired(), classes = "lifecycle_warning_deprecated") + expect_s3_class(wrn, "lifecycle_warning_deprecated") + expect_snapshot(wrn) + + # Calling it again shows the warning again, again without "once per session" + wrn <- catch_cnd(retired(), classes = "lifecycle_warning_deprecated") + expect_s3_class(wrn, "lifecycle_warning_deprecated") + expect_snapshot(wrn) }) test_that("the topenv of the empty env is not the global env", { diff --git a/vignettes/communicate.Rmd b/vignettes/communicate.Rmd index 68cde99..cbce50c 100644 --- a/vignettes/communicate.Rmd +++ b/vignettes/communicate.Rmd @@ -233,16 +233,6 @@ Then describe why the function was superseded, and what the recommended alternat The rest of the documentation can stay the same. -If you're willing to live on the bleeding edge of lifecycle, add a call to the experimental `signal_stage()`: - -```{r} -gather <- function(data, key = "key", value = "value", ...) { - lifecycle::signal_stage("superseded", "gather()") -} -``` - -This signal isn't currently hooked up to any behaviour, but we plan to provide logging and analysis tools in a future release. - ### Mark function as experimental To advertise that a function is experimental and the interface might change in the future, first add an experimental badge to the description: @@ -254,16 +244,6 @@ To advertise that a function is experimental and the interface might change in t If the function is very experimental, you might want to add `@keywords internal` too. -If you're willing to try an experimental lifecycle feature, add a call to `signal_stage()` in the body: - -```{r} -cool_function <- function() { - lifecycle::signal_stage("experimental", "cool_function()") -} -``` - -This signal isn't currently hooked up to any behaviour, but we plan to provide logging and analysis tools in a future release. - ## Arguments ### Deprecate an argument, keeping the existing default