-
-
Notifications
You must be signed in to change notification settings - Fork 8
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
Teal refactor #66
Teal refactor #66
Conversation
* constructor, eval_code, lockEnvironment - need validation * prototype * constructor for the list of data (possibly reactive) * progress with join quosure * - added more constructors - test constructors - test join * update WIP * fix constructor from list * Update Quosure.R * add id to the code, resolve join conflicts, more test * implement id field in Quosure to distinguish detect code entries
R/quosure-join.R
Outdated
is_overwritten <- vapply(common_names, function(el) { | ||
!identical(get(el, x@env), get(el, y@env)) | ||
}, logical(1)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am a little bit concerned here about get()
operation as it could evaluate lazy bindings or promises therefore this functionality could be expensive and most importantly - it could have some side effects. I neither have a counter-example nor a potential solution. Just note to myself...
R/quosure-join.R
Outdated
#' - indices of the shared code are not consecutive or don't start from 1 | ||
#' @param x (`Quosure`) | ||
#' @param y (`Quosure`) | ||
#' @return `TRUE` if able to join or `character` used to print error message. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it's always good to assure that function always returns the same data type. This would prevent you doing expect_true(foo(...))
and expect_match(foo(...), "...")
at the same time.
This is not the first time where we are facing the problem of returning a character message if something else TRUE. I suggest to always return boolean with additional attribute. Alternatively you might want to use checkmate
assertion collections.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree. As a user it can be annoying when a function returns 2 types of objects. ('user' includes developer w/in package)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This function is internal, user shouldn't use this function at all. .check_joinable
is used only in the join
in following way:
join_validation <- .check_joinable(x, y)
# join expressions
if (!isTRUE(join_validation)) {
stop(join_validation)
}
Alternatively, we can move stop
to the .check_joinable and forget the whole thing
Signed-off-by: Nikolas Burkoff <nikolas.burkoff@tessella.com>
Signed-off-by: Nikolas Burkoff <nikolas.burkoff@tessella.com>
#' q1 <- new_qenv(code = "print('a')", env = new.env()) | ||
#' q1 | ||
#' @export | ||
setMethod("show", "qenv", function(object) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See #88 (for later)
Signed-off-by: Nikolas Burkoff <nikolas.burkoff@tessella.com>
Signed-off-by: Nikolas Burkoff <nikolas.burkoff@tessella.com>
q1 <- eval_code(new_qenv(), quote(library(checkmate))) | ||
# library call adds package env in the search path just over .GlobalEnv | ||
# it means that q3@env before the call was a parent of .GlobalEnv but not after the call | ||
|
||
q2 <- eval_code(q1, quote(assert_number(1))) | ||
testthat::expect_identical(parent.env(q2@env), parent.env(.GlobalEnv)) | ||
|
||
detach("package:checkmate", unload = TRUE) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just confirming this test leaves the status of the checkmate package unchanged (we don't need a on.exit(detach("package:checkmate")) on line 29 to make sure that it is detached if something goes wrong in lines 32 and 33? @gogonzo
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Lets do this 🦾
DESCRIPTION
Outdated
@@ -19,14 +19,17 @@ Depends: | |||
R (>= 4.0) | |||
Imports: | |||
checkmate, | |||
cli, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can we remove cli
dependency? It's a big package
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if we do then we don't fix this:
#86 - unless you want to fix it a different way
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
that's my question - can we do (name that thing) differently not involving cli package?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
so this is what we call:
> cli::ansi_strip
function (string, sgr = TRUE, csi = TRUE, link = TRUE)
{
if (!is.character(string))
string <- as.character(string)
string <- enc2utf8(string)
stopifnot(is_flag(sgr), is_flag(csi), is_flag(link))
clean <- .Call(clic_ansi_strip, string, sgr, csi, link)
class(clean) <- setdiff(class(clean), c("cli_ansi_string",
"ansi_string"))
clean
}
<bytecode: 0x0000018dd338c3e0>
<environment: namespace:cli>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
and dplyr imports cli so in practice ppl using this package will have cli installed but if there's an easy way round this then happy to change (or put issue in bnacklog to change)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we could add it into suggests like rlang does and only call it if installed?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here I am more concerned about the package size and the installation process. Up to you how would you like to process it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we could add it into suggests like rlang and only call it if installed?
This only makes sense if a particular piece of code is unlikely to be called assuming standard workflow. E.g. a wide tree-based workflow / case when where there are many many possibilities. Here, if I understand everything correctly it's a part of standard logic so it's very likely that it will be executed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
so I assume that these funny terminal printing characters added by rlang are only added if cli is installed (cli is a suggests in rlang only) - therefore I think it makes sense for us to use suggests as well - as striping these terminal printing characters out only makes sense if cli (via rlang) added them in the first place - commit coming soon
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
so rlang is only in the suggests but needs to be imported - whoops
And we are one step away from test coverage perfection :). In the covr report there is only one line non-covered in tests:
|
For anyone concerned about deep coping the objects. There are no deep copies in library(teal.code)
library(lobstr)
x <- data.frame(a = runif(10))
q1 <- new_qenv(env = list2env(list(x = x)), code = "x <- data.frame(a = 1)")
identical(lobstr::ref(q1[["x"]]), lobstr::ref(x))
# TRUE
q2 <- eval_code(q1, quote(x$b <- runif(10)))
!identical(lobstr::ref(q2[["x"]]), lobstr::ref(q1[["x"]]))
# TRUE
identical(lobstr::ref(q2[["x"]]$a), lobstr::ref(q1[["x"]]$a))
# TRUE
q3 <- eval_code(q2, quote(y <- x))
identical(q3[["y"]], q2[["x"]])
# TRUE
q4 <- join(q2, q3)
identical(lobstr::ref(q4[["y"]]), lobstr::ref(q2[["x"]]))
# TRUE |
|
Part of insightsengineering/teal#731