Skip to contents

The Python sibling of repro_run_scripts(): runs each script WHOLE, as a python <script> subprocess via processx::run() (not callr, which is R-specific), with the working directory set to the materialised sandbox. Unlike repro_run_scripts()'s callr-based runner, there is no per- statement capture of result objects here (see this file's header for why) — only the whole script's stdout/stderr/exit status/elapsed time are recorded, so captures is always NULL for every row (kept as a column, not dropped, so the module's downstream code that expects the same shape repro_run_scripts() returns does not need to branch by language).

Usage

repro_run_scripts_py(
  run_tbl,
  order,
  lib_dir = NULL,
  python_bin = "python",
  timeout = 600,
  skip = character(0),
  parses = NULL,
  failed_deps = character(0),
  deadline = NULL
)

Arguments

run_tbl

repro_write_scripts() output (file_name, script_path, run_dir)

order

a vector of file_names in the order to run

lib_dir

throwaway pip install --target directory (or NULL) — prepended to PYTHONPATH so an installed dependency is importable

python_bin

the python executable to run scripts with (default "python")

timeout

per-script timeout in seconds

skip

character vector of file_names to record as skipped_missing_inputs instead of running

parses

named logical (by file_name); a file that will not parse (see code_parse_py()/the module's own syntax check) is recorded not_parsed and not run

failed_deps

character vector of package names repro_install_deps_py() could not install

deadline

the time (Sys.time() plus the time for all scripts together) after which no script is started, recorded as skipped_time_limit; a running script is stopped then. NULL (the default) sets no such limit.

Value

a data frame — same columns as repro_run_scripts()'s return: file_name, outcome, error, error_type, undefined_var, stdout, stderr, elapsed, script_lines, captures (always NULL per row — see above)

Details

This isolates a CRASH, not the filesystem or network — the same caveat repro_run_scripts()'s own roxygen states for its callr backend applies identically here: the script can read/write/delete anywhere this process can, and reach the network freely. Use sandbox = "docker" (repro_run_scripts_py_docker()) for code you do not trust.

Examples

if (FALSE) { # \dontrun{
# needs Python
root <- file.path(tempdir(), "run_demo_py")
plan <- data.frame(file_name = "analysis.py", target_path = "analysis/analysis.py")
code <- list(analysis.py = "print(sum([1, 2, 3]))")
run_tbl <- repro_write_scripts(code, list(), plan, root, lang = "Python")
repro_run_scripts_py(run_tbl, order = "analysis.py")
} # }