Skip to content

Commit c24b014

Browse files
authored
merge pr #805: prompt on parameter extraction when implementation is missing
2 parents c54f07b + 1447f27 commit c24b014

File tree

9 files changed

+91
-45
lines changed

9 files changed

+91
-45
lines changed

R/arguments.R

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -102,9 +102,8 @@ set_mode.model_spec <- function(object, mode) {
102102
# determine if the model specification could feasibly match any entry
103103
# in the union of the parsnip model environment and model_info_table.
104104
# if not, trigger an error based on the (possibly inferred) model spec slots.
105-
if (!spec_is_possible(cls,
106-
object$engine, object$user_specified_engine,
107-
mode, user_specified_mode = TRUE)) {
105+
if (!spec_is_possible(spec = object,
106+
mode = mode, user_specified_mode = TRUE)) {
108107
check_spec_mode_engine_val(cls, object$engine, mode)
109108
}
110109

R/engines.R

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -120,9 +120,8 @@ set_engine.model_spec <- function(object, engine, ...) {
120120
# determine if the model specification could feasibly match any entry
121121
# in the union of the parsnip model environment and model_info_table.
122122
# if not, trigger an error based on the (possibly inferred) model spec slots.
123-
if (!spec_is_possible(mod_type,
124-
object$engine, user_specified_engine = TRUE,
125-
object$mode, object$user_specified_mode)) {
123+
if (!spec_is_possible(spec = object,
124+
engine = object$engine, user_specified_engine = TRUE)) {
126125
check_spec_mode_engine_val(mod_type, object$engine, object$mode)
127126
}
128127

R/extract.R

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,14 @@ extract_fit_engine.model_fit <- function(x, ...) {
7474
#' @export
7575
#' @rdname extract-parsnip
7676
extract_parameter_set_dials.model_spec <- function(x, ...) {
77+
if (!spec_is_loaded(spec = x)) {
78+
prompt_missing_implementation(
79+
spec = x,
80+
prompt = cli::cli_abort,
81+
call = NULL
82+
)
83+
}
84+
7785
all_args <- generics::tunable(x)
7886
tuning_param <- generics::tune_args(x)
7987

R/fit.R

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -121,11 +121,7 @@ fit.model_spec <-
121121

122122
if (length(possible_engines(object)) == 0) {
123123
prompt_missing_implementation(
124-
cls = class(object)[1],
125-
engine = object$engine,
126-
user_specified_engine = object$user_specified_engine,
127-
mode = object$mode,
128-
user_specified_mode = object$user_specified_mode,
124+
spec = object,
129125
prompt = cli::cli_abort,
130126
call = call2("fit")
131127
)

R/misc.R

Lines changed: 28 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ mode_filter_condition <- function(mode, user_specified_mode) {
5858
#'
5959
#' The helpers `spec_is_possible()`, `spec_is_loaded()`, and
6060
#' `prompt_missing_implementation()` provide tooling for checking
61-
#' model specifications. In addition to the `cls`, `engine`, and `mode`
61+
#' model specifications. In addition to the `spec`, `engine`, and `mode`
6262
#' arguments, the functions take arguments `user_specified_engine` and
6363
#' `user_specified_mode`, denoting whether the user themselves has
6464
#' specified the engine or mode, respectively.
@@ -91,9 +91,13 @@ mode_filter_condition <- function(mode, user_specified_mode) {
9191
#' @export
9292
#' @keywords internal
9393
#' @rdname add_on_exports
94-
spec_is_possible <- function(cls,
95-
engine, user_specified_engine,
96-
mode, user_specified_mode) {
94+
spec_is_possible <- function(spec,
95+
engine = spec$engine,
96+
user_specified_engine = spec$user_specified_engine,
97+
mode = spec$mode,
98+
user_specified_mode = spec$user_specified_mode) {
99+
cls <- class(spec)[[1]]
100+
97101
all_model_info <-
98102
dplyr::full_join(
99103
read_model_info_table(),
@@ -119,9 +123,13 @@ spec_is_possible <- function(cls,
119123
#' @export
120124
#' @keywords internal
121125
#' @rdname add_on_exports
122-
spec_is_loaded <- function(cls,
123-
engine, user_specified_engine,
124-
mode, user_specified_mode) {
126+
spec_is_loaded <- function(spec,
127+
engine = spec$engine,
128+
user_specified_engine = spec$user_specified_engine,
129+
mode = spec$mode,
130+
user_specified_mode = spec$user_specified_mode) {
131+
cls <- class(spec)[[1]]
132+
125133
engine_condition <- engine_filter_condition(engine, user_specified_engine)
126134
mode_condition <- mode_filter_condition(mode, user_specified_mode)
127135

@@ -143,9 +151,7 @@ spec_is_loaded <- function(cls,
143151

144152
is_printable_spec <- function(x) {
145153
!is.null(x$method$fit$args) &&
146-
spec_is_loaded(class(x)[1],
147-
x$engine, x$user_specified_engine,
148-
x$mode, x$user_specified_mode)
154+
spec_is_loaded(x)
149155
}
150156

151157
# construct a message informing the user that there are no
@@ -158,10 +164,14 @@ is_printable_spec <- function(x) {
158164
#' @export
159165
#' @keywords internal
160166
#' @rdname add_on_exports
161-
prompt_missing_implementation <- function(cls,
162-
engine, user_specified_engine,
163-
mode, user_specified_mode,
167+
prompt_missing_implementation <- function(spec,
168+
engine = spec$engine,
169+
user_specified_engine = spec$user_specified_engine,
170+
mode = spec$mode,
171+
user_specified_mode = spec$user_specified_mode,
164172
prompt, ...) {
173+
cls <- class(spec)[[1]]
174+
165175
engine_condition <- engine_filter_condition(engine, user_specified_engine)
166176
mode_condition <- mode_filter_condition(mode, user_specified_mode)
167177

@@ -303,18 +313,17 @@ new_model_spec <- function(cls, args, eng_args, mode, user_specified_mode = TRUE
303313
# determine if the model specification could feasibly match any entry
304314
# in the union of the parsnip model environment and model_info_table.
305315
# if not, trigger an error based on the (possibly inferred) model spec slots.
306-
if (!spec_is_possible(cls,
307-
engine, user_specified_engine,
308-
mode, user_specified_mode)) {
309-
check_spec_mode_engine_val(cls, engine, mode)
310-
}
311-
312316
out <- list(
313317
args = args, eng_args = eng_args,
314318
mode = mode, user_specified_mode = user_specified_mode, method = method,
315319
engine = engine, user_specified_engine = user_specified_engine
316320
)
317321
class(out) <- make_classes(cls)
322+
323+
if (!spec_is_possible(spec = out)) {
324+
check_spec_mode_engine_val(cls, engine, mode)
325+
}
326+
318327
out
319328
}
320329

R/print.R

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,8 @@ print.model_spec <- function(x, ...) {
99
#' @rdname add_on_exports
1010
#' @export
1111
print_model_spec <- function(x, cls = class(x)[1], desc = get_model_desc(cls), ...) {
12-
if (!spec_is_loaded(cls,
13-
x$engine, x$user_specified_engine,
14-
x$mode, x$user_specified_mode)) {
15-
prompt_missing_implementation(cls,
16-
x$engine, x$user_specified_engine,
17-
x$mode, x$user_specified_mode,
18-
prompt = cli::cli_inform)
12+
if (!spec_is_loaded(spec = structure(x, class = cls))) {
13+
prompt_missing_implementation(spec = structure(x, class = cls), prompt = cli::cli_inform)
1914
}
2015

2116
cat(desc, " Model Specification (", x$mode, ")\n\n", sep = "")

man/add_on_exports.Rd

Lines changed: 20 additions & 8 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

tests/testthat/_snaps/extract.md

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
# extract parameter set from model with no loaded implementation
2+
3+
Code
4+
extract_parameter_set_dials(bt_mod)
5+
Condition
6+
Error:
7+
! parsnip could not locate an implementation for `bag_tree` regression model specifications.
8+
i The parsnip extension package baguette implements support for this specification.
9+
i Please install (if needed) and load to continue.
10+
11+
---
12+
13+
Code
14+
extract_parameter_dials(bt_mod, parameter = "min_n")
15+
Condition
16+
Error:
17+
! parsnip could not locate an implementation for `bag_tree` regression model specifications.
18+
i The parsnip extension package baguette implements support for this specification.
19+
i Please install (if needed) and load to continue.
20+

tests/testthat/test_extract.R

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,14 @@ test_that('extract parameter set from model with main and engine parameters', {
5050
expect_equal(c5_info$object[[2]], NA)
5151
})
5252

53+
test_that('extract parameter set from model with no loaded implementation', {
54+
bt_mod <- bag_tree(min_n = tune()) %>%
55+
set_mode("regression")
56+
57+
expect_snapshot(error = TRUE, extract_parameter_set_dials(bt_mod))
58+
expect_snapshot(error = TRUE, extract_parameter_dials(bt_mod, parameter = "min_n"))
59+
})
60+
5361
# ------------------------------------------------------------------------------
5462

5563
test_that('extract single parameter from model with no parameters', {

0 commit comments

Comments
 (0)