@@ -1063,30 +1063,46 @@ filter.epi_archive <- function(.data, ..., .by = NULL, .format_aware = FALSE) {
10631063 # They are expected to be active bindings, so directly
10641064 # assigning has issues; `rm` first.
10651065 rm(list = forbidden_colnames , envir = e )
1066- delayedAssign(" version" , cli :: cli_abort(c(
1067- " Using `version` in `filter.epi_archive` may produce unexpected results." ,
1068- " >" = " See if `epix_as_of` or `epix_slide` would work instead." ,
1069- " >" = " If not, see `?filter.epi_archive` details for how to proceed."
1070- ), class = " epiprocess__filter_archive__used_version" ), assign.env = e )
1066+ eval_env <- new.env(parent = asNamespace(" epiprocess" )) # see (2) below
1067+ delayedAssign(
1068+ " version" ,
1069+ cli_abort(c(
1070+ " Using `version` in `filter.epi_archive` may produce unexpected results." ,
1071+ " >" = " See if `epix_as_of` or `epix_slide` would work instead." ,
1072+ " >" = " If not, see `?filter.epi_archive` details for how to proceed."
1073+ ), class = " epiprocess__filter_archive__used_version" ),
1074+ eval.env = eval_env ,
1075+ assign.env = e
1076+ )
10711077 for (measurement_colname in measurement_colnames ) {
1072- # Record current `measurement_colname` and set up delayed
1073- # binding for error in a child environment, so that `for` loop
1074- # updating its value and `rm` cleanup don't mess things up:
1075- local({
1076- local_measurement_colname <- measurement_colname
1077- delayedAssign(measurement_colname , cli :: cli_abort(c(
1078+ # Record current `measurement_colname` and set up execution for
1079+ # the promise for the error in its own dedicated environment, so
1080+ # that (1) `for` loop updating its value and `rm` cleanup don't
1081+ # mess things up. We can also (2) prevent changes to data mask
1082+ # ancestry (to involve user's quosure env rather than our
1083+ # quosure env) or contents (from edge case of user binding
1084+ # functions inside the mask) from potentially interfering by
1085+ # setting the promise's execution environment to skip over the
1086+ # data mask.
1087+ eval_env <- new.env(parent = asNamespace(" epiprocess" ))
1088+ eval_env [[" local_measurement_colname" ]] <- measurement_colname
1089+ delayedAssign(
1090+ measurement_colname ,
1091+ cli_abort(c(
10781092 " Using `{format_varname(local_measurement_colname)}`
10791093 in `filter.epi_archive` may produce unexpected results." ,
10801094 " >" = " See `?filter.epi_archive` details for how to proceed."
1081- ), class = " epiprocess__filter_archive__used_measurement" ), assign.env = e )
1082- })
1095+ ), class = " epiprocess__filter_archive__used_measurement" ),
1096+ eval.env = eval_env ,
1097+ assign.env = e
1098+ )
10831099 }
10841100 break
10851101 }
10861102 e <- parent.env(e )
10871103 }
1088- # Don't mask similarly-named user objects:
1089- rm(list = c(" e" , " measurement_colname" ))
1104+ # Don't mask similarly-named user objects in ancestor envs :
1105+ rm(list = c(" e" , " measurement_colname" , " eval_env " ))
10901106 TRUE
10911107 },
10921108 ... ,
0 commit comments