Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

knitr engine with python: output option ignored for object with _repr_html_ method #9389

Closed
machow opened this issue Apr 16, 2024 · 12 comments
Closed
Labels
bug Something isn't working knitr upstream Bug is in upstream library

Comments

@machow
Copy link

machow commented Apr 16, 2024

Bug description

When rendering a qmd with a mix of python and R code cells, the output option seems to be ignored for some objects. At first glance, it seems like it's ignored for objects with IPython display hooks (e.g. _repr_html_).

Steps to reproduce

The qmd below was provided by @AlbertRapp (and tweaked a bit to reduce to anything with _repr_html_) in posit-dev/great-tables#291.

Note that output is respected in some cases, but not in others.

```{r}
#| output: false
# R code chunk
1 + 1
```

```{python}
#| output: false
# This PYTHON output is suppressed
1 + 1
```

```{python}
#| output: false

class MyClass:
    def _repr_html_(self):
        return "<p>uh-oh</p>"

MyClass()
```

Expected behavior

No output is shown for cells with output set to false

Actual behavior

Output is shown for objects with a ._repr_html_() method

Your environment

Mac OS 14.4.1

Quarto check output

Quarto 1.4.549
[✓] Checking versions of quarto binary dependencies...
      Pandoc version 3.1.11: OK
      Dart Sass version 1.69.5: OK
      Deno version 1.37.2: OK
[✓] Checking versions of quarto dependencies......OK
[✓] Checking Quarto installation......OK
      Version: 1.4.549
      Path: /Applications/quarto/bin

[✓] Checking tools....................OK
      TinyTeX: (not installed)
      Chromium: (not installed)

[✓] Checking LaTeX....................OK
      Tex:  (not detected)

[✓] Checking basic markdown render....OK

[✓] Checking Python 3 installation....OK
      Version: 3.10.11
      Path: /Users/machow/.pyenv/versions/3.10.11/bin/python3
      Jupyter: (None)

      Jupyter is not available in this Python installation.
      Install with python3 -m pip install jupyter

R scripting front-end version 4.1.2 (2021-11-01)
[✓] Checking R installation...........(None)

      Unable to locate an installed version of R.
      Install R from https://cloud.r-project.org/
@mcanouil
Copy link
Collaborator

mcanouil commented Apr 16, 2024

I believe this is an issue with knitr or reticulate directly.

CC. @cderv

Rmarkdown documentHTML
---
title: "Quarto Playground"
output: html_document
---

This is a playground for Quarto.

```{r}
#| results: false
# R code chunk
1 + 1
```

```{python}
#| results: false
# This PYTHON output is suppressed
1 + 1
```

```{python}
#| results: false
class MyClass:
    def _repr_html_(self):
        return "<p>uh-oh</p>"

MyClass()
```
image

@mcanouil mcanouil added the upstream Bug is in upstream library label Apr 16, 2024
@mcanouil
Copy link
Collaborator

mcanouil commented Apr 16, 2024

It's definitely an issue (or a "feature") from reticulate:

@cscheid cscheid closed this as not planned Won't fix, can't repro, duplicate, stale Apr 16, 2024
@mcanouil
Copy link
Collaborator

@machow I suggest your report this on reticulate repository.

@machow
Copy link
Author

machow commented Apr 18, 2024

@mcanouil or @cscheid can you say a little bit more about what quarto is doing, and how it relates to the code you shared?

