Ian Farm
2025-Jan-22 20:34 UTC
[Rd] Depends: R (>= 4.1) for packages that use |> and \(...)
Hello all, Would packages using the underscore placeholder with the native pipe need to also depend on R >= 4.2.0? There appear to be a number, modifying Ivan's GitHub search: https://github.com/search?q=org%3Acran+path%3A%2F%5B.%5D%5BRr%5Dd%3F%24%2F+%2F%5Cs%5C%7C%3E%5Cs.*%3D%5Cs%3F_%2F&type=code Regards, Ian ____ Ian Farm Laboratory Manager, The Agroecology Lab University of Maine School of Food and Agriculture 5762 Roger Clapp Greenhouses, Orono, Maine 04469 On Wed, Jan 22, 2025 at 1:47?AM Kurt Hornik <Kurt.Hornik at wu.ac.at> wrote:> >>>>> Kurt Hornik writes: > > I just committed c8761[2-4] to the trunk which adds an internal utility > for finding package code using the pipe or function shorthand, teaches R > CMD build to add a dependency on R >= 4.1.0 as necessary, and teaches R > CMD check to NOTE a missing dependency on R >= 4.1.0, based on Ivan's > code. > > Currently, we seem to have about 1149 packages on CRAN with package code > using the pipe or function shorthand, with only 415 depending on R >> 4.1.0, and 734 not. Argh. > > Thanks again for spotting this. > > Best > -k > > >>>>> Kurt Hornik writes: > > Oh dear. Using a variant of Ivan's code, I seem to find 728 (!!!) CRAN > > packages which are missing their R >= 4.1 dependency. > > > So clearly we need to do more about this than teach R CMD build to add > > the dependency ... > > > Best > > -k > > >>>>> Henrik Bengtsson writes: > >> Thanks. Will take a look ... > > >> Best > >> -k > > >>> Thanks for looking into this and the patch. FWIW, there's an open > >>> PR18105 - "R CMD build: Add dependency on R >= 4.1.0 if code uses pipe > >>> symbol |>" for this > >>> (https://bugs.r-project.org/show_bug.cgi?id=18105). > > >>> /Henrik > > >>> On Thu, Jan 16, 2025 at 3:42?AM Ivan Krylov via R-devel > >>> <r-devel at r-project.org> wrote: > >>>> > >>>> Hello R-devel, > >>>> > >>>> Approximately [*] the following CRAN packages make use of the pipe > >>>> syntax in their source code or examples without depending on R >= 4.1: > >>>> > >>>> [1] "biplotEZ" "CaseBasedReasoning" "collinear" > >>>> [4] "cubble" "disk.frame" "duckdbfs" > >>>> [7] "eia" "feltr" "flattabler" > >>>> [10] "geodimension" "hgnc" "himach" > >>>> [13] "lay" "lidR" "locateip" > >>>> [16] "particles" "photosynthesis" "pivotea" > >>>> [19] "planr" "rtrek" "satres" > >>>> [22] "sdtmval" "selenider" "sewage" > >>>> [25] "stminsights" "tabr" "tidygraph" > >>>> [28] "tidywikidatar" "USgas" "washi" > >>>> [31] "zctaCrosswalk" > >>>> > >>>> Since we have checks in place to automatically set Depends: R (>> >>>> 2.10.0) for data files compressed with xz or bzip2 and >= 3.5.0 for > >>>> data files serialized with format version 3, would it make sense to > >>>> automatically add Depends: R (>= 4.1) for such packages? > >>>> > >>>> The patch at the end of this message adds the R version dependency > >>>> during R CMD build: > >>>> > >>>> R-devel CMD build --no-build-vignettes . > >>>> * checking for file ?./DESCRIPTION? ... OK > >>>> * preparing ?biplotEZ?: > >>>> * checking DESCRIPTION meta-information ... OK > >>>> * cleaning src > >>>> * checking vignette meta-information ... OK > >>>> * checking for LF line-endings in source and make files and shell > >>>> scripts > >>>> * checking for empty or unneeded directories > >>>> NB: this package now depends on R (>= 4.1.0) > >>>> WARNING: Added dependency on R >= 4.1.0 because some of the source > >>>> files use the new syntax constructs. > >>>> Files making use of R >= 4.1 pipe |> or function shorthand \(...): > >>>> biplotEZ/R/biplot.R biplotEZ/R/translate_axes.R > >>>> * building ?biplotEZ_2.2.tar.gz? > >>>> > >>>> A more extensive test could also look at the tests, demos, and > >>>> \examples{}, but that may take longer and open the door for false > >>>> positives. A package that uses |> in one example would still be useful > >>>> on R-4.0.0, while a package that uses |> in the source code would fail > >>>> to parse and install. > >>>> > >>>> Index: src/library/tools/R/QC.R > >>>> ==================================================================> >>>> --- src/library/tools/R/QC.R (revision 87545) > >>>> +++ src/library/tools/R/QC.R (working copy) > >>>> @@ -10367,7 +10367,29 @@ > >>>> } > >>>> } > >>>> > >>>> +.check_use_of_R41_syntax <- > >>>> +function(files) > >>>> +{ > >>>> + out <- vapply(files, > >>>> + function(f) tryCatch( > >>>> + any(getParseData(parse(f, keep.source = TRUE))$token > %in% c("PIPE", "'\\\\'")), > >>>> + error = function(e) FALSE > >>>> + ), > >>>> + FALSE) > >>>> + out <- files[out] > >>>> + class(out) <- "check_use_of_R41_syntax" > >>>> + out > >>>> +} > >>>> > >>>> +format.check_use_of_R41_syntax <- > >>>> +function(x, ...) > >>>> +{ > >>>> + if (length(x)) { > >>>> + c("Files making use of R >= 4.1 pipe |> or function > shorthand \\(...):", > >>>> + .strwrap22(x, " ")) > >>>> + } else character() > >>>> +} > >>>> + > >>>> ### Local variables: *** > >>>> ### mode: outline-minor *** > >>>> ### outline-regexp: "### [*]+" *** > >>>> Index: src/library/tools/R/build.R > >>>> ==================================================================> >>>> --- src/library/tools/R/build.R (revision 87545) > >>>> +++ src/library/tools/R/build.R (working copy) > >>>> @@ -1165,9 +1165,11 @@ > >>>> desc <- .read_description(file.path(pkgname, "DESCRIPTION")) > >>>> Rdeps <- .split_description(desc)$Rdepends2 > >>>> hasDep350 <- FALSE > >>>> + hasDep410 <- FALSE > >>>> for(dep in Rdeps) { > >>>> if(dep$op != '>=') next > >>>> if(dep$version >= "3.5.0") hasDep350 <- TRUE > >>>> + if(dep$version >= "4.1.0") hasDep410 <- TRUE > >>>> } > >>>> if (!hasDep350) { > >>>> ## re-read files after exclusions have been applied > >>>> @@ -1189,6 +1191,23 @@ > >>>> "\n") > >>>> } > >>>> } > >>>> + if (!hasDep410) { > >>>> + uses410 <- > .check_use_of_R41_syntax(dir(file.path(pkgname, "R"), > >>>> + full.names > TRUE, > >>>> + pattern > "[.]R$", > >>>> + ignore.case > TRUE)) > >>>> + if (length(uses410)) { > >>>> + fixup_R_dep(pkgname, "4.1.0") > >>>> + msg <- paste("WARNING: Added dependency on R >> 4.1.0 because", > >>>> + "some of the source files use the new > syntax", > >>>> + "constructs.") > >>>> + printLog(Log, > >>>> + paste(c(strwrap(msg, indent = 2L, exdent > 2L), > >>>> + format(uses410)), > >>>> + collapse = "\n"), > >>>> + "\n") > >>>> + } > >>>> + } > >>>> > >>>> ## add NAMESPACE if the author didn't write one > >>>> if(!file.exists(namespace <- file.path(pkgname, "NAMESPACE")) ) { > >>>> > >>>> > >>>> -- > >>>> Best regards, > >>>> Ivan > >>>> > >>>> [*] Based on the following GitHub search, which requires logging in: > >>>> > https://github.com/search?q=org%3Acran%20path%3A%2F%5B.%5D%5BRr%5Dd%3F%24%2F%20%2F%5Cs%5C%7C%3E%2F&type=code > >>>> There's currently no REST API support for regexp search, so the list > >>>> was obtained manually. > >>>> > >>>> ______________________________________________ > >>>> R-devel at r-project.org mailing list > >>>> https://stat.ethz.ch/mailman/listinfo/r-devel > > >>> ______________________________________________ > >>> R-devel at r-project.org mailing list > >>> https://stat.ethz.ch/mailman/listinfo/r-devel > > >> ______________________________________________ > >> R-devel at r-project.org mailing list > >> https://stat.ethz.ch/mailman/listinfo/r-devel > > ______________________________________________ > R-devel at r-project.org mailing list > https://stat.ethz.ch/mailman/listinfo/r-devel >[[alternative HTML version deleted]]
Ivan Krylov
2025-Jan-23 09:10 UTC
[Rd] Depends: R (>= 4.1) for packages that use |> and \(...)
Many thanks to Henrik for remembering the report in Bugzilla and to Kurt for implementing the change and finding out the true number of affected packages. On Wed, 22 Jan 2025 15:34:41 -0500 Ian Farm <ian.farm at maine.edu> wrote:> Would packages using the underscore placeholder with the native pipe > need to also depend on R >= 4.2.0?That's a good find! For the R >= 4.2 syntax, we only need to check for getParseData(...)$token %in% 'PLACEHOLDER'. The R >= 4.3 syntax feature is harder to test for:>> As an experimental feature the placeholder _ can now also be used in >> the rhs of a forward pipe |> expression as the first argument in an >> extraction call, such as _$coef. More generally, it can be used as >> the head of a chain of extractions, such as _$coef[[2]].I think it might be possible to parse(text = paste('PLACEHOLDER |>', grandparent_expression)) and then look at the top-level function in the call, but that feels quite fragile: x <- utils::getParseData(parse(f, keep.source = TRUE)) i <- x$token %in% "PLACEHOLDER" pi <- x[i, "parent"] ppi <- x[x$id %in% pi, "parent"] placeholder_expressions <- utils::getParseText(x, ppi) extractor_used <- vapply(placeholder_expressions, function(src) { toplevel <- parse(text = paste("PLACEHOLDER |> ", src))[[1]][[1]] identical(toplevel, quote(`$`)) || identical(toplevel, quote(`[`)) || identical(toplevel, quote(`[[`)) }, FALSE) Alternatively, we may find the first child of the grandparent of the placeholder. If it's the placeholder expression, then the pipe must be of the form ...|> _..., which is the R >= 4.3 syntax: x <- utils::getParseData(parse(f, keep.source = TRUE)) i <- x$token %in% "PLACEHOLDER" vapply(which(i), function(i) { pi <- x[i, "parent"] ppi <- x[x$id %in% pi, "parent"] cppi <- x[x$parent %in% ppi, "id"] min(cppi) == pi }, FALSE) -- Best regards, Ivan