Skip to content

Reduce Rd bloat from deep R6 inheritance chains - #1914

Open
kapelner wants to merge 1 commit into
r-lib:mainfrom
kapelner:r6-inherited-documentation-display
Open

Reduce Rd bloat from deep R6 inheritance chains#1914
kapelner wants to merge 1 commit into
r-lib:mainfrom
kapelner:r6-inherited-documentation-display

Conversation

@kapelner

@kapelner kapelner commented Aug 2, 2026

Copy link
Copy Markdown

In a package with a deep R6 inheritance chain (subclass -> parent -> grandparent -> ...), every class's Rd page rendered a single flat "Inherited methods" list mixing in every ancestor's methods together. Since each level down the chain accumulates the methods of all its ancestors, this list grows with total inherited method count across the whole chain -- for a package with many R6 classes and inheritance depths of 5+ levels, this produced Rd files with hundreds of lines per class just for this one section, and (more importantly) made every one of those classes' pages large enough that repeated Rd-to-text conversion during R CMD INSTALL compounded a separate, unrelated R-core memory issue we ran into and reported upstream.

This adds a new r6_inherited_documentation_display option (settable via Config/roxygen2/r6_inherited_documentation_display in DESCRIPTION, or man/roxygen/meta.R) with three values:

  • "grouped" (new default): one collapsed subsection per ancestor class that actually contributed an inherited method ("+ inherited public methods from "), nearest ancestor first, each still listing its own methods as linked bullets -- same information as before, but organized by ancestor instead of flattened, and collapsed by default instead of auto-expanding.
  • "single": a single fixed-size line pointing at the immediate parent class only, regardless of how many methods are inherited or how deep the chain is -- the actual bloat fix, for packages where even the grouped form is too large.
  • "original": byte-for-byte the previous rendering, for anyone who prefers it or hits a regression.

All three were verified against roxygen2's own test suite (8 new/updated tests, plus updated snapshots for the two existing integration tests that exercise multi-level R6 inheritance) and against a real-world package with R6 inheritance chains up to 5 levels deep -- "original" mode produced a total generated man/ size of ~5.0M, "grouped" reduced that to ~4.1M (same information, just organized by ancestor and collapsed by default instead of flattened and auto-expanded), and "single" reduced it further to ~2.2M by dropping per-method enumeration entirely.

This changes the default rendering (flat list -> grouped-by-ancestor, collapsed instead of auto-expanded) but not the underlying information shown; original is available for anyone who wants the old default back exactly.

In a package with a deep R6 inheritance chain (subclass -> parent ->
grandparent -> ...), every class's Rd page rendered a single flat
"Inherited methods" list mixing in every ancestor's methods together.
Since each level down the chain accumulates the methods of all its
ancestors, this list grows with total inherited method count across the
whole chain -- for a package with many R6 classes and inheritance depths
of 5+ levels, this produced Rd files with hundreds of lines per class
just for this one section, and (more importantly) made every one of
those classes' pages large enough that repeated Rd-to-text conversion
during R CMD INSTALL compounded a separate, unrelated R-core memory
issue we ran into and reported upstream.

This adds a new r6_inherited_documentation_display option (settable via
Config/roxygen2/r6_inherited_documentation_display in DESCRIPTION, or
man/roxygen/meta.R) with three values:

- "grouped" (new default): one collapsed subsection per ancestor class
  that actually contributed an inherited method ("+ inherited public
  methods from <ancestor>"), nearest ancestor first, each still listing
  its own methods as linked bullets -- same information as before, but
  organized by ancestor instead of flattened, and collapsed by default
  instead of auto-expanding.
- "single": a single fixed-size line pointing at the immediate parent
  class only, regardless of how many methods are inherited or how deep
  the chain is -- the actual bloat fix, for packages where even the
  grouped form is too large.
- "original": byte-for-byte the previous rendering, for anyone who
  prefers it or hits a regression.

All three were verified against roxygen2's own test suite (8 new/updated
tests, plus updated snapshots for the two existing integration tests
that exercise multi-level R6 inheritance) and against a real-world
package with R6 inheritance chains up to 5 levels deep -- "original"
mode produced a total generated man/ size of ~5.0M, "grouped" reduced
that to ~4.1M (same information, just organized by ancestor and
collapsed by default instead of flattened and auto-expanded), and
"single" reduced it further to ~2.2M by dropping per-method enumeration
entirely.

This changes the default rendering (flat list -> grouped-by-ancestor,
collapsed instead of auto-expanded) but not the underlying information
shown; original is available for anyone who wants the old default back
exactly.
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 this pull request may close these issues.

1 participant