diff --git a/NAMESPACE b/NAMESPACE index 04266082..30112f5b 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -177,6 +177,7 @@ export(py_has_attr) export(py_help) export(py_help_handler) export(py_id) +export(py_import_from) export(py_install) export(py_is_null_xptr) export(py_iterator) diff --git a/R/import.R b/R/import.R index b6fe2138..211b1ed8 100644 --- a/R/import.R +++ b/R/import.R @@ -252,5 +252,37 @@ import_from_path_immediate <- function(module, path, convert) { } - +#' Import objects from a Python module +#' +#' @param module string, name of python module +#' @param ... names of objects to import as bare expressions. Can be named to +#' change the binding name in R. rlang dynamic dots are supported. +#' @param .convert passed on to `import()` +#' @param .env R environment where to assign the imported symbols. +#' +#' @details This function is useful for porting the Python idiom `from foo +#' import abc, hjk, xyz` to R. Here are few examples: +#' +#' | Python | R | +#' |---------------------------------------------|--------------------------------------------------| +#' | `from numpy import abs` | `py_import_from("numpy", abs)` | +#' | `from jax import grad, jit, vmap` | `py_import_from("jax", grad, jit, vmap)` | +#' | `from datetime import date as d, time as t` | `py_import_from("datetime", d = date, t = time)` | +#' +#' @return `NULL` invisibly. This function is called for its side effect of +#' assigning symbols in `.env`. +#' @export +py_import_from <- function(module, ..., .convert = TRUE, .env = parent.frame()) { + module <- import(module, convert = .convert) + dots <- lapply( + rlang::ensyms(..., .named = TRUE, .ignore_empty = "all", + .ignore_null = "none", .homonyms = "error", + .unquote_names = TRUE, .check_assign = TRUE), + function(name) { + py_maybe_convert(py_get_attr(module, as.character(name)), + .convert) + }) + list2env(dots, envir = .env) + invisible() +} diff --git a/man/py_import_from.Rd b/man/py_import_from.Rd new file mode 100644 index 00000000..fe65713f --- /dev/null +++ b/man/py_import_from.Rd @@ -0,0 +1,33 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/import.R +\name{py_import_from} +\alias{py_import_from} +\title{Import objects from a Python module} +\usage{ +py_import_from(module, ..., .convert = TRUE, .env = parent.frame()) +} +\arguments{ +\item{module}{string, name of python module} + +\item{...}{names of objects to import as bare expressions. Can be named to +change the binding name in R. rlang dynamic dots are supported.} + +\item{.convert}{passed on to \code{import()}} + +\item{.env}{R environment where to assign the imported symbols.} +} +\value{ +\code{NULL} invisibly. This function is called for its side effect of +assigning symbols in \code{.env}. +} +\description{ +Import objects from a Python module +} +\details{ +This function is useful for porting the Python idiom \verb{from foo import abc, hjk, xyz} to R. Here are few examples:\tabular{ll}{ + Python \tab R \cr + \verb{from numpy import abs} \tab \code{py_import_from("numpy", abs)} \cr + \verb{from jax import grad, jit, vmap} \tab \code{py_import_from("jax", grad, jit, vmap)} \cr + \verb{from datetime import date as d, time as t} \tab \code{py_import_from("datetime", d = date, t = time)} \cr +} +}