Skip to content
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

Use rlang dots helper instead of ellipsis #6038

Merged
merged 6 commits into from Oct 4, 2021
Merged

Conversation

romainfrancois
Copy link
Member

Perhaps this should drop the rlang:: prefix too since rlang is @import'ed

R/rows.R Outdated
@@ -186,7 +186,7 @@ rows_upsert.data.frame <- function(x, y, by = NULL, ..., copy = FALSE, in_place
rows_delete <- function(x, y, by = NULL, ..., copy = FALSE, in_place = FALSE) {
# Need action = warn, because methods may have
# side effects that persist even after we abort
ellipsis::check_dots_used(action = warn)
rlang::check_dots_used(action = warn)
Copy link
Member

Choose a reason for hiding this comment

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

I plan to deprecate the action = , maybe wait until that's the case? I'll do it next week.

Copy link
Member

Choose a reason for hiding this comment

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

Why is this not throwing errors?

Copy link
Member Author

Choose a reason for hiding this comment

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

cc @krlmlr

Copy link
Member

Choose a reason for hiding this comment

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

These methods are unusual in the sense that their main purpose may be the side effects they cause, especially with in_place = TRUE for database backends. Throwing an error after the side effects happened would be wrong here.

Copy link
Member

Choose a reason for hiding this comment

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

I'm generally in favor of removing the check_dots_*() helpers from the generics, and letting the methods call check_dots_empty(), like what @romainfrancois did in dm cynkra/dm#639

The only other place we use check_dots_used() like this is in pull(), but we could change that too to make pull.data.frame() call check_dots_empty().

Copy link
Member Author

Choose a reason for hiding this comment

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

Good catch, perhaps we can do pull() in a follow up pull request. Although it looks like more methods exist:
https://github.com/search?q=org%3Acran+S3method%28pull%2C&type=code

So perhaps more implementations would have to use check_dots_empty()

@lionel-
Copy link
Member

lionel- commented Oct 1, 2021

Perhaps this should drop the rlang:: prefix too since rlang is @import'ed

yeah for consistency

@romainfrancois
Copy link
Member Author

Not sure why still getting

W  checking dependencies in R code (1.3s)
   '::' or ':::' import not declared from: ‘ellipsis’

@DavisVaughan
Copy link
Member

DavisVaughan commented Oct 1, 2021

Ooooh @romainfrancois this was a tough one. It is because we inline tidyselect::peek_vars here and that uses ellipsis::

peek_vars <- tidyselect::peek_vars

Found by stepping through tools:::.check_packages_used("dplyr")

It would be great to remove that if we can, I think

@romainfrancois
Copy link
Member Author

romainfrancois commented Oct 4, 2021

This seems to do the trick. Thanks @DavisVaughan. cc @lionel- in case peek_vars <- tidyselect::peek_vars is still needed for something, I don't believe so.

Perhaps we can use check_dots_empty() on the rows_*.data.frame methods and let implementations (in dm:: ?) do something different with the ... ? cc @krlmlr

@romainfrancois
Copy link
Member Author

We have:

rows_insert <- function(x, y, by = NULL, ..., copy = FALSE, in_place = FALSE) {
  # Need action = warn, because methods may have
  # side effects that persist even after we abort
  check_dots_used()
  UseMethod("rows_insert")
}

and then in dm::

rows_insert.tbl_dbi <- function(x, y, by = NULL, ...,
                                in_place = NULL, copy = FALSE, check = NULL,
                                returning = NULL) {

And the ... are not passed through, so this is just about checking that specific arguments of the methods (check=, returning= are fully named ? Should dm rather itself call check_dots_empty() so that it fails when that happens rather warn ?

@krlmlr
Copy link
Member

krlmlr commented Oct 4, 2021

Am I understanding this right: if all methods use check_dots_empty(), we don't need check_dots_used() in the generic?

@romainfrancois
Copy link
Member Author

Yeah I guess so, at least in this case where IIUC the generic had check_dots_used() to make sure everything in the ... was used after the end of the methods, which as the comment implied might be too late, happen after some changes have been performed in the database, ....

If instead, the method checks that the ... are unused, it can fail immediately, and so avoid doing unwanted work on the database.

Copy link
Member

@lionel- lionel- left a comment

Choose a reason for hiding this comment

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

Another potential reason for using check_dots_empty() in dplyr methods instead of check_dots_used() in dplyr generics is that the latter can't detect that an argument was defused with {{ or enquo().

@romainfrancois romainfrancois merged commit a35d328 into master Oct 4, 2021
@romainfrancois romainfrancois deleted the remove_ellipsis branch October 4, 2021 15:48
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants