Skip to content

Conversation

Copy link
Contributor

Copilot AI commented Jan 27, 2026

Pull Request

The module print method displayed NULL for decorators when structured as nested lists:

module(
  decorators = list(
    table = list(decorator1, decorator2)
  )
)
# Output showed: Decorators: NULL

Changes

  • R/modules.R: Added recursive helper in format.teal_module() to extract labels from nested decorator structures. Includes depth limit (10) to prevent infinite recursion.

  • tests/testthat/test-modules.R: Added tests for single, flat list, nested list, and mixed decorator structures.

Now correctly displays: Decorators: decorator1, decorator2 regardless of list nesting depth.

Original prompt

This section details on the original issue you should resolve

<issue_title>[Feature Request]: Improve module print method for multiple decorators on the same object</issue_title>
<issue_description>### Feature description

When I create a module with multiple decorators for the same object, the decorators object shows NULL:

tm_module(label = "Multiple decorators", ..., decorators = list(table = list(decorator1(), decorator2()))
|- Multiple decorators
...
|  |- Decorators       : NULL
|  L- Transformators   : 

I would expect it would have the labels of each decorator:

|- Multiple decorators
...
|  |- Decorators       : decorator1, decorator2
|  L- Transformators   : 

Code of Conduct

  • I agree to follow this project's Code of Conduct.

Contribution Guidelines

  • I agree to follow this project's Contribution Guidelines.

Security Policy

  • I agree to follow this project's Security Policy.</issue_description>

Comments on the Issue (you are @copilot in this section)

@donyunardi ### Acceptance Criteria * Show the assigned decorator's label in the module's print method * Have tests on the structure of how multiple decorators for one or multiple objects should be added.

Discussion also brought up the private helpers srv_decorate_teal_data(), ui_decorate_teal_data()on TMG and TMC</comment_new>


💬 We'd love your input! Share your thoughts on Copilot coding agent in our 2 minute survey.

Copilot AI and others added 2 commits January 27, 2026 11:06
- Updated format.teal_module to recursively extract decorator labels from nested lists
- Added tests for single, multiple, and nested decorator structures
- Fixes issue where decorators in nested lists showed NULL instead of labels

Co-authored-by: m7pr <133694481+m7pr@users.noreply.github.com>
…action

- Added depth parameter with limit of 10 to prevent potential infinite recursion
- Improved code safety based on code review feedback
- All tests still pass

Co-authored-by: m7pr <133694481+m7pr@users.noreply.github.com>
Copilot AI changed the title [WIP] Improve module print method for multiple decorators Fix module print method for nested decorator lists Jan 27, 2026
Copilot AI requested a review from m7pr January 27, 2026 11:11
@m7pr m7pr marked this pull request as ready for review January 27, 2026 13:21
@m7pr
Copy link
Collaborator

m7pr commented Jan 27, 2026

devtools::load_all()
  decorator1 <- teal_transform_module(
    label = "Decorator One",
    server = function(id, data) {
      moduleServer(id, function(input, output, session) data)
    }
  )

  decorator2 <- teal_transform_module(
    label = "Decorator Two",
    server = function(id, data) {
      moduleServer(id, function(input, output, session) data)
    }
  )

  mod <- module(
    label = "test module",
    server_args = list(decorators = list(decorator1, decorator2))
  )
mod
image

Signed-off-by: Marcin <133694481+m7pr@users.noreply.github.com>
@github-actions
Copy link
Contributor

github-actions bot commented Jan 27, 2026

Unit Tests Summary

  1 files   29 suites   2m 20s ⏱️
407 tests 362 ✅ 45 💤 0 ❌
653 runs  604 ✅ 49 💤 0 ❌

Results for commit 7e94ee2.

♻️ This comment has been updated with latest results.

@github-actions
Copy link
Contributor

github-actions bot commented Jan 27, 2026

Unit Test Performance Difference

Test Suite $Status$ Time on main $±Time$ $±Tests$ $±Skipped$ $±Failures$ $±Errors$
module_teal 💚 $130.71$ $-16.96$ $0$ $0$ $0$ $0$
shinytest2-disable_report 💀 $0.39$ $-0.39$ $-4$ $-4$ $0$ $0$
shinytest2-disable_src 💀 $0.18$ $-0.18$ $-2$ $-2$ $0$ $0$
shinytest2-show-rcode 💀 $0.30$ $-0.30$ $-3$ $-3$ $0$ $0$
shinytest2-teal_modifiers 💀 $0.55$ $-0.55$ $-7$ $-7$ $0$ $0$
Additional test case details
Test Suite $Status$ Time on main $±Time$ Test Case
module_teal 💚 $3.05$ $-1.00$ srv_teal_filters_slicesGlobal_appends_new_slice_and_activates_in_module_when_added_in_a_module_if_module_specific
modules 👶 $+0.01$ format.teal_module_handles_mixed_decorator_structure
modules 👶 $+0.02$ format.teal_module_handles_mixed_global_and_object_specific_decorators
modules 👶 $+0.01$ format.teal_module_prints_decorators_from_complex_nested_structure
modules 👶 $+0.01$ format.teal_module_prints_decorators_from_nested_list_structure
modules 👶 $+0.01$ format.teal_module_prints_multiple_decorators_in_flat_list
modules 👶 $+0.01$ format.teal_module_prints_single_decorator_label
shinytest2-decorators 👶 $+0.03$ unnamed
shinytest2-disable_report 💀 $0.10$ $-0.10$ Add_to_report_button_is_not_disabled_by_default.
shinytest2-disable_report 💀 $0.10$ $-0.10$ Report_button_is_active_on_a_nested_module_by_default
shinytest2-disable_report 💀 $0.10$ $-0.10$ Report_button_is_disabled_on_a_module_changed_by_disable_report_
shinytest2-disable_report 💀 $0.09$ $-0.09$ Report_button_is_disabled_on_nested_modules_changed_by_disable_report_
shinytest2-disable_src 💀 $0.09$ $-0.09$ Show_R_Code_button_is_disabled_on_a_module
shinytest2-disable_src 💀 $0.09$ $-0.09$ Show_R_Code_is_disabled_on_nested_modules_changed_with_disable_src
shinytest2-reporter 👶 $+0.01$ unnamed
shinytest2-show-rcode 💀 $0.10$ $-0.10$ e2e_Module_with_Show_R_Code_has_code
shinytest2-show-rcode 💀 $0.11$ $-0.11$ e2e_Module_with_Show_R_Code_has_modal_with_two_dismiss_and_two_copy_to_clipboard_buttons
shinytest2-show-rcode 💀 $0.09$ $-0.09$ e2e_Module_with_Show_R_Code_initializes_with_visible_button
shinytest2-teal_data_module 👶 $+0.01$ unnamed
shinytest2-teal_modifiers 💀 $0.09$ $-0.09$ e2e_add_landing_modal_displays_landing_modal_on_app_startup
shinytest2-teal_modifiers 💀 $0.07$ $-0.07$ e2e_add_landing_modal_modal_can_be_dismissed
shinytest2-teal_modifiers 💀 $0.07$ $-0.07$ e2e_combined_modifiers_displays_all_customizations_when_chained_together
shinytest2-teal_modifiers 💀 $0.07$ $-0.07$ e2e_modify_footer_displays_custom_footer_in_the_app
shinytest2-teal_modifiers 💀 $0.08$ $-0.08$ e2e_modify_header_displays_custom_header_in_the_app
shinytest2-teal_modifiers 💀 $0.08$ $-0.08$ e2e_modify_title_sets_custom_title_in_the_page_title_head_title_displays_custom_favicon_in_the_app
shinytest2-teal_modifiers 💀 $0.08$ $-0.08$ e2e_modify_title_sets_custom_title_in_the_page_title_head_title_displays_custom_title_in_the_app

Results for commit e9c5e64

♻️ This comment has been updated with latest results.

@github-actions
Copy link
Contributor

github-actions bot commented Jan 27, 2026

badge

Code Coverage Summary

Filename                          Stmts    Miss  Cover    Missing
------------------------------  -------  ------  -------  -----------------------------------------------------------------------------------------------
R/after.R                            59      21  64.41%   42-52, 64, 69, 77-79, 81-89, 100, 104-105
R/checkmate.R                        24       0  100.00%
R/dummy_functions.R                  61       2  96.72%   54, 56
R/include_css_js.R                   11       0  100.00%
R/init.R                            136       0  100.00%
R/module_bookmark_manager.R          99      54  45.45%   78-133
R/module_data_summary.R             177       8  95.48%   40, 50, 205, 236-240
R/module_filter_data.R               64       0  100.00%
R/module_filter_manager.R           207       7  96.62%   116-117, 313, 340, 352, 359-360
R/module_init_data.R                 84       0  100.00%
R/module_nested_tabs.R              371      36  90.30%   163, 267-282, 302-306, 324, 361, 479-482, 486-489, 493-496
R/module_session_info.R              18       0  100.00%
R/module_snapshot_manager.R         272       9  96.69%   302-306, 373, 376-378
R/module_source_code.R               69       0  100.00%
R/module_teal_lockfile.R            131      53  59.54%   45-57, 60-62, 76, 86-88, 100-102, 110-119, 122, 124, 126-127, 142-146, 161-162, 177-186
R/module_teal_reporter.R            122       9  92.62%   60, 77-78, 81, 98, 128, 142, 144, 158
R/module_teal.R                     211       7  96.68%   127, 142-143, 183, 217, 260-261
R/module_transform_data.R           116       6  94.83%   48, 132-136
R/module_validate_error.R            73       0  100.00%
R/modules.R                         341      59  82.70%   170-174, 229-232, 332, 339, 353, 472, 538-546, 562-568, 698-704, 717-725, 740-755, 788, 800-808
R/reporter_previewer_module.R        41      12  70.73%   41, 45, 68-85
R/teal_data_module-eval_code.R       23       0  100.00%
R/teal_data_module-within.R           7       0  100.00%
R/teal_data_module.R                 20       0  100.00%
R/teal_data_utils.R                  49       0  100.00%
R/teal_modifiers.R                   57       0  100.00%
R/teal_slices-store.R                29       0  100.00%
R/teal_slices.R                      48       2  95.83%   153-154
R/teal_transform_module.R            45       0  100.00%
R/TealAppDriver.R                   355     355  0.00%    50-753
R/utils.R                           291      48  83.51%   403-452, 540-549
R/validate_inputs.R                  32       0  100.00%
R/validations.R                      58       0  100.00%
R/zzz.R                              19       0  100.00%
TOTAL                              3720     688  81.51%

Diff against main

Filename       Stmts    Miss  Cover
-----------  -------  ------  -------
R/modules.R      +50      -2  +3.66%
TOTAL            +50      -2  +0.31%

Results for commit: 7e94ee2

Minimum allowed coverage is 80%

♻️ This comment has been updated with latest results

Signed-off-by: Marcin <133694481+m7pr@users.noreply.github.com>
Copy link
Contributor

@llrs-roche llrs-roche left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nicely tested with format()!

I miss some tests with a mix of decorators: one general and some others specific:

decorators = list(decorator0.
        table = list(decorator1, decorator2),
        plot = list(decorator3)
      )

I see it works but see also my comment about having a tree structure to know which decorator is applied to each object.

@llrs-roche llrs-roche self-assigned this Jan 28, 2026
@m7pr
Copy link
Collaborator

m7pr commented Jan 28, 2026

Now

  decorator1 <- teal_transform_module(
    label = "Dec1",
    server = function(id, data) {
      moduleServer(id, function(input, output, session) data)
    }
  )

  decorator2 <- teal_transform_module(
    label = "Dec2",
    server = function(id, data) {
      moduleServer(id, function(input, output, session) data)
    }
  )

  decorator3 <- teal_transform_module(
    label = "Dec3",
    server = function(id, data) {
      moduleServer(id, function(input, output, session) data)
    }
  )

  mod <- module(
    label = "test module",
    server_args = list(
      decorators = list(
        table = list(decorator1, decorator2),
        plot = list(decorator3)
      )
    )
  )
  mod

gives

image

and this

  decorator0 <- teal_transform_module(
    label = "Global Decorator",
    server = function(id, data) {
      moduleServer(id, function(input, output, session) data)
    }
  )

  decorator1 <- teal_transform_module(
    label = "Decorator One",
    server = function(id, data) {
      moduleServer(id, function(input, output, session) data)
    }
  )

  decorator2 <- teal_transform_module(
    label = "Decorator Two",
    server = function(id, data) {
      moduleServer(id, function(input, output, session) data)
    }
  )

  decorator3 <- teal_transform_module(
    label = "Decorator Three",
    server = function(id, data) {
      moduleServer(id, function(input, output, session) data)
    }
  )

  # Mix of global decorator and object-specific decorators
  mod <- module(
    label = "test module",
    server_args = list(
      decorators = list(
        decorator0,
        table = list(decorator1, decorator2),
        plot = list(decorator3)
      )
    )
  )


image

Copy link
Contributor

@llrs-roche llrs-roche left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My local checks fail: [ FAIL 7 | WARN 0 | SKIP 0 | PASS 85 ] I'm not sure why, but it might be related to the [ opened that are not closed that are somehow misidentified.

One last comment, are the semicolons : not aligned on purpose? See the proposed changes
I think it is fine for the individual objects but wanted to check with you.

Possible alignment of semicolons:

|  |- Server Arguments : 
|  |- Decorators       :
|  |  |- Global Decorator
|  |  |- table: Decorator One, Decorator Two
|  |  L- plot : Decorator Three
|  L- Transformators   : 

Now that I think of it a similar modification might be in order for Transformators.

Co-authored-by: Lluís Revilla <185338939+llrs-roche@users.noreply.github.com>
Signed-off-by: Marcin <133694481+m7pr@users.noreply.github.com>
@m7pr
Copy link
Collaborator

m7pr commented Jan 28, 2026

About the semicolons, this was a mistake. I think your proposition is good enough but I'm also thinking if we could add some more spaces before :

image

so it's like this

image

@llrs-roche
Copy link
Contributor

That would be perfect, but I wasn't sure if the decorators as being less important (?) were worth to indent as the other sections. Not sure if people use this feature much and we dedicated enough time already ... I'll leave it up to you

@m7pr
Copy link
Collaborator

m7pr commented Feb 10, 2026

Hey guys, with the newest approach (where arguments are grouped under one umbrella, and transformators and decorators are split into multiple lines) I decided that colon indentation is now obsolete and decided to show the print like that

TEAL ROOT
  L- Test Module with All Features
     |- Datasets: all
     |- Properties:
     |  |- Bookmarkable: FALSE
     |  L- Reportable: TRUE
     |- Arguments:
     |  |- templates_ids (character)
     |  |- templates (data.frame)
     |  L- Decorators:
     |     |- Test Decorator
     |     L- table:
     |        L- Table Style Decorator
     L- Transformators:
        L- Data Transformator

I think it's clean enough and serves the purpose of inspecting the module structure (currently nested for decorators and transformators)

image

Hoping to get this closed, so we can focus on bigger priorities

Code
devtools::load_all(".")
library(teal.data)

test_decorator <- teal::teal_transform_module(
  label = "Test Decorator",
  ui = function(id) {
    ns <- shiny::NS(id)
    shiny::tagList(
      shiny::textInput(ns("text"), "Text Input", value = "default")
    )
  },
  server = function(id, data) {
    shiny::moduleServer(id, function(input, output, session) {
      shiny::reactive({
        req(data())
        within(data(), {
          if (exists("test_var")) {
            test_var <- paste(test_var, input$text)
          }
        })
      })
    })
  }
)

table_decorator <- teal::teal_transform_module(
  label = "Table Style Decorator",
  ui = function(id) {
    ns <- shiny::NS(id)
    shiny::tagList(
      shiny::checkboxInput(ns("bold"), "Bold", value = FALSE)
    )
  },
  server = function(id, data) {
    shiny::moduleServer(id, function(input, output, session) {
      shiny::reactive({
        req(data())
        data()
      })
    })
  }
)

test_transformator <- teal::teal_transform_module(
  label = "Data Transformator",
  ui = function(id) {
    ns <- shiny::NS(id)
    shiny::tagList(
      shiny::numericInput(ns("multiplier"), "Multiplier", value = 1)
    )
  },
  server = function(id, data) {
    shiny::moduleServer(id, function(input, output, session) {
      shiny::reactive({
        req(data())
        within(data(), {
          if (exists("ADSL")) {
            ADSL$new_var <- ADSL$AGE * input$multiplier
          }
        })
      })
    })
  }
)

data <- teal_data(
  ADSL = teal.data::rADSL
)

# Create a module with:
# - UI args (templates_ids)
# - Server args (templates, decorators)
# - Decorators (both global and object-specific)
# - Transformators
test_module <- teal::module(
  label = "Test Module with All Features",
  ui = function(id, templates_ids) {
    ns <- shiny::NS(id)
    shiny::tagList(
      shiny::h3("Test Module"),
      shiny::p(paste("Template IDs:", paste(templates_ids, collapse = ", ")))
    )
  },
  server = function(id, data, templates, reporter, ...) {
    shiny::moduleServer(id, function(input, output, session) {
      # Module server logic
      output$plot <- shiny::renderPlot({
        plot(1:10)
      })
    })
  },
  ui_args = list(
    templates_ids = c("template1", "template2", "template3")
  ),
  server_args = list(
    templates = data.frame(
      id = c("template1", "template2"),
      name = c("Template 1", "Template 2")
    ),
    decorators = list(
      # Global decorator
      test_decorator,
      # Object-specific decorators
      table = list(table_decorator)
    )
  ),
  transformators = list(test_transformator)
)

print(test_module)

# Also test with modules() to see nested structure
modules_obj <- teal::modules(
  label = "Test Modules",
  test_module
)

cat("\n=== Modules Structure ===\n")
print(modules_obj)

Copy link
Contributor

@llrs-roche llrs-roche left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like the output when there are decorators and transformators.

I found format.teal_module quite complex (cyclocomp complexity of 46!).
Lines of codes to handle:

  • Datasets: 430:436 -> 6
  • properties: 438:447 ->9
  • arguments: 449:560 -> 111
    • decorators: 492:558 ->66
  • transformators 562:588->26

Couldn't some code from transformators be reused on the arguments to handle decorators? Or extract some of these in a separate function? I think it would be great if we can make it simpler.

What should be the output when there are not transformators or decorators?
Testing without them they are printed but with no information: should the leaves not be printed, have NULL or something else? Maybe this was discussed and I missed it.

print(test_module)
|- Test Module with All Features
|  |- Datasets: all
|  |- Properties:
|  |  |- Bookmarkable: FALSE
|  |  L- Reportable: TRUE
|  |- Arguments:
|  |  |- templates_ids (character)
|  |  L- templates (data.frame)
|  |  L- Decorators: 
|  |- Transformators: 

Test files check that something is present not how. I leave some minor comments about the code style and there is one on tests that I think applies to multiple tests.

@m7pr
Copy link
Collaborator

m7pr commented Feb 11, 2026

@llrs-roche

  • I simplified print - the function body went from ~190 lines down to ~80 lines. The key structural improvement is computing visible_sections up front so tree connectors (|- vs L-) are determined by which sections actually render, not by hardcoded assumptions.
    • Created format_tree_leaves and format_decorator_entries for that.
  • We are not showing Transformers or Decorators if they are not included.

Examples and results below

Code
devtools::load_all(".")
library(teal.data)

test_decorator <- teal::teal_transform_module(
  label = "Test Decorator",
  ui = function(id) {
    ns <- shiny::NS(id)
    shiny::tagList(
      shiny::textInput(ns("text"), "Text Input", value = "default")
    )
  },
  server = function(id, data) {
    shiny::moduleServer(id, function(input, output, session) {
      shiny::reactive({
        req(data())
        within(data(), {
          if (exists("test_var")) {
            test_var <- paste(test_var, input$text)
          }
        })
      })
    })
  }
)

table_decorator <- teal::teal_transform_module(
  label = "Table Style Decorator",
  ui = function(id) {
    ns <- shiny::NS(id)
    shiny::tagList(
      shiny::checkboxInput(ns("bold"), "Bold", value = FALSE)
    )
  },
  server = function(id, data) {
    shiny::moduleServer(id, function(input, output, session) {
      shiny::reactive({
        req(data())
        data()
      })
    })
  }
)

test_transformator <- teal::teal_transform_module(
  label = "Data Transformator",
  ui = function(id) {
    ns <- shiny::NS(id)
    shiny::tagList(
      shiny::numericInput(ns("multiplier"), "Multiplier", value = 1)
    )
  },
  server = function(id, data) {
    shiny::moduleServer(id, function(input, output, session) {
      shiny::reactive({
        req(data())
        within(data(), {
          if (exists("ADSL")) {
            ADSL$new_var <- ADSL$AGE * input$multiplier
          }
        })
      })
    })
  }
)

data <- teal_data(
  ADSL = teal.data::rADSL
)

# Create a module with:
# - UI args (templates_ids)
# - Server args (templates, decorators)
# - Decorators (both global and object-specific)
# - Transformators
test_module <- teal::module(
  label = "Test Module with All Features",
  ui = function(id, templates_ids) {
    ns <- shiny::NS(id)
    shiny::tagList(
      shiny::h3("Test Module"),
      shiny::p(paste("Template IDs:", paste(templates_ids, collapse = ", ")))
    )
  },
  server = function(id, data, templates, reporter, ...) {
    shiny::moduleServer(id, function(input, output, session) {
      # Module server logic
      output$plot <- shiny::renderPlot({
        plot(1:10)
      })
    })
  },
  ui_args = list(
    templates_ids = c("template1", "template2", "template3")
  ),
  server_args = list(
    templates = data.frame(
      id = c("template1", "template2"),
      name = c("Template 1", "Template 2")
    ),
    decorators = list(
      # Global decorator
      test_decorator,
      # Object-specific decorators
      table = list(table_decorator)
    )
  ),
  transformators = list(test_transformator)
)

print(test_module)

# Module without decorators or transformators
bare_module <- teal::module(
  label = "Bare Module (no decorators, no transformators)",
  ui = function(id, page_size) {
    ns <- shiny::NS(id)
    shiny::tagList(
      shiny::h3("Bare Module"),
      shiny::p(paste("Page size:", page_size))
    )
  },
  server = function(id, data, cache, ...) {
    shiny::moduleServer(id, function(input, output, session) NULL)
  },
  ui_args = list(page_size = 25),
  server_args = list(cache = TRUE)
)

cat("\n=== Bare Module (no decorators, no transformators) ===\n")
print(bare_module)

# Minimal module — no args, no decorators, no transformators
minimal_module <- teal::module(
  label = "Minimal Module"
)

cat("\n=== Minimal Module (nothing extra) ===\n")
print(minimal_module)

# Also test with modules() to see nested structure
modules_obj <- teal::modules(
  label = "Test Modules",
  test_module,
  bare_module,
  minimal_module
)

cat("\n=== Modules Structure ===\n")
print(modules_obj)

image

3 - module with everything
2 - basic module with some arugments
1 - bare module

@m7pr
Copy link
Collaborator

m7pr commented Feb 11, 2026

image

@m7pr m7pr requested review from gogonzo, llrs-roche and m7pr February 11, 2026 11:12
Copy link
Contributor

@llrs-roche llrs-roche left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks great! The code is easier to follow now.

One last nitpick, some leaves seem to carry on some | that does not continue below. If possible it would be great to fix, if not it good enough now in my opinion.

  |  |- Transformators:
-  |  |  L- Data Transformator
+  |     L- Data Transformator
  |- Bare Module (no decorators, no transformators)
  |  |- Datasets: all
  |  |- Properties:
  |  |  |- Bookmarkable: FALSE
  |  |  L- Reportable: FALSE
  |  |- Arguments:
-  |  |  |- page_size (numeric)
-  |  |  L- cache (logical)
+  |     |- page_size (numeric)
+  |     L- cache (logical)

@m7pr
Copy link
Collaborator

m7pr commented Feb 11, 2026

@llrs-roche I added the requested change

image

Lastly, I see 2 tests fail locally - one for teal.slice and one for teal.reporter hmm

── Failed tests ──────────────────────────────────────────────────────────────
Failure (test-teal_reporter.R:2:3): TealReportCard object can be initialized
Expected `TealReportCard$new()` to produce warnings.
Backtrace:1. └─lifecycle::expect_deprecated(TealReportCard$new()) at test-teal_reporter.R:2:3
 2.   └─testthat::expect_warning(...)

Error (test-teal_slices.R:192:3): c.teal_slices combines mapping of two equal slices objects but ignores adding duplicated one
Error in `teal.slice::teal_slices(..., exclude_varnames = exclude_varnames, include_varnames = include_varnames, count_type = count_type, allow_add = allow_add)`: Some teal_slice objects have the same id:
test1
Backtrace:1. ├─testthat::expect_identical(...) at test-teal_slices.R:192:3
  2. │ └─testthat::quasi_label(enquo(object), label)
  3. │   └─rlang::eval_bare(expr, quo_get_env(quo))
  4. ├─base::c(tss1, tss2)
  5. ├─teal:::c.teal_slices(tss1, tss2)
  6. │ ├─base::do.call(...)
  7. │ └─teal (local) `<fn>`(...)
  8. │   ├─shiny::isolate(...) at teal/R/teal_slices.R:81:3
  9. │   │ ├─shiny::..stacktraceoff..(...)
 10. │   │ └─ctx$run(...)
 11. │   │   ├─promises::with_promise_domain(...)
 12. │   │   │ └─domain$wrapSync(expr)
 13. │   │   ├─shiny::withReactiveDomain(...)
 14. │   │   │ └─promises::with_promise_domain(...)
 15. │   │   │   └─domain$wrapSync(expr)
 16. │   │   │     └─base::force(expr)
 17. │   │   ├─shiny::captureStackTraces(...)
 18. │   │   │ └─promises::with_promise_domain(...)
 19. │   │   │   └─domain$wrapSync(expr)
 20. │   │   │     └─base::withCallingHandlers(expr, error = doCaptureStack)
 21. │   │   └─env$runWith(self, func)
 22. │   │     └─shiny (local) contextFunc()
 23. │   │       └─shiny::..stacktraceon..(expr)
 24. │   └─teal.slice::teal_slices(...) at teal/R/teal_slices.R:111:5
 25. │     └─base::stop("Some teal_slice objects have the same id:\n", toString(unique(slices_id[duplicated(slices_id)])))
 26. └─base::.handleSimpleError(...)
 27.   └─shiny (local) h(simpleError(msg, call))

[ FAIL 2 | WARN 0 | SKIP 51 | PASS 598 ]

@llrs-roche
Copy link
Contributor

Thanks @m7pr! Merge as soon as the checks are green

@m7pr m7pr dismissed gogonzo’s stale review February 11, 2026 12:59

changes implemented

@m7pr m7pr merged commit e2b2e71 into main Feb 11, 2026
28 checks passed
@m7pr m7pr deleted the copilot/improve-module-print-method branch February 11, 2026 12:59
@github-actions github-actions bot locked and limited conversation to collaborators Feb 11, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feature Request]: Improve module print method for multiple decorators on the same object

4 participants