Skip to content

Augment Abort & co.; add rlang condition tutorial, helpers #102

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 1 commit into
base: dev
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .Rbuildignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
^.*\.Rproj$
^\.Rproj\.user$
^LICENSE\.md$
^man-roxygen$
32 changes: 32 additions & 0 deletions NAMESPACE
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,15 @@ export(epi_slide)
export(epix_as_of)
export(epix_merge)
export(epix_slide)
export(global_handlers_list)
export(global_handlers_push)
export(global_handlers_remove)
export(growth_rate)
export(handle_via_dump_frames)
export(handle_via_entrace)
export(handle_via_muffle_message)
export(handle_via_muffle_warning)
export(handle_via_recover)
export(is_epi_archive)
export(is_epi_df)
export(quiet)
Expand All @@ -53,18 +61,42 @@ importFrom(dplyr,ungroup)
importFrom(lubridate,days)
importFrom(lubridate,weeks)
importFrom(magrittr,"%>%")
importFrom(purrr,map2_lgl)
importFrom(purrr,map_chr)
importFrom(purrr,map_dbl)
importFrom(purrr,map_lgl)
importFrom(rlang,"!!!")
importFrom(rlang,"!!")
importFrom(rlang,.data)
importFrom(rlang,.env)
importFrom(rlang,abort)
importFrom(rlang,arg_match)
importFrom(rlang,base_env)
importFrom(rlang,caller_env)
importFrom(rlang,chr)
importFrom(rlang,dbl)
importFrom(rlang,empty_env)
importFrom(rlang,enquo)
importFrom(rlang,enquos)
importFrom(rlang,env_label)
importFrom(rlang,fn_env)
importFrom(rlang,global_env)
importFrom(rlang,inform)
importFrom(rlang,inject)
importFrom(rlang,is_function)
importFrom(rlang,is_quosure)
importFrom(rlang,is_reference)
importFrom(rlang,names2)
importFrom(rlang,sym)
importFrom(rlang,syms)
importFrom(rlang,warn)
importFrom(stats,cor)
importFrom(stats,median)
importFrom(stats,setNames)
importFrom(tibble,lst)
importFrom(tidyr,unnest)
importFrom(tidyselect,eval_select)
importFrom(tidyselect,starts_with)
importFrom(tsibble,as_tsibble)
importFrom(utils,capture.output)
importFrom(utils,str)
8 changes: 0 additions & 8 deletions R/utils.R
Original file line number Diff line number Diff line change
@@ -1,11 +1,3 @@
break_str = function(str, nchar = 79, init = "") {
str = paste(strwrap(str, nchar, init = init), collapse = "\n")
str[1] = substring(str, nchar(init)+1)
return(str)
}

Abort = function(msg, ...) rlang::abort(break_str(msg, init = "Error: "), ...)
Warn = function(msg, ...) rlang::warn(break_str(msg, init = "Warning: "), ...)

##########

Expand Down
735 changes: 735 additions & 0 deletions R/utils_conditions.R

Large diffs are not rendered by default.

17 changes: 17 additions & 0 deletions man-roxygen/Condition.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#' @param message character vector; an `rlang` non-`cli`-format message; this
#' will be line-wrapped and augmented with information about
#' `display_subfields` and how to access any `more_subfields`
#' @param class_suffix string or NULL; if non-NULL, and we are in a package,
#' then `"<pkgname>__<class_suffix>"` will be tacked on as an S3 class of the
#' condition object; if we are not in a package, then the suffix (without any
#' prefix) will be added as an S3 class. Additionally, regardless of whether
#' `class_suffix` is `NULL`, if we are in a package, two additional S3 classes
#' will be added as well: `"<pkgname>__<conditiontype>"` and
#' `"<pkgname>__condition"`
#' @param display_subfields list of objects to display as part of the condition
#' message using [`utils::str`] and save in the condition object
#' @param more_subfields list of objects to save in the condition object but
#' only point to, not display, in the condition message
#' @param call environment; the calling environment from which the trace should
#' be produced
NULL
6 changes: 6 additions & 0 deletions man-roxygen/handler_dots.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#' @param ... named calling handlers: each a function that takes a condition
#' object as an argument and performs some handling (such as printing or
#' recording a stack trace), passed by name, where the name associates the
#' handler with a class of conditions it should be called on (e.g.,
#' `"condition"` as a catch-all, `"error"`, `"warning"`, `"message"`, or more
#' specific classes provided by some packages)
32 changes: 32 additions & 0 deletions man-roxygen/handler_fn.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# See notes on the use of `r ...` dynamic R code in roxygen2 comments
# `utils_conditions.R`. We have to use a bit different code to get this to work
# inside this template tag file, leading to long `r ...` chunks; don't
# wrap/fill/format these, or else current roxygen2 at time of writing will not
# properly process them. Keep the blank lines around them to help prevent
# accidental auto-formatting.
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Roxygen templates provide a different way to execute dynamic code with <%= ...... %>. Might provide a way around the line wrap fighting. (Here and in other template file, and maybe also in other non-template places where dynamic R code is used that could be turned into templates.)


