Skip to content

print implementations should not mix output to stdout and messages from cli functions #277

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

Closed
brookslogan opened this issue Dec 15, 2023 · 4 comments · Fixed by #280
Closed

Comments

@brookslogan
Copy link
Contributor

brookslogan commented Dec 15, 2023

E.g., mixing cat (printing to output stream) and {cli} functions ([issuing messages that knitr intercepts or] printing to message stream) in print.epi_recipe and print.frosting leads to some trouble with knitting documents.

E.g., trying to rebuild forecast-framework.qmd in delphi-tooling book has this in a chunk with #| collapse: true earlier in the document for printing an epi_recipe:

#> ── Operations
#> 1.
#> Lagging: case_rate by 0, 7, 14 | Trained
#> 2.
#> Lagging: death_rate by 0, 7, 14 | Trained
#> 3.
#> Leading: death_rate by 7 | Trained
#> 4.
#> • Removing rows with NA values in: lag_0_case_rate, ... | Trained
#> 5.
#> • Removing rows with NA values in: ahead_7_death_rate | Trained
#> 6.
#> • # of recent observations per key limited to:: Inf | Trained

or, when printing a frosting with some other set of options:

2023-12-15-023636_759x588_scrot

It also messes with capture.output, which only captures one stream at a time (ordering is lost).

Potential fixes:

  • See if cat can print to message stream via file argument.
  • Replace cat with something like cli::cli_text with appropriate escaping/interpolation of programmatically-constructed/user-input/etc. strings, if it outputs in an acceptable format.
@brookslogan
Copy link
Contributor Author

brookslogan commented Dec 15, 2023

Workaround for capture.output at REPL:

with_message_in_stdout <- function(code) {
  sink(stdout(), type = "message")
  on.exit({
    sink(type = "message")
  })
  code
}

capture.output(with_message_in_stdout(print(extract_recipe(out_gb$epi_workflow))))
#> ...
#> [14] "1. Lagging: case_rate by 0, 7, 14 | Trained"                                  
#> ...

But this doesn't seem to fix the qmd/knitr issues; in this context, the streams still appear to be separate, and capture.output can only capture one or the other at a time. [And I'm not sure how to apply this setting in .qmd.]

@brookslogan
Copy link
Contributor Author

brookslogan commented Dec 15, 2023

Workaround for .qmd:

withCallingHandlers(
  print(extract_recipe(out_gb$epi_workflow)),
  message = function(m) {cat(m$message); tryInvokeRestart("muffleMessage")}
)

[See here for people also suggesting this approach and discussion + link to the NA setting I couldn't figure out how to apply.]

@brookslogan brookslogan changed the title print implementations should not mix output to "output" and "message" streams print implementations should not mix output to stdout and messages from cli functions Dec 15, 2023
@dajmcdon
Copy link
Contributor

I've tried dealing with this in various ways in the past. The version in {recipes} was somewhat recently updated but {workflows} still mixes: https://github.com/tidymodels/workflows/blob/main/R/workflow.R.

A while back I'd found an open issue for this problem (cli resulting in breaks via knitr html) in one of the tidy packages, but I can't find it now.

@dajmcdon
Copy link
Contributor

@rachlobay This happens in your #274 as well.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants