Looking for help to design a test with modified frame stack

I've a package that write files when knitr exits. I do so by deferring the writing function in knitr frame. Initially, I used a fixed number to retrieve the correct frame, but this approach breaks when loading the conflicted package first (see pakret doesn't populate `.bib` files if loaded after conflicted · Issue #30 · arnaudgallou/pakret · GitHub). I suspect this happens because conflicted alters the frame stack.

I've a simple fix to get the correct frame automatically. I now would like to add a test for it. I'm struggling with how to emulate the behavior of conflicted though. I tried to attach a dummy environment before loading my package but that doesn't seem to work as expected. Unfortunately, looking at the source code of conflicted::conflicts_prefer() hasn't been very helpful.

I'd greatly appreciate any guidance on how to alter the frame stack to design my test.

1 Like

Interesting problem. Would you able to provide some toy code to demonstrate what you've tried? And could you provide some more insight into how you want to manipulate the frames? Maybe you could run sys.status() in your desired setup.

For now, I simply load the library in a wrapper function to add a frame on top of it. This is certainly the simplest solution and enough to run my test.

(function() library(pakret))()
# ran in reprex::reprex()
# hence the high number of frames

print(sys.nframe())
#> [1] 39
(function() {
  print(sys.nframe())
  # library(pakret)
})()
#> [1] 40

I initially wanted to replicate the following behavior without using conflicted explicitly. I'm still interested in it for the sake of learning though.

conflicted::conflicts_prefer(dplyr::filter)
#> [conflicted] Will prefer dplyr::filter over any other package.
library(rlang)
search()
#>  [1] ".GlobalEnv"        ".conflicts"        "package:rlang"    
#>  [4] "package:stats"     "package:graphics"  "package:grDevices"
#>  [7] "package:utils"     "package:datasets"  "package:methods"  
#> [10] "Autoloads"         "tools:callr"       "package:base"

Created on 2025-10-08 with reprex v2.1.1

I'm not 100% sure, but I think the reason conflicted breaks my package is that it modifies the search path in such a way that the .conflicts environment stays in position 2. I presume the magic happens with rlang::env_bind() (called inside conflicted:::shims_bind()). It's written in C so I can't really read it.

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.

If you have a query related to it or one of the replies, start a new topic and refer back with a link.