#' @description
#'
#' This is a very simple function, but simply repeating its definition
#' everywhere of interest prevents

#' `r paste0(if(getRversion()>="4")"["else"","\x60base::globalCallingHandlers\x60",if(getRversion()>="4")"]"else"")`

#' and straightforward handler-related functions from recognizing these repeated
#' redefinitions as the same things (due to differing bytecode, srcrefs, closure
#' environments, and/or other things). This function provides a consistent
#' identity for this type of handler, and attempts to maintain this identity
#' even across package reloads (by setting its closure environment to a
#' something that should always be available and never reloaded; to match
#' `rlang:::hnd_entrace`, this is [`base::baseenv()`]; this means that things
#' not available from `base` require use of `<pkg>::` to access).
#'
#' @param cnd a condition object (e.g., an error, warning, or message)
#'
#' @seealso [`base::withCallingHandlers`] to tie this handler to a condition
#' subclass for a block of code, or

#' `r paste0(if(getRversion()>="4")"["else"","\x60base::globalCallingHandlers\x60",if(getRversion()>="4")"]"else"")`,

#' [`global_handlers_push`], [`global_handlers_remove`],
#' [`global_handlers_list`] to enable/disable/list these associations globally
25 changes: 25 additions & 0 deletions man-roxygen/handler_fn_env_test.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# See notes on the use of `r ...` dynamic R code in roxygen2 comments
# `utils_conditions.R`. We have to use a bit different code to get this to work
# inside this template tag file, leading to long `r ...` chunks; don't
# wrap/fill/format these, or else current roxygen2 at time of writing will not
# properly process them. Keep the blank lines around them to help prevent
# accidental auto-formatting.

#' @param .fn_env_test optional; a single string, selected from the choices
#' listed in the nominal default value, with the effective default being the
#' first choice listed; indicates how [`rlang::fn_env`]s of handler functions
#' should be tested for equality when comparing handler functions for
#' equality. Here, `fn_env` is the closure environment for closure functions,
#' or the base namespace environment for primitive functions. Choosing
#' `"label"` means to test the [`rlang::env_label`]s of these environments,
#' intended to be somewhat strict while allowing a package function to remain
#' equal to "itself" if its formals and body haven't changed; `"identical"`
#' means to use [`base::identical`] with its defaults (ignoring bytecode and
#' srcref); `"ignore"` means to ignore the `fn_env`s when comparing functions.
#' The more lenient comparisons provide some flexibility when working with
#' handler functions that aren't carefully crafted to work with functions
#' based on stricter equality tests that

#' `r paste0(if(getRversion()>="4")"["else"","\x60base::globalCallingHandlers\x60",if(getRversion()>="4")"]"else"")`

#' uses.
41 changes: 41 additions & 0 deletions man/Abort.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

41 changes: 41 additions & 0 deletions man/Inform.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

41 changes: 41 additions & 0 deletions man/Warn.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

12 changes: 8 additions & 4 deletions man/as_epi_archive.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

18 changes: 18 additions & 0 deletions man/check_global_handlers_stack_support.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

19 changes: 19 additions & 0 deletions man/check_named_handlers_dots.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

19 changes: 19 additions & 0 deletions man/condition_noncli_message.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading