diff --git a/R/argparse.R b/R/argparse.R index 3ed4e87..fed321d 100644 --- a/R/argparse.R +++ b/R/argparse.R @@ -1,4 +1,4 @@ -# Copyright (c) 2012-2020 Trevor L. Davis +# Copyright (c) 2012-2021 Trevor L. Davis # # This file is free software: you may copy, redistribute and/or modify it # under the terms of the GNU General Public License as published by the @@ -47,21 +47,23 @@ #' @export #' @examples #' -#' parser <- ArgumentParser(description='Process some integers') -#' parser$add_argument('integers', metavar='N', type = "integer", nargs='+', -#' help='an integer for the accumulator') -#' parser$add_argument('--sum', dest='accumulate', action='store_const', -#' const='sum', default='max', -#' help='sum the integers (default: find the max)') -#' parser$print_help() -#' # default args for ArgumentParser()$parse_args are commandArgs(TRUE) -#' # which is what you'd want for an Rscript but not for interactive use -#' args <- parser$parse_args(c("--sum", "1", "2", "3")) -#' accumulate_fn <- get(args$accumulate) -#' print(accumulate_fn(args$integers)) +#' if (argparse:::detects_python()) { +#' parser <- ArgumentParser(description='Process some integers') +#' parser$add_argument('integers', metavar='N', type = "integer", nargs='+', +#' help='an integer for the accumulator') +#' parser$add_argument('--sum', dest='accumulate', action='store_const', +#' const='sum', default='max', +#' help='sum the integers (default: find the max)') +#' parser$print_help() +#' # default args for ArgumentParser()$parse_args are commandArgs(TRUE) +#' # which is what you'd want for an Rscript but not for interactive use +#' args <- parser$parse_args(c("--sum", "1", "2", "3")) +#' accumulate_fn <- get(args$accumulate) +#' print(accumulate_fn(args$integers)) +#' } ArgumentParser <- function(..., python_cmd = NULL) { # nolint - python_cmd <- .find_python_cmd(python_cmd) - .assert_python_cmd(python_cmd) + python_cmd <- find_python_cmd(python_cmd) + assert_python_cmd(python_cmd) initial_python_code <- c("import argparse", "try:", " import json", @@ -294,7 +296,7 @@ get_Rscript_filename <- function() { # nolint # Internal function to check python cmd is okay # @param python_cmd Python cmd to use -.assert_python_cmd <- function(python_cmd) { +assert_python_cmd <- function(python_cmd) { if (!findpython::is_python_sufficient(python_cmd, required_modules = c("argparse", "json | simplejson"))) { stop(paste(sprintf("python executable %s either is not installed,", python_cmd), "is not on the path, or does not have argparse, json modules", @@ -302,9 +304,15 @@ get_Rscript_filename <- function() { # nolint } } +detects_python <- function() { + python_cmd <- find_python_cmd() + findpython::is_python_sufficient(python_cmd, + required_modules = c("argparse", "json | simplejson")) +} + # Internal function to find python cmd # @param python_cmd Python cmd to use -.find_python_cmd <- function(python_cmd) { +find_python_cmd <- function(python_cmd = NULL) { if (is.null(python_cmd)) { python_cmd <- getOption("python_cmd") } diff --git a/cran-comments.rst b/cran-comments.rst index 3f930db..c70513e 100644 --- a/cran-comments.rst +++ b/cran-comments.rst @@ -1,7 +1,8 @@ -**Nota benes** +## Notes -* This update should fix the new ``r-devel-linux-x86-64-debian-gcc`` package check error - (seems to be result of non-reverse-compatible python update). +* The examples and unit tests are now skipped if an appropriate + version of Python is not found as with the 'r-devel-windows-x86_64-gcc10-UCRT' + CRAN flavor. * As in previous uploads while in a non-interactive session (i.e. in an Rscript) if ``parse_args()`` observes a help flag it will print a usage @@ -13,18 +14,21 @@ * This package has a Python dependency most easily satisfied having (C)Python 3.2 or greater on the PATH. See file INSTALL for more details. -**Test environments** +## Test environments -* local (linux), R 4.0.3 +* local (linux), R 4.1.0 * win-builder (windows), R devel -* appveyor (windows), R release and R devel -* travis-ci (OSX), R release -* travis-ci (linux), R release and R devel +* Github Actions (linux), R release and R devel +* Github Actions (windows), R release +* Github Actions (OSX), R release -**R CMD check --as-cran results** +## R CMD check --as-cran results Status: OK -**Downstream dependencies** +## revdepcheck results -This package does not have any downstream dependencies. +We checked 3 reverse dependencies (0 from CRAN + 3 from Bioconductor), comparing R CMD check results across CRAN and dev versions of this package. + + * We saw 0 new problems + * We failed to check 0 packages diff --git a/man/ArgumentParser.Rd b/man/ArgumentParser.Rd index cf118a9..eec89f8 100644 --- a/man/ArgumentParser.Rd +++ b/man/ArgumentParser.Rd @@ -33,18 +33,20 @@ a wrapper to Python's argparse module \examples{ -parser <- ArgumentParser(description='Process some integers') -parser$add_argument('integers', metavar='N', type = "integer", nargs='+', - help='an integer for the accumulator') -parser$add_argument('--sum', dest='accumulate', action='store_const', - const='sum', default='max', - help='sum the integers (default: find the max)') -parser$print_help() -# default args for ArgumentParser()$parse_args are commandArgs(TRUE) -# which is what you'd want for an Rscript but not for interactive use -args <- parser$parse_args(c("--sum", "1", "2", "3")) -accumulate_fn <- get(args$accumulate) -print(accumulate_fn(args$integers)) +if (argparse:::detects_python()) { + parser <- ArgumentParser(description='Process some integers') + parser$add_argument('integers', metavar='N', type = "integer", nargs='+', + help='an integer for the accumulator') + parser$add_argument('--sum', dest='accumulate', action='store_const', + const='sum', default='max', + help='sum the integers (default: find the max)') + parser$print_help() + # default args for ArgumentParser()$parse_args are commandArgs(TRUE) + # which is what you'd want for an Rscript but not for interactive use + args <- parser$parse_args(c("--sum", "1", "2", "3")) + accumulate_fn <- get(args$accumulate) + print(accumulate_fn(args$integers)) +} } \references{ Python's \code{argparse} library, which this package is based on, diff --git a/tests/test_help.Rout.save b/tests/test_help.Rout.save deleted file mode 100644 index d513425..0000000 --- a/tests/test_help.Rout.save +++ /dev/null @@ -1,26 +0,0 @@ - -R version 3.3.2 (2016-10-31) -- "Sincere Pumpkin Patch" -Copyright (C) 2016 The R Foundation for Statistical Computing -Platform: x86_64-pc-linux-gnu (64-bit) - -R is free software and comes with ABSOLUTELY NO WARRANTY. -You are welcome to redistribute it under certain conditions. -Type 'license()' or 'licence()' for distribution details. - - Natural language support but running in an English locale - -R is a collaborative project with many contributors. -Type 'contributors()' for more information and -'citation()' on how to cite R or R packages in publications. - -Type 'demo()' for some demos, 'help()' for on-line help, or -'help.start()' for an HTML browser interface to help. -Type 'q()' to quit R. - -> library("argparse") -> p <- ArgumentParser() -> p$parse_args("--help") -usage: PROGRAM [-h] - -optional arguments: - -h, --help show this help message and exit diff --git a/tests/test_version.Rout.save b/tests/test_version.Rout.save deleted file mode 100644 index 93d4473..0000000 --- a/tests/test_version.Rout.save +++ /dev/null @@ -1,24 +0,0 @@ - -R version 3.3.2 (2016-10-31) -- "Sincere Pumpkin Patch" -Copyright (C) 2016 The R Foundation for Statistical Computing -Platform: x86_64-pc-linux-gnu (64-bit) - -R is free software and comes with ABSOLUTELY NO WARRANTY. -You are welcome to redistribute it under certain conditions. -Type 'license()' or 'licence()' for distribution details. - - Natural language support but running in an English locale - -R is a collaborative project with many contributors. -Type 'contributors()' for more information and -'citation()' on how to cite R or R packages in publications. - -Type 'demo()' for some demos, 'help()' for on-line help, or -'help.start()' for an HTML browser interface to help. -Type 'q()' to quit R. - -> library("argparse") -> p <- ArgumentParser() -> p$add_argument("-v", "--version", action = "version", version = "1.0.1") -> p$parse_args("--version") -1.0.1 diff --git a/tests/test_help.R b/tests/testthat/scripts/test_help.R similarity index 64% rename from tests/test_help.R rename to tests/testthat/scripts/test_help.R index 6beb057..d8fb538 100644 --- a/tests/test_help.R +++ b/tests/testthat/scripts/test_help.R @@ -1,3 +1,3 @@ library("argparse") p <- ArgumentParser() -p$parse_args("--help") +p$parse_args() diff --git a/tests/test_version.R b/tests/testthat/scripts/test_version.R similarity index 81% rename from tests/test_version.R rename to tests/testthat/scripts/test_version.R index 08b287c..a534c36 100644 --- a/tests/test_version.R +++ b/tests/testthat/scripts/test_version.R @@ -1,4 +1,4 @@ library("argparse") p <- ArgumentParser() p$add_argument("-v", "--version", action = "version", version = "1.0.1") -p$parse_args("--version") +p$parse_args() diff --git a/tests/testthat/test-argparse.R b/tests/testthat/test-argparse.R index aa819c8..2ad58c3 100644 --- a/tests/testthat/test-argparse.R +++ b/tests/testthat/test-argparse.R @@ -1,4 +1,4 @@ -# Copyright (c) 2012-2018 Trevor L Davis +# Copyright (c) 2012-2021 Trevor L Davis # # This file is free software: you may copy, redistribute and/or modify it # under the terms of the GNU General Public License as published by the @@ -21,10 +21,9 @@ # Python (GPL-compatible) license stack. context("Unit tests") -options(python_cmd = .find_python_cmd(NULL)) -# options(python_cmd = "/home/trevorld/tmp/python/Python-3.9.0/python") # nolint context("print_help") test_that("print_help works as expected", { + skip_if_not(detects_python()) parser <- ArgumentParser(description = "Process some integers.") expect_output(parser$print_help(), "usage:") expect_output(parser$print_help(), "optional arguments:") @@ -42,6 +41,7 @@ test_that("print_help works as expected", { context("convert_agument") test_that("convert_argument works as expected", { + skip_if_not(detects_python()) expect_equal(convert_argument("foobar"), "'foobar'") expect_equal(convert_argument(14.9), "14.9") expect_equal(convert_argument(c(12.1, 14.9)), "(12.1, 14.9)") @@ -50,6 +50,7 @@ test_that("convert_argument works as expected", { context("convert_..._to_arguments") test_that("convert_..._to_arguments works as expected", { + skip_if_not(detects_python()) # test in mode "add_argument" c.2a <- function(...) convert_..._to_arguments("add_argument", ...) waz <- "wazzup" @@ -71,6 +72,7 @@ test_that("convert_..._to_arguments works as expected", { context("add_argument") test_that("add_argument works as expected", { + skip_if_not(detects_python()) parser <- ArgumentParser() parser$add_argument("integers", metavar = "N", type = "integer", nargs = "+", help = "an integer for the accumulator") @@ -119,6 +121,7 @@ test_that("add_argument works as expected", { context("version") test_that("version flags works as expected", { + skip_if_not(detects_python()) # Feature request of Dario Beraldi parser <- ArgumentParser() parser$add_argument("-v", "--version", action = "version", version = "1.0.1") @@ -136,6 +139,7 @@ test_that("version flags works as expected", { context("ArgumentParser") test_that("ArgumentParser works as expected", { + skip_if_not(detects_python()) parser <- ArgumentParser(prog = "foobar", usage = "%(prog)s arg1 arg2") parser$add_argument("--hello", dest = "saying", action = "store_const", const = "hello", default = "bye", @@ -149,7 +153,9 @@ test_that("ArgumentParser works as expected", { expect_error(ArgumentParser(add_help = TRUE)$parse_args("-h"), "help requested") expect_error(ArgumentParser(add_help = FALSE)$parse_args("-h"), "unrecognized arguments") }) + test_that("parse_args works as expected", { + skip_if_not(detects_python()) parser <- ArgumentParser("foobar", usage = "%(prog)s arg1 arg2") parser$add_argument("--hello", dest = "saying", action = "store", default = "foo", choices = c("foo", "bar"), @@ -192,6 +198,7 @@ test_that("parse_args works as expected", { # Bug found by Erick Rocha Fonseca context("Unicode arguments/options") test_that("Unicode support works if Python and OS sufficient", { + skip_if_not(detects_python()) skip_on_os("windows") # Didn't work on win-builder skip_on_cran() # Didn't work on Debian Clang did_find_python3 <- findpython::can_find_python_cmd(minimum_version = "3.0", @@ -202,7 +209,9 @@ test_that("Unicode support works if Python and OS sufficient", { p$add_argument("name") expect_equal(p$parse_args("\u8292\u679C"), list(name = "\u8292\u679C")) # 芒果 }) + test_that("Unicode attempt throws error if Python or OS not sufficient", { + skip_if_not(detects_python()) skip_on_os("windows") # Didn't work on AppVeyor skip_on_cran() # Didn't work on Debian Clang did_find_python2 <- findpython::can_find_python_cmd(maximum_version = "2.7", @@ -218,6 +227,7 @@ test_that("Unicode attempt throws error if Python or OS not sufficient", { # Mutually exclusive groups is a feature request by Vince Reuter context("Mutually exclusive groups") test_that("mutually exclusive groups works as expected", { + skip_if_not(detects_python()) parser <- ArgumentParser(prog = "PROG") group <- parser$add_mutually_exclusive_group() group$add_argument("--foo", action = "store_true") @@ -240,6 +250,7 @@ test_that("mutually exclusive groups works as expected", { # argument groups is a feature request by Dario Beraldi context("Add argument group") test_that("add argument group works as expected", { + skip_if_not(detects_python()) parser <- ArgumentParser(prog = "PROG", add_help = FALSE) group1 <- parser$add_argument_group("group1", "group1 description") group1$add_argument("foo", help = "foo help") @@ -252,6 +263,7 @@ test_that("add argument group works as expected", { # subparser support is a feature request by Zebulun Arendsee context("Supparser support") test_that("sub parsers work as expected", { + skip_if_not(detects_python()) # create the top-level parser parser <- ArgumentParser(prog = "PROG") parser$add_argument("--foo", action = "store_true", help = "foo help") @@ -276,3 +288,20 @@ test_that("sub parsers work as expected", { expect_output(parser_a$print_help(), "usage: PROG a") expect_output(parser_b$print_help(), "usage: PROG b") }) + +context("Paths that quit()") +test_that("Paths that quit()", { + skip_if_not(detects_python()) + skip_on_os("windows") + cmd <- file.path(R.home(), "bin/Rscript") + skip_if(Sys.which(cmd) == "") + + expect_equal(system2(cmd, c("scripts/test_version.R", "--version"), stdout = TRUE), + "1.0.1") + + help <- system2(cmd, c("scripts/test_help.R", "--help"), + stdout = TRUE, stderr = TRUE) + expect_equal(help, + c("usage: scripts/test_help.R [-h]", "", "optional arguments:", + " -h, --help show this help message and exit")) +})