Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ dependencies = [
"markdown>=3.6,<4",
# add features to markdown
# Pinned to specific version for introduction of codeblock handling.
"pymdown-extensions>=10.15,<11",
"pymdown-extensions>=10.21.2,<11",
# syntax highlighting of code in markdown
"pygments>=2.19,<3",
Comment thread
Light2Dark marked this conversation as resolved.
# for reading, writing configs
Expand Down Expand Up @@ -268,7 +268,7 @@ docs = [
"pillow>=10.2.0,!=11.3.0", # for social cards, 11.3.0 doesn't have manylinux wheels
"cairosvg>=2.7.1", # for social cards
"mdx-include>=1.4.2",
"pymdown-extensions>=10.7",
"pymdown-extensions>=10.21.2",
"lzstring>=1.0.4",
"beautifulsoup4>=4.12.0",
"markdownify>=0.13.0",
Expand Down
48 changes: 48 additions & 0 deletions tests/_output/test_doc.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
# Copyright 2026 Marimo. All rights reserved.
"""Tests for `marimo._output.doc.doc` / `mo.doc`."""

from __future__ import annotations

import marimo as mo
from marimo._output.doc import doc
from marimo._output.hypertext import Html


def test_doc_on_mddoc_decorated_function_does_not_raise() -> None:
"""Regression test for https://github.com/marimo-team/marimo/issues/9316.

`mo.doc` renders `_rich_help_` output (which contains a ```python fenced
code block with the object's signature) through pymdown-extensions +
pygments. pymdown-extensions <10.21.2 passed `filename=None` to pygments'
`HtmlFormatter`, and pygments >=2.20 crashed with
`AttributeError: 'NoneType' object has no attribute 'replace'`.

This test exercises the full pipeline end-to-end on each `@mddoc`-decorated
object used by the Layout tutorial so a regression in the pinned dependency
range is caught immediately.
"""
for obj in (mo.hstack, mo.vstack, mo.accordion, mo.callout, mo.tree):
result = doc(obj)
assert isinstance(result, Html), (
f"doc({obj.__name__}) returned {result!r}"
)
# The highlighted signature block should be present in the output.
assert "codehilite" in result.text
assert obj.__name__ in result.text


def test_doc_on_mddoc_decorated_method_does_not_raise() -> None:
for method in (mo.Html.center, mo.Html.right, mo.Html.left):
result = doc(method)
assert isinstance(result, Html)
assert "codehilite" in result.text


def test_doc_on_object_without_rich_help_returns_none() -> None:
"""When the target object doesn't implement `_rich_help_`, `doc` should
fall back to `help(obj)` and return `None`."""

class Plain:
"""A plain class without `_rich_help_`."""

assert doc(Plain) is None
2 changes: 1 addition & 1 deletion tests/snapshots/dependencies.txt
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ narwhals>=2.0.0
packaging
psutil>=5.0
pygments>=2.19,<3
pymdown-extensions>=10.15,<11
pymdown-extensions>=10.21.2,<11
pyyaml>=6.0.1
pyzmq>=27.1.0; python_version < '3.15'
starlette>=0.37.2
Expand Down
Loading