diff --git a/NAMESPACE b/NAMESPACE index 20fd619..f4ab3e5 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -1,6 +1,5 @@ # Generated by roxygen2: do not edit by hand -S3method(conditionMessage,lifecycle_stage) S3method(print,lifecycle_warnings) export(badge) export(deprecate_soft) diff --git a/NEWS.md b/NEWS.md index 2a7f6ef..d2d9eaa 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,6 +1,6 @@ # lifecycle (development version) -* `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. +* `signal_stage()` no longer does anything, and is now purely a way to express intent at the call site of whether a function is superseded or experimental (#203). * `deprecate_soft()` and `deprecate_warn()` are faster thanks to some internal refactoring (#191, #194, #195, #201). diff --git a/R/deprecated-signal.R b/R/deprecated-signal.R deleted file mode 100644 index 44d32a0..0000000 --- a/R/deprecated-signal.R +++ /dev/null @@ -1,93 +0,0 @@ -#' Deprecated functions for signalling lifecycle stages -#' -#' @description -#' `r badge("deprecated")` -#' @name deprecated-signallers -#' @keywords internal -NULL - -#' @rdname deprecated-signallers -#' @export -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) -} - -new_lifecycle_stage_cnd <- function(stage, what, with, env) { - out <- list(stage = stage, what = what, with = with, env = env) - class(out) <- c("lifecycle_stage", "condition") - out -} - -lifecycle_stage_cnd_data <- function(cnd) { - stage <- cnd$stage - what <- cnd$what - with <- cnd$with - env <- cnd$env - - what <- spec(what, env = env) - - if (is_null(what$arg)) { - message <- sprintf("%s() is %s", what$fn, stage) - } else { - message <- sprintf("%s(%s) is %s", what$fn, what$arg, stage) - } - - if (!is_null(with)) { - with <- spec(with, NULL, "signal_stage") - message <- paste0(message, "\n", lifecycle_message_with(with, what)) - } - - list( - message = message, - stage = stage, - package = what$pkg, - function_nm = what$fn, - argument = what$arg, - reason = what$reason - ) -} - -# `cnd_signal()` calls `signalCondition()`, which currently eagerly evaluates -# `conditionMessage()`, meaning that right now we don't save any time by making -# the message generation lazy. But we are hoping to fix this in base R in the -# future, since the message is only used in the error path and could be -# generated on demand at that point. -# https://github.com/wch/r-source/blob/f200c30b1a20dfa9394d7facff616e9cb2a42c6d/src/library/base/R/conditions.R#L157-L163 -# https://github.com/wch/r-source/blob/f200c30b1a20dfa9394d7facff616e9cb2a42c6d/src/main/errors.c#L1904-L1909 -#' @export -conditionMessage.lifecycle_stage <- function(c) { - lifecycle_stage_cnd_data(c)$message -} diff --git a/R/signal.R b/R/signal.R new file mode 100644 index 0000000..cb2be1f --- /dev/null +++ b/R/signal.R @@ -0,0 +1,64 @@ +#' Signal other experimental or superseded features +#' +#' @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, it is currently purely a way to +#' express intent at the call site. In the future, we hope to replace this with +#' a standardized call to `base::declare()`. +#' +#' @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 `r badge("deprecated")` +#' +#' @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 = deprecated()) { + # Does nothing + invisible() +} + +#' Deprecated functions for signalling lifecycle stages +#' +#' @description +#' `r badge("deprecated")` +#' @name deprecated-signallers +#' @keywords internal +NULL + +#' @rdname deprecated-signallers +#' @export +signal_experimental <- function(when, what, env = caller_env()) { + deprecate_soft( + "1.1.0", + what = "signal_experimental()", + with = "signal_stage()", + id = "lifecycle_signal_experimental" + ) + signal_stage("experimental", what) +} + +#' @rdname deprecated-signallers +#' @export +signal_superseded <- function(when, what, env = caller_env()) { + deprecate_soft( + "1.1.0", + what = "signal_superseded()", + with = "signal_stage()", + id = "lifecycle_signal_superseded" + ) + signal_stage("superseded", what) +} diff --git a/man/deprecated-signallers.Rd b/man/deprecated-signallers.Rd index ae0ecee..0b92e72 100644 --- a/man/deprecated-signallers.Rd +++ b/man/deprecated-signallers.Rd @@ -1,14 +1,11 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in R/deprecated-signal.R +% Please edit documentation in R/signal.R \name{deprecated-signallers} \alias{deprecated-signallers} -\alias{signal_stage} \alias{signal_experimental} \alias{signal_superseded} \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()) diff --git a/man/signal_stage.Rd b/man/signal_stage.Rd new file mode 100644 index 0000000..9c943d6 --- /dev/null +++ b/man/signal_stage.Rd @@ -0,0 +1,35 @@ +% 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 = deprecated()) +} +\arguments{ +\item{stage}{Life cycle stage, either \code{"experimental"} or \code{"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}{\ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#deprecated}{\figure{lifecycle-deprecated.svg}{options: alt='[Deprecated]'}}}{\strong{[Deprecated]}}} +} +\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, it is currently purely a way to +express intent at the call site. In the future, we hope to replace this with +a standardized call to \code{base::declare()}. +} +\examples{ +foofy <- function(x, y, z) { + signal_stage("experimental", "foofy()") + x + y / z +} +foofy(1, 2, 3) +} diff --git a/tests/testthat/_snaps/deprecated-signal.md b/tests/testthat/_snaps/deprecated-signal.md deleted file mode 100644 index f1b5e3c..0000000 --- a/tests/testthat/_snaps/deprecated-signal.md +++ /dev/null @@ -1,48 +0,0 @@ -# signal generates user friendly message - - Code - (expect_condition(signal_stage("experimental", "foo()"))) - Output - - Code - (expect_condition(signal_stage("superseded", "foo(bar)"))) - Output - - -# signal_stage supports with - - Code - (expect_condition(signal_stage("superseded", "foo()", "bar()"))) - Output - - Code - (expect_condition(signal_stage("superseded", "foo(bar=)", "foo(baz=)"))) - Output - - -# `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/signal.md b/tests/testthat/_snaps/signal.md new file mode 100644 index 0000000..2e26cd4 --- /dev/null +++ b/tests/testthat/_snaps/signal.md @@ -0,0 +1,18 @@ +# `signal_experimental()` and `signal_superseded()` are deprecated + + Code + signal_experimental("1.1.0", "foo()") + Condition + Warning: + `signal_experimental()` was deprecated in lifecycle 1.1.0. + i Please use `signal_stage()` instead. + +--- + + Code + signal_superseded("1.1.0", "foo()") + Condition + Warning: + `signal_superseded()` was deprecated in lifecycle 1.1.0. + i Please use `signal_stage()` instead. + diff --git a/tests/testthat/test-deprecated-signal.R b/tests/testthat/test-deprecated-signal.R deleted file mode 100644 index 3b21e21..0000000 --- a/tests/testthat/test-deprecated-signal.R +++ /dev/null @@ -1,45 +0,0 @@ -test_that("signal stage captures desired data", { - local_options(lifecycle_verbosity = "quiet") - - f <- function() { - signal_stage("experimental", "pkg::foo(bar = 'baz')") - } - - cnd <- expect_condition(f(), class = "lifecycle_stage") - data <- lifecycle_stage_cnd_data(cnd) - expect_equal(data$stage, "experimental") - expect_equal(data$package, "pkg") - expect_equal(data$function_nm, "foo") - expect_equal(data$argument, "bar") - expect_equal(data$reason, "baz") -}) - -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)"))) - }) -}) - -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-signal.R b/tests/testthat/test-signal.R new file mode 100644 index 0000000..051098c --- /dev/null +++ b/tests/testthat/test-signal.R @@ -0,0 +1,12 @@ +test_that("`signal_stage()` does nothing", { + expect_null(signal_stage("experimental", "pkg::foo(bar = 'baz')"), NULL) +}) + +test_that("`signal_experimental()` and `signal_superseded()` are deprecated", { + expect_snapshot({ + signal_experimental("1.1.0", "foo()") + }) + expect_snapshot({ + signal_superseded("1.1.0", "foo()") + }) +})