trevorld / r-argparse

Compare 757a803 ... +6 ... 2181ac1

Coverage Reach
argparse.R

No flags found

Use flags to group coverage reports by test type, project and/or folders.
Then setup custom commit statuses and notifications for each flag.

e.g., #unittest #integration

#production #enterprise

#frontend #backend

Learn more about Codecov Flags here.

Showing 1 of 14 files from the diff.
Other files ignored by Codecov

@@ -39,8 +39,6 @@
Loading
39 39
#'
40 40
#' @references Python's \code{argparse} library, which this package is based on,
41 41
#'  is described here: \url{https://docs.python.org/3/library/argparse.html}
42 -
#' @section Acknowledgement:
43 -
#'     A big thanks to Martin Diehl for a bug report.
44 42
#'
45 43
#' @import jsonlite
46 44
#' @import R6
@@ -134,32 +132,14 @@
Loading
134 132
                            paste(sprintf("'%s'", args), collapse = ", ")),
135 133
                    "print(json.dumps(args.__dict__, sort_keys=True))")
136 134
            output <- private$python_code$run(new_code)
137 -
            if (grepl("^usage:", output[1])) {
138 -
                has_positional_arguments <- any(grepl("^positional arguments:", output))
139 -
                has_optional_arguments <- any(grepl("^optional arguments:", output))
140 -
                if (has_positional_arguments || has_optional_arguments) {
141 -
                    .print_message_and_exit(output, "help requested:")
142 -
                } else {
143 -
                    .stop(output, "parse error:")
144 -
                }
145 -
            } else if (grepl("^Traceback", output[1])) {
146 -
                .stop(output, "Error: python error")
147 -
            } else if (any(grepl("^SyntaxError: Non-ASCII character", output))) {
148 -
                message <- paste("Non-ASCII character detected.",
149 -
                               "If you wish to use Unicode arguments/options",
150 -
                               "please upgrade to Python 3.2+",
151 -
                               "Please see file INSTALL for more details.")
152 -
                .stop(message, "non-ascii character error:")
153 -
            } else if (any(grepl("^SyntaxError: positional argument follows keyword argument", output)) ||
154 -
                       grepl("^SyntaxError: non-keyword arg after keyword arg", output[2])) {
155 -
                message <- "Positional argument following keyword argument."
156 -
                .stop(message, "syntax error:")
157 -
            } else if (grepl("^\\{", output)) {
158 -
                args <- jsonlite::fromJSON(paste(output, collapse = ""))
159 -
                return(args)
160 -
            } else { # presumably version number request
161 -
                .print_message_and_exit(output, "version requested:")
162 -
            }
135 +
            parse_args_output(output)
136 +
        },
137 +
        parse_known_args = function(args = commandArgs(TRUE)) {
138 +
            new_code <- c(sprintf("args_remainder = %s.parse_known_args([%s])", private$name,
139 +
                            paste(sprintf("'%s'", args), collapse = ", ")),
140 +
                    "print(json.dumps((args_remainder[0].__dict__, args_remainder[1])))")
141 +
            output <- private$python_code$run(new_code)
142 +
            parse_args_output(output)
163 143
        },
164 144
        print_help = function() {
165 145
            cat(private$python_code$run(sprintf("%s.print_help()", private$name)), sep = "\n")
@@ -207,14 +187,44 @@
Loading
207 187
                   n_mutually_exclusive_groups = 0, n_groups = 0)
208 188
)
209 189
190 +
parse_args_output <- function(output) {
191 +
    if (grepl("^usage:", output[1])) {
192 +
        has_positional_arguments <- any(grepl("^positional arguments:", output))
193 +
        has_optional_arguments <- any(grepl("^optional arguments:", output))
194 +
        if (has_positional_arguments || has_optional_arguments) {
195 +
            .print_message_and_exit(output, "help requested:")
196 +
        } else {
197 +
            .stop(output, "parse error:")
198 +
        }
199 +
    } else if (grepl("^Traceback", output[1])) {
200 +
        .stop(output, "Error: python error")
201 +
    } else if (any(grepl("^SyntaxError: Non-ASCII character", output))) {
202 +
        message <- paste("Non-ASCII character detected.",
203 +
                       "If you wish to use Unicode arguments/options",
204 +
                       "please upgrade to Python 3.2+",
205 +
                       "Please see file INSTALL for more details.")
206 +
        .stop(message, "non-ascii character error:")
207 +
    } else if (any(grepl("^SyntaxError: positional argument follows keyword argument", output)) ||
208 +
               grepl("^SyntaxError: non-keyword arg after keyword arg", output[2])) {
209 +
        message <- "Positional argument following keyword argument."
210 +
        .stop(message, "syntax error:")
211 +
    } else if (grepl("^\\{|^\\[", output)) {
212 +
        args <- jsonlite::fromJSON(paste(output, collapse = ""))
213 +
        return(args)
214 +
    } else { # presumably version number request
215 +
        .print_message_and_exit(output, "version requested:")
216 +
    }
217 +
}
210 218
211 219
# @param argument argument to be converted from R to Python
212 -
convert_argument <- function(argument) {
220 +
convert_argument <- function(argument, as_list = FALSE) {
213 221
    if (is.character(argument)) argument <- shQuote(argument, type = "sh")
214 222
    if (is.numeric(argument)) argument <- as.character(argument)
215 223
    if (is.logical(argument)) argument <- ifelse(argument, "True", "False")
216 224
    if (is.null(argument)) argument <- "None"
217 -
    if (length(argument) > 1) {
225 +
    if (as_list) {
226 +
        argument <- sprintf("[%s]", paste(argument, collapse = ", "))
227 +
    } else if (length(argument) > 1) {
218 228
        argument <- sprintf("(%s)", paste(argument, collapse = ", "))
219 229
    }
220 230
    argument
@@ -235,6 +245,17 @@
Loading
235 245
    sprintf("type=%s", python_type)
236 246
}
237 247
248 +
should_as_list <- function(name, argument_list) {
249 +
    if (name == "default" &&
250 +
        (argument_list[["action"]] %||% "store") == "append") {
251 +
        TRUE
252 +
    } else {
253 +
        FALSE
254 +
    }
255 +
}
256 +
257 +
`%||%` <- function(x, y) if (is.null(x)) y else x # nolint
258 +
238 259
# @param mode Either "add_argument" or "ArgumentParser"
239 260
convert_..._to_arguments <- function(mode, ...) { # nolint
240 261
@@ -247,7 +268,8 @@
Loading
247 268
    for (ii in seq_along(argument_list)) {
248 269
        name <- argument_names[ii]
249 270
        equal <- equals[ii]
250 -
        argument <- convert_argument(argument_list[[ii]])
271 +
        as_list <- should_as_list(name, argument_list)
272 +
        argument <- convert_argument(argument_list[[ii]], as_list)
251 273
        proposed_arguments <- append(proposed_arguments,
252 274
                                     paste0(name, equal, argument))
253 275
    }
@@ -305,9 +327,8 @@
Loading
305 327
}
306 328
307 329
detects_python <- function() {
308 -
    python_cmd <- find_python_cmd()
309 -
    findpython::is_python_sufficient(python_cmd,
310 -
                                     required_modules = c("argparse", "json | simplejson"))
330 +
    python_cmd <- try(find_python_cmd())
331 +
    !inherits(python_cmd, "try-error")
311 332
}
312 333
313 334
# Internal function to find python cmd

Learn more Showing 1 files with coverage changes found.

Changes in R/argparse.R
-2
+2
Loading file...
Files Coverage
argparse.R +1.83% 93.02%
Project Totals (1 files) 93.02%
Loading