From d77cc689ec8e87d8146ab575c4b44514308039da Mon Sep 17 00:00:00 2001 From: Tomasz Kalinowski Date: Wed, 13 Nov 2024 09:29:37 -0500 Subject: [PATCH] implement `ChildrenOverflow` for >100 children --- R/ark-variables-methods.R | 43 ++++++++++++++++----------- R/zzz.R | 11 ++++--- inst/python/rpytools/ark_variables.py | 33 ++++++++++++++++++++ 3 files changed, 65 insertions(+), 22 deletions(-) create mode 100644 inst/python/rpytools/ark_variables.py diff --git a/R/ark-variables-methods.R b/R/ark-variables-methods.R index 066160f2e..4db8c949e 100644 --- a/R/ark-variables-methods.R +++ b/R/ark-variables-methods.R @@ -17,7 +17,7 @@ ark_positron_variable_display_type.python.builtin.object <- function(x, ..., inc i <- .globals$get_positron_variable_inspector(x) out <- i$get_display_type() - if(startsWith(class(x)[1], "python.builtin.")) + if (startsWith(class(x)[1], "python.builtin.")) # display convert value? out <- paste("python", out) out @@ -44,17 +44,15 @@ ark_positron_variable_get_children.python.builtin.object <- function(x, ...) { get_keys_and_children <- .globals$ark_variable_get_keys_and_children if (is.null(get_keys_and_children)) { - get_keys_and_children <- .globals$ark_variable_get_keys_and_children <- py_eval( - "lambda i: zip(*((str(key), i.get_child(key)) for key in i.get_children()))", - convert = FALSE - ) + get_keys_and_children <- .globals$ark_variable_get_keys_and_children <- + import("rpytools.ark_variables", convert = FALSE)$get_keys_and_children } keys_and_children <- iterate(get_keys_and_children(i), simplify = FALSE) - out <- iterate(keys_and_children[[2L]], simplify = FALSE) - names(out) <- as.character(py_to_r(keys_and_children[[1L]])) + children <- iterate(keys_and_children[[2L]], simplify = FALSE) + names(children) <- as.character(py_to_r(keys_and_children[[1L]])) - out + children } #' @param index An integer > 1, representing the index position of the child in the @@ -70,16 +68,25 @@ ark_positron_variable_get_child_at.python.builtin.object <- function(x, ..., nam i <- .globals$get_positron_variable_inspector(x) get_child <- .globals$ark_variable_get_child if (is.null(get_child)) { - get_child <- .globals$ark_variable_get_child <- py_run_string( - local = TRUE, convert = FALSE, " -def new_get_child(): - from itertools import islice - def get_child(inspector, index): - key = next(islice(inspector.get_children(), index-1, None)) - return inspector.get_child(key) - return get_child -")$new_get_child() + get_child <- .globals$ark_variable_get_child <- + import("rpytools.ark_variables", convert = FALSE)$get_child + } + + get_child(i, index) } - get_child(i, index) + +ark_positron_variable_display_type.rpytools.ark_variables.ChildrenOverflow <- function(x, ..., include_length = TRUE) { + "" +} +ark_positron_variable_kind.rpytools.ark_variables.ChildrenOverflow <- function(x, ...) { + "empty" # other? collection? map? lazy? +} + +ark_positron_variable_display_value.rpytools.ark_variables.ChildrenOverflow <- function(x, ..., width = getOption("width")) { + paste(py_to_r(x$n_remaining), "more values") +} + +ark_positron_variable_has_children.rpytools.ark_variables.ChildrenOverflow <- function(x, ...) { + FALSE } diff --git a/R/zzz.R b/R/zzz.R index a4befd2c2..bbdfe1858 100644 --- a/R/zzz.R +++ b/R/zzz.R @@ -84,10 +84,13 @@ "ark_positron_variable_get_child_at", "ark_positron_variable_get_children" )) { - method_sym <- as.name(paste0(method_name, ".python.builtin.object")) - .ark.register_method( - method_name, "python.builtin.object", - call(":::", quote(reticulate), method_sym)) + for (class_name in c("python.builtin.object", + "rpytools.ark_variables.ChildrenOverflow")) { + method <- get0(paste0(method_name, ".", class_name)) + if (!is.null(method)) { + .ark.register_method(method_name, class_name, method) + } + } } }) } diff --git a/inst/python/rpytools/ark_variables.py b/inst/python/rpytools/ark_variables.py new file mode 100644 index 000000000..180c8c1eb --- /dev/null +++ b/inst/python/rpytools/ark_variables.py @@ -0,0 +1,33 @@ +from itertools import islice + +MAX_DISPLAY = 100 + +def get_keys_and_children(inspector): + keys, values = [], [] + keys_iterator = iter(inspector.get_children()) + # positron frontend only displays the first 100 items, then the length of the rest. + try: + for _ in range(MAX_DISPLAY): + key = next(keys_iterator) + keys.append(str(key)) + values.append(inspector.get_child(key)) + except StopIteration: + return keys, values + + n_remaining = 0 + for n_remaining, _ in enumerate(keys_iterator, 1): + pass + if n_remaining > 0: + keys.append("[[...]]") + values.append(ChildrenOverflow(n_remaining)) + + return keys, values + + +def get_child(inspector, index): + key = next(islice(inspector.get_children(), index - 1, None)) + return inspector.get_child(key) + +class ChildrenOverflow: + def __init__(self, n_remaining): + self.n_remaining = n_remaining