From 81b24dde4d47aeedd9cd8fae02a4ac6fe5a71fea Mon Sep 17 00:00:00 2001 From: Hassan Kibirige Date: Wed, 1 Apr 2026 23:22:02 -0700 Subject: [PATCH 1/2] Remove Builder subclasses and style registry The renderer has no style-specific logic, making BuilderPkgdown, BuilderSinglePage, and the _registry/__init_subclass__ dispatch mechanism redundant. --- great_docs/_renderer/introspection.py | 51 ++------------------------- great_docs/core.py | 5 --- tests/test_great_docs.py | 50 +------------------------- 3 files changed, 3 insertions(+), 103 deletions(-) diff --git a/great_docs/_renderer/introspection.py b/great_docs/_renderer/introspection.py index c09af4c6..3c8aafc5 100644 --- a/great_docs/_renderer/introspection.py +++ b/great_docs/_renderer/introspection.py @@ -383,9 +383,6 @@ class Builder: """ - style: str - _registry: "dict[str, Builder]" = {} - out_inventory: str = "objects.json" out_index: str = "index.qmd" out_page_suffix = ".qmd" @@ -399,15 +396,6 @@ class Builder: typing_module_paths: list[str] items: list[layout.Item] - def __init_subclass__(cls, **kwargs: object) -> None: - super().__init_subclass__(**kwargs) - - if hasattr(cls, "style") and cls.style in cls._registry: - raise KeyError(f"A builder for style {cls.style} already exists") - - if hasattr(cls, "style"): - cls._registry[cls.style] = cls - def __init__( self, package: str, @@ -428,9 +416,7 @@ def __init__( parser: str = "numpy", _fast_inventory: bool = False, ) -> None: - self.layout = self.load_layout( - title, desc=desc, sections=sections, package=package, options=options - ) + self.layout = layout.Layout(title, desc, sections=sections, package=package, options=options) self.package = package self.version = None @@ -459,14 +445,6 @@ def __init__( self._fast_inventory = _fast_inventory - def load_layout( - self, title: str, desc: str, sections: dict, package: str, options: "dict | None" = None - ) -> layout.Layout: - try: - return layout.Layout(title, desc, sections=sections, package=package, options=options) - except (ValueError, TypeError) as e: - raise ValueError(str(e)) from None - # building ---------------------------------------------------------------- def build(self, filter: str = "*") -> None: @@ -637,35 +615,10 @@ def from_quarto_config(cls, quarto_cfg: "str | dict") -> Builder: cfg = quarto_cfg.get("api-reference") or quarto_cfg.get("quartodoc") if cfg is None: raise KeyError("No `api-reference:` section found in your _quarto.yml.") - style = cfg.get("style", "pkgdown") - cls_builder = cls._registry[style] - _fast_inventory = quarto_cfg.get("interlinks", {}).get("fast", False) _removed_keys = {"style", "renderer", "render_interlinks"} - return cls_builder( + return cls( **{k: v for k, v in cfg.items() if k not in _removed_keys}, _fast_inventory=_fast_inventory, ) - - -class BuilderPkgdown(Builder): - """Build an API in R pkgdown style.""" - - style = "pkgdown" - - -class BuilderSinglePage(Builder): - """Build an API with all docs embedded on a single page.""" - - style = "single-page" - - def load_layout(self, *args, **kwargs): - el = super().load_layout(*args, **kwargs) - - el.sections = [layout.Page(path=self.out_index, contents=el.sections)] - - return el - - def write_index(self, *args, **kwargs): - pass diff --git a/great_docs/core.py b/great_docs/core.py index 1825385f..f655efb0 100644 --- a/great_docs/core.py +++ b/great_docs/core.py @@ -8231,15 +8231,10 @@ def _add_api_reference_config(self) -> None: ref_title = get_translation("reference", self._config.language) - # Configure the qrenderer - renderer_config = {"style": "_renderer.py"} - api_ref_config = { "package": importable_name, "dir": "reference", "title": ref_title, - "style": "pkgdown", - "renderer": renderer_config, } if ref_desc: api_ref_config["desc"] = ref_desc diff --git a/tests/test_great_docs.py b/tests/test_great_docs.py index 1fef72e0..94ae58aa 100644 --- a/tests/test_great_docs.py +++ b/tests/test_great_docs.py @@ -146,8 +146,6 @@ ) from great_docs._renderer.introspection import ( Builder, - BuilderPkgdown, - BuilderSinglePage, dynamic_alias, get_object, get_parser_defaults, @@ -27154,7 +27152,7 @@ def test_builder_from_quarto_config_no_section_raises(): def test_builder_from_quarto_config_with_style(): - """Builder.from_quarto_config uses style to pick builder class.""" + """Builder.from_quarto_config ignores style key in config.""" cfg = { "api-reference": { @@ -27183,52 +27181,6 @@ def test_builder_from_quarto_config_interlinks_fast(): assert builder._fast_inventory is True -def test_builder_pkgdown_style(): - """BuilderPkgdown has style='pkgdown'.""" - - assert BuilderPkgdown.style == "pkgdown" - - -def test_builder_single_page_style(): - """BuilderSinglePage has style='single-page'.""" - - assert BuilderSinglePage.style == "single-page" - - -def test_builder_single_page_wraps_sections(): - """BuilderSinglePage wraps sections in a single Page.""" - - builder = BuilderSinglePage( - package="json", - sections=[{"title": "Funcs", "desc": "", "contents": [{"name": "dumps"}]}], - ) - # layout.sections should be a single Page - assert len(builder.layout.sections) == 1 - - -def test_builder_single_page_from_config(): - """BuilderSinglePage is selected via style='single-page'.""" - - cfg = { - "api-reference": { - "package": "json", - "sections": [], - "style": "single-page", - } - } - builder = Builder.from_quarto_config(cfg) - assert isinstance(builder, BuilderSinglePage) - - -def test_builder_single_page_write_index_noop(): - """BuilderSinglePage.write_index does nothing.""" - - builder = BuilderSinglePage(package="json") - # write_index should return None and not create files - result = builder.write_index(builder.layout) - assert result is None - - def test_cli_ordered_group_list_commands(): """OrderedGroup.list_commands returns commands in insertion order.""" From a30914d72e77e69dbd8615c2155ef6bec0d70b63 Mon Sep 17 00:00:00 2001 From: Hassan Kibirige Date: Thu, 2 Apr 2026 16:32:47 -0700 Subject: [PATCH 2/2] Add expected builder error to test case Previous commit undid a bundling of these errors but left the test unchanged. --- tests/test_great_docs.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_great_docs.py b/tests/test_great_docs.py index 94ae58aa..4b95b362 100644 --- a/tests/test_great_docs.py +++ b/tests/test_great_docs.py @@ -26820,7 +26820,7 @@ def test_builder_init_desc(): def test_builder_load_layout_error(): """Builder.load_layout raises ValueError for invalid sections.""" - with pytest.raises(ValueError): + with pytest.raises((ValueError, TypeError)): Builder(package="json", sections=123)