For example, the qmd has the option output: false, but that option is not one that knitr uses. I'm sure there's some small transformation on the quarto side -> knitr, but I do not have enough context to keep investigating (we are a long way from Great Tables; I'm okay following this through, but am missing a maybe negligible quarto detail)

Edit: depending on quarto's intention for output vs the more knitr-centric results or fig-show, it seems like this might be a quarto bug?

@mcanouil
Copy link
Collaborator

Indeed, "output" does not exist in knitr, "results" does.
"output" is an alias and does the same thing as "results".

  • # forward output: false option to results, fig.show, warning, and message
    if (isFALSE(format$execute[["output"]])) {
    opts_chunk$results <- "hide"
    opts_chunk$fig.show <- "hide"
    opts_chunk$warning <- FALSE
    opts_chunk$message <- FALSE
    } else if (identical(format$execute[["output"]], "asis")) {
    opts_chunk$results <- "asis"
    }

However, based on my understanding, the reticulate package appears to be the critical component in the interplay of knitr, reticulate, and Quarto.

@cderv is clearly the one with the best understanding regarding this.

@cscheid
Copy link
Collaborator

cscheid commented Apr 19, 2024

can you say a little bit more about what quarto is doing, and how it relates to the code you shared?

Quarto isn't the one doing anything here. The interpretation of cell options is all handled by reticulate in the case of Python cells in a documented rendered by the knitr engine.

@machow
Copy link
Author

machow commented Apr 19, 2024

Thanks for taking the time to clarify! The piece I'm still a bit confused on is still the intent of the output: option. From the quarto docs (on knitr engine):

image

By "results" in the description of output:, do you mean "text results"?

I think the ambiguity is that...

  • The word "results" in the description of output: currently means "text results" (or maybe w/e results: does).
  • The word "results in the description of include: means all results.

So if set include: false, something different happens (all output is hidden). It feels like this comes down to quarto's intention behind output:. Is it meant to only hide text results or all results? (or to just punt to knitr results:, which I can make peace with :).

@machow
Copy link
Author

machow commented Apr 19, 2024

For posterity, I think the easiest workaround for people in this situation is using a semi-colon to suppress python output:

```{python}
class MyClass:
    def _repr_html_(self):
        return "<p>uh-oh</p>"


MyClass();               # <---- NOTE THE SEMI COLON 
```

@mcanouil
Copy link
Collaborator

mcanouil commented Apr 19, 2024

From knitr: https://yihui.org/knitr/options/

image image

So include still produces output just not as text while results managed all text output.
Note that in knitr an image is a text output as what's actually emitted is ![](path/to/image.png).

@cderv
Copy link
Collaborator

cderv commented Apr 23, 2024

Sorry - I was off last week.

This is definitely a reticulate issue. It is not handling the results = 'hide' option correctly for element created when _repr_html_ is present (like great_table outputs). So when knitr applies on the results, it is too late to suppress the output, because results = 'asis' will apply (so that the created HTML output is correctly inserted).

Not directly quarto related, but still a quarto issue in a way as output: false should definitely work for this !

Thanks for the report @machow - I'll open an issue in reticulate

@machow
Copy link
Author

machow commented Apr 24, 2024

@cderv thanks for taking a look. I'm confused on why reticulate should hide this, when R in an Rmd + ggplot would produce the graph.

test.Rmd

```{r, results="hide"}
library(ggplot2)

ggplot(mtcars, aes(cyl, mpg)) + geom_point()
```

Note that the graph is produced and included in the knitted output.

RE @mcanouil 's point:

So include still produces output just not as text while results managed all text output. Note that in knitr an image is a text output as what's actually emitted is ![](path/to/image.png). (emph added)

knitr provides a fig.show option to disable outputs like these. So it seems clear in knitr something like ![](path/to/image.png) is not what's referred to in the explanation of results= as text output.

Is the point here that _repr_html_() is taken to be "text output", basically output as if results="asis"? If so, I could how it's a results="hide" x reticulate bug.

In any event, thanks everyone for being so patient with helping me get a feel for this (I'm going to step away from this issue now, since I use jupyter to execute 😎)

@cderv
Copy link
Collaborator

cderv commented Apr 24, 2024

Thanks a lot for your input. This is precious feedback! I'll be also happy if you stay around 😄 😉

Indeed, the results option does not apply to plots. it applies only to text output from an R evaluation point of view (is.character()). What was said about image output being text does not apply here. The ggplot above is a plot object after evaluation and handled by the fig.show option, as you found.

Tables are not considered figures as of now, this will hide gt table in R for example

```{r, results="hide"}
library(gt)

gt(head(mtcars))
```

That is mainly why I thought a great_tables object in reticulate should be hidden like in R.

reticulate provides an engine that skip a lot of knitr direct handling of evaluated output, so we can adapt differently for python, or try to make it work the same.

Hope this clarify a little what I meant.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working knitr upstream Bug is in upstream library
Projects
None yet
Development

No branches or pull requests

4 participants