tests.sphinx packageΒΆ

SubmodulesΒΆ

tests.sphinx.conftest moduleΒΆ

Fixtures and helpers for Sphinx tests.

Separated from the root tests/conftest.py so that the Sphinx dependency (and its ecosystem: myst-parser, docutils, etc.) is only imported when running the tests in this subdirectory.

class tests.sphinx.conftest.FormatType(*values)[source]ΒΆ

Bases: Enum

Sphinx document format types and their file extensions.

RST = '.rst'ΒΆ
MYST = '.md'ΒΆ
class tests.sphinx.conftest.SphinxAppWrapper(app, format_type)[source]ΒΆ

Bases: object

Wrapper around Sphinx application with additional testing methods.

classmethod create(format_type, tmp_path, return_srcdir=False, enable_exec_directives=True)[source]ΒΆ

Factory method to create a SphinxAppWrapper with given format.

enable_exec_directives opts the test app into the click:* and python:* directive families. Defaults to True for every fixture-built app because the test suite primarily exercises those directives. Tests that verify the off-by-default production gate flip the flag back to False explicitly.

Return type:

Generator[SphinxAppWrapper | tuple[SphinxAppWrapper, Path], None, None]

build_document(content)[source]ΒΆ

Build a Sphinx document with content and return the HTML output.

Automatically detects the format from the app configuration and uses the appropriate file extension (.rst or .md).

Return type:

str | None

generate_test_content(test_case)[source]ΒΆ

Generate content for a test case based on the app’s format type.

Return type:

str

tests.sphinx.conftest.sphinx_app(request, tmp_path)[source]ΒΆ

Create a Sphinx application for testing.

tests.sphinx.conftest.sphinx_app_for_format(request, tmp_path)[source]ΒΆ

sphinx_app variant whose format is supplied by the caller.

Identical to sphinx_app() but without the default params: the FormatType is taken from the test’s indirect parametrization. A params-bearing fixture cannot also be parametrized by a test (pytest rejects it as a duplicate parametrization), so a test that drives the format per case parametrizes this variant instead, usually through format_params().

tests.sphinx.conftest.sphinx_app_rst(tmp_path)[source]ΒΆ

Create a Sphinx application for testing RST format only.

The click:* and python:* directive families are enabled so tests can exercise them. Tests that explicitly verify the off-by- default opt-in gate construct their own app via SphinxAppWrapper.create() with enable_exec_directives=False.

tests.sphinx.conftest.sphinx_app_myst(tmp_path)[source]ΒΆ

Create a Sphinx application for testing MyST format only.

The click:* and python:* directive families are enabled: see sphinx_app_rst() for the rationale.

tests.sphinx.conftest.sphinx_app_myst_with_include(tmp_path)[source]ΒΆ

Create a Sphinx application for testing MyST format with include files.

class tests.sphinx.conftest.DirectiveTestCase(name, format_type=None, source_block=None, run_block=None, document=None, html_matches=None)[source]ΒΆ

Bases: object

Test case data for directive tests.

name: strΒΆ
format_type: FormatType | None = NoneΒΆ
source_block: str | None = NoneΒΆ
run_block: str | None = NoneΒΆ
document: str | None = NoneΒΆ
html_matches: Sequence[str] | str | None = NoneΒΆ
tests.sphinx.conftest.format_params(*test_cases)[source]ΒΆ

Pair each test case with every document format it is written for.

Feeds the indirect parametrization of sphinx_app_for_format(), so a case is only ever built by an app whose format it can render: a case pinned to a FormatType yields that format alone, a format-agnostic one yields a parameter per format.

Return type:

tuple[ParameterSet, ...]

tests.sphinx.conftest.unescape_quotes(text)[source]ΒΆ

Replace quote entities with bare quotes, so both escapings compare equal.

Pygments 2.21.0 replaced its escape_html() helper with html.escape(value, quote=False). Token text carries bare " and ' since then, where older releases produced " and '. Both forms render the same, and the pygments extra declares a floor spanning that release, so HTML fragments are compared with quotes normalized.

Return type:

str

tests.sphinx.conftest.plain_whitespace(text)[source]ΒΆ

Replace whitespace tokens with bare spaces, so both lexings compare equal.

Pygments 2.19.0 made the Python lexer emit some blanks of a def or from statement as whitespace tokens, where older releases leave them as bare text. Both forms render the same, and the sphinx extra declares a floor below that release, so HTML fragments are compared with these tokens flattened.

Return type:

str

tests.sphinx.conftest.python_block(*lines)[source]ΒΆ

Build expected Python highlight block.

Return type:

str

tests.sphinx.conftest.shell_block(*lines)[source]ΒΆ

Build expected shell session block.

Return type:

str

tests.sphinx.conftest.admonition_block(admonition_type, content)[source]ΒΆ

Build expected admonition block.

Parameters:
  • admonition_type (str) – The type of admonition (note, tip, warning, etc.)

  • content (str) – The inner HTML content of the admonition (without the title)

Return type:

str

tests.sphinx.test_sphinx moduleΒΆ

Fixtures and utilities for Sphinx testing.

tests.sphinx.test_sphinx.test_import_without_myst_parser()[source]ΒΆ

The extension imports in a project that installs no myst-parser.

Sphinx does not depend on myst-parser, so a project that installs Sphinx without the sphinx extra has none. A hard import of it in click_extra.sphinx breaks such a project outright.

tests.sphinx.test_sphinx.imports_sphinx_package(node)[source]ΒΆ

Whether an import statement reaches click_extra.sphinx or a module of it.

Return type:

bool

tests.sphinx.test_sphinx.is_sphinx_guard(call)[source]ΒΆ

Whether the call is pytest.importorskip("sphinx", ...).

Return type:

bool

tests.sphinx.test_sphinx.unguarded_sphinx_imports(tree)[source]ΒΆ

Lines importing click_extra.sphinx that no importorskip("sphinx") precedes.

A guard covers the rest of the function it is called in, or the whole module when called at its top level.

Return type:

list[int]

tests.sphinx.test_sphinx.test_imports_outside_this_tree_skip_without_sphinx()[source]ΒΆ

Outside tests/sphinx/, a test skips itself before importing the extension.

The collect_ignore_glob of this tree skips it on a builder shipping no Sphinx, and covers no test outside it. Such a test has to call pytest.importorskip("sphinx") before it imports click_extra.sphinx, or it fails on that builder instead of skipping.

tests.sphinx.test_sphinx.test_sphinx_extension_setup(sphinx_app)[source]ΒΆ

Test that the Sphinx extension is properly loaded.

tests.sphinx.test_sphinx.test_resolve_any_xref(sphinx_app)[source]ΒΆ

Test that resolve_any_xref is implemented and returns an empty list.

tests.sphinx.test_sphinx_announcement moduleΒΆ

Tests for the year count of an announcement banner.

tests.sphinx.test_sphinx_announcement.anniversaries(start, day)[source]ΒΆ

Count the anniversaries of start that day has reached, one at a time.

Counted apart from years_since(), so the test does not grade a formula against itself. start cannot be a 29 February, which date.replace cannot move to a common year.

Return type:

int

tests.sphinx.test_sphinx_announcement.test_years_since_on_every_day_of_a_leap_span()[source]ΒΆ

The count goes up on each anniversary, and never a day before it.

The span holds the leap days of 2024, 2028 and 2032. Each moves a count of days divided by 365 one day further ahead, which the last assertion checks the span catches.

Return type:

None

tests.sphinx.test_sphinx_announcement.test_years_since_a_leap_day(today, expected)[source]ΒΆ

A start on 29 February has its anniversary on 1 March of a common year.

Return type:

None

tests.sphinx.test_sphinx_announcement.test_years_since_counts_to_the_current_day()[source]ΒΆ

Without today, the count ends on the current day in UTC.

Return type:

None

tests.sphinx.test_sphinx_changelog moduleΒΆ

Tests for the anchors of changelog releases.

tests.sphinx.test_sphinx_changelog.MYST_CHANGELOG = '# Changelog\n\nSee the [next release](#v1-5-0).\n\n## [`1.5.0.dev0` (unreleased)](https://example.com/compare/v1.4.2...main)\n\n- Plant a pear tree.\n\n## [`1.4.2` (2026-03-15)](https://example.com/compare/v1.4.1...v1.4.2)\n\n- Prune the apple trees.\n\n## `1.4.1` (2026-02-01)\n\n- Water the plums.\n'ΒΆ

A MyST changelog, one release titled as a link, one as plain text.

tests.sphinx.test_sphinx_changelog.LETTERLESS_CHANGELOG = '# 2026\n\n## `1.4.2` (2026-03-15)\n\n- Prune the apple trees.\n\n## `1.4.1` (2026-02-01)\n\n- Water the plums.\n'ΒΆ

A MyST changelog whose headings all have no letters, so no heading slug.

tests.sphinx.test_sphinx_changelog.RST_CHANGELOG = 'Changelog\n=========\n\n1.5.0.dev0 (unreleased)\n-----------------------\n\n- Plant a pear tree.\n\n1.4.2 (2026-03-15)\n------------------\n\n- Prune the apple trees.\n\n1.4.1 (2026-02-01)\n------------------\n\n- Water the plums.\n'ΒΆ

The same changelog in reStructuredText.

tests.sphinx.test_sphinx_changelog.ORCHARD_PAGE = '# Orchard\n\nThe trees were [last pruned](changelog.md#v1-4-2).\n'ΒΆ

A MyST page linking to a release of the changelog page.

tests.sphinx.test_sphinx_changelog.build(tmp_path, pages, *, anchors=None)[source]ΒΆ

Build pages, a map of file names to sources, and return the output.

anchors sets RELEASE_ANCHORS_CONFIG, left to its default when None. Returns the output directory and the warning stream.

tests.sphinx.test_sphinx_changelog.test_release_heading(title, version)[source]ΒΆ

Only a title made of a full version and a parenthesized label matches.

tests.sphinx.test_sphinx_changelog.test_releases_are_anchored_on_their_version(tmp_path, page)[source]ΒΆ

Each release section takes its version as ID, the one in preparation too.

A link to a version anchor resolves, from the changelog and from another page.

A link resolves to a release on a page where no heading has a slug.

tests.sphinx.test_sphinx_changelog.test_release_anchors_are_off_by_default(tmp_path)[source]ΒΆ

Without the opt-in, each release keeps the ID docutils gave it.

tests.sphinx.test_sphinx_click moduleΒΆ

Tests for Sphinx directives click:source and click:run in rST and MyST formats.

tests.sphinx.test_sphinx_click.test_directive_functionality(sphinx_app_for_format, test_case)[source]ΒΆ

Test standard directive functionalities in each format a case targets.

tests.sphinx.test_sphinx_click.test_directive_option_format(sphinx_app_rst)[source]ΒΆ

rST will fail to render if an :option: is not followed by an empty line.

tests.sphinx.test_sphinx_click.test_directive_option_language_override(sphinx_app)[source]ΒΆ

Test that language override works for click:run directive.

tests.sphinx.test_sphinx_click.test_sphinx_directive_state_persistence(sphinx_app)[source]ΒΆ

Test that state persists between declare and run directives in real Sphinx.

tests.sphinx.test_sphinx_click.test_directive_variable_conflict(var_name, sphinx_app_for_format, content, directive_lineno, error_lineno)[source]ΒΆ

Test that variable conflicts are properly detected in real Sphinx environment.

tests.sphinx.test_sphinx_click.GENERATED_BLOCK_ANCHOR = 'from click_extra import command, echo'ΒΆ

First body line of the GENERATED_BLOCK_LINE_CASES documents below.

The line a generated block is expected to be attributed to, located in the document itself so editing a case moves the expectation with it.

tests.sphinx.test_sphinx_click.test_generated_block_is_attributed_to_the_directive_body(sphinx_app_for_format, test_case)[source]ΒΆ

A block a directive generates is attributed to its first body line.

The generated lines exist nowhere in the document, so the parser has to be told which document line to hang a diagnostic raised inside them on. Both formats must answer the same way, and neither is free to fall back on its own default: docutils numbers an unlabelled block from the top of the file, and myst-parser measures its offsets from the directive rather than the document.

The last two cases carry both an option block and a body ending in blank lines, whose content_offset myst-parser 5.1.0 and older over-counted by one.

tests.sphinx.test_sphinx_click.test_exit_exception_percolate(sphinx_app)[source]ΒΆ

Test directives that handle command errors and exit codes.

tests.sphinx.test_sphinx_click.test_clickrunner_forces_color(monkeypatch)[source]ΒΆ

ClickRunner forces FORCE_COLOR so Rich-based CLIs colorize under NO_COLOR.

The runner already passes color=True (Click’s color system). But rich-click renders help through Rich’s Console, gated on FORCE_COLOR, which color=True never reaches. The runner therefore also forces FORCE_COLOR (clearing the disabling vars) around the executed command, then restores the environment.

tests.sphinx.test_sphinx_click.test_clickrunner_sets_the_handlers_of_the_build_aside()[source]ΒΆ

ClickRunner takes the handlers it found on the root logger off it while a documented command runs, then puts them back.

A build shares its process with Sphinx, its extensions and its theme. A handler one of them gave the root logger would print each record of the command a second time, which the shell of a reader never does.

tests.sphinx.test_sphinx_click.test_clickrunner_sets_the_level_of_the_build_aside(document_level, expected)[source]ΒΆ

ClickRunner gives the root logger the default level while a documented command runs, where the build left another one, then gives that one back.

A command leaves the root logger at the level it found. The level of the build would so let through what a command logs before its verbosity options apply, which the shell of a reader never prints.

tests.sphinx.test_sphinx_click.test_clickrunner_capture_mode_controls_fileno(capture, renders)[source]ΒΆ

ClickRunner(capture=...) decides whether a CLI calling fileno() renders.

Click’s "sys" mode backs the captured stream with an in-memory buffer whose fileno() raises io.UnsupportedOperation, so a documented command that re-opens its descriptor (a common UTF-8-on-Windows guard) aborts. "fd" (the default on Unix, also exposed as the click_extra_run_capture conf.py value) returns a copy of the original stdout descriptor, so the command runs and its click.echo output renders. What it writes through that copy does not, see test_clickrunner_captures_prep_path_stdout. On Windows, where fd-backed streams are not supported, the default falls back to "sys".

tests.sphinx.test_sphinx_click.test_clickrunner_captures_prep_path_stdout(capture)[source]ΒΆ

A command writing to - through prep_path renders in every capture mode.

Under "fd", sys.stdout.fileno() returns a copy of the original stdout descriptor, so a stream opened on it writes past the capture.

tests.sphinx.test_sphinx_click.test_program_from_command_line(command_line, expected)[source]ΒΆ

Only an interpreter prefix is dropped from a displayed command line.

tests.sphinx.test_sphinx_click.test_clickrunner_keeps_a_multi_word_prog_name(monkeypatch)[source]ΒΆ

A subcommand-shaped program name reaches the command it runs, whole.

tests.sphinx.test_sphinx_click.test_clickrunner_prompt_inlines_environment_assignments(monkeypatch)[source]ΒΆ

Variables are set on the invocation, the way the runner applies them.

CliRunner scopes env to the one call, so an export line would advertise a persistence the next block does not inherit.

tests.sphinx.test_sphinx_click.test_clickrunner_prompt_quotes_a_spaced_argument(monkeypatch)[source]ΒΆ

An argument holding spaces stays the single token a reader must type.

tests.sphinx.test_sphinx_click.test_clickrunner_hide_prompt_drops_the_invocation(monkeypatch)[source]ΒΆ

_show_prompt=False leaves the output alone and drops the line above it.

tests.sphinx.test_sphinx_click.test_clickrunner_prompt_past_the_input_aborts(monkeypatch, terminate_input)[source]ΒΆ

A prompt reading past the end of the input aborts, as it does under Click.

The read past the end returns no byte at all, which the echoing stream has to pass through rather than look for a ^D in.

tests.sphinx.test_sphinx_click.test_click_run_prompt_options(sphinx_app_myst, options, prompted)[source]ΒΆ

:show-prompt: / :hide-prompt: gate the invocation line.

tests.sphinx.test_sphinx_click.test_click_run_output_holding_a_fence_stays_in_its_block(sphinx_app_myst)[source]ΒΆ

Output carrying a code fence of its own renders whole in the result block.

A fixed three-backtick fence closes on the output’s own bare fence line, and MyST then parses the rest of the output as part of the page.

tests.sphinx.test_sphinx_click.test_code_fence_outgrows_the_fences_it_wraps(lines, fence)[source]ΒΆ

The fence is one backtick longer than any run opening a line, at least three.

tests.sphinx.test_sphinx_click.test_click_run_hide_prompt_reaches_the_screenshot(sphinx_app_myst)[source]ΒΆ

A capture is drawn from the same lines, so it loses the prompt too.

tests.sphinx.test_sphinx_click.test_click_run_screenshot_writes_the_asset(sphinx_app_myst)[source]ΒΆ

:screenshot: writes the capture beside the documentation.

The image is a side effect: the page keeps its results code block, which inside Sphinx beats an image by staying selectable and searchable.

tests.sphinx.test_sphinx_click.ANIMATED_SOURCE = '\n    ```{click:source}\n    :hide-source:\n    from click_extra import SPINNERS, Spinner, Style, command, echo\n\n    @command\n    def greet():\n        echo("Hello, papaya!")\n\n    steeping = Spinner("Steeping", spinner=SPINNERS["moon"], style=Style(fg="green"))\n    ```\n'ΒΆ

A spinner and a CLI, seeded for the animated-capture blocks below.

tests.sphinx.test_sphinx_click.test_click_run_screenshot_animate_stacks_a_spinner(sphinx_app_myst)[source]ΒΆ

:screenshot-animate: draws every frame of the spinner it names.

The frames and the interval are taken off the spinner itself, so the picture and the animation cannot disagree about either.

tests.sphinx.test_sphinx_click.test_click_run_screenshot_animate_defines_every_class_it_uses(sphinx_app_myst)[source]ΒΆ

No frame names a class the animated capture leaves undefined.

A frame whose rules are missing does not vanish: it falls back to the presentation attributes and draws in the wrong face and the wrong color, which reads as the animation resetting its styling once a cycle.

tests.sphinx.test_sphinx_click.test_click_run_screenshot_animate_accepts_bare_frames(sphinx_app_myst)[source]ΒΆ

A sequence of texts animates too, timed by :screenshot-interval:.

tests.sphinx.test_sphinx_click.test_click_run_screenshot_line_numbers_give_every_frame_one_gutter(sphinx_app_myst)[source]ΒΆ

A frame reaching ten rows does not push its text a cell to the right.

Each frame counts its own rows, from one. Numbered on its own, the nine-row frame aligns its numbers on one digit and the ten-row frame on two, so every row moves between the two frames.

tests.sphinx.test_sphinx_click.test_click_run_screenshot_animate_bare_frames_need_an_interval(sphinx_app_myst)[source]ΒΆ

Bare frames carry no timing of their own, so one has to be stated.

tests.sphinx.test_sphinx_click.test_click_run_screenshot_animate_rejects_a_foreign_subject(sphinx_app_myst)[source]ΒΆ

Something that is neither a spinner nor frames fails the build.

tests.sphinx.test_sphinx_click.test_click_run_screenshot_animate_is_deterministic(sphinx_app_myst)[source]ΒΆ

A declared subject composes the same lines on every build.

This is what lets an animated capture be committed at all: a recording would time its frames a little differently on every run and dirty the tree.

tests.sphinx.test_sphinx_click.test_click_run_screenshot_animate_rewrites_a_declared_asset(sphinx_app_myst)[source]ΒΆ

A declared animation is regenerated on every build, like any capture.

It composes the same lines every time, so the file only changes with the code, and regenerating it is what keeps the asset from drifting away from that code. Gating the write on what the animation is would freeze out every change to how it is drawn.

tests.sphinx.test_sphinx_click.test_click_run_screenshot_animate_carries_a_presentation_change(sphinx_app_myst)[source]ΒΆ

Restating how an animation is drawn reaches the committed asset.

The frames are untouched by a margin, so nothing about what the animation is moves. The picture still has to change.

tests.sphinx.test_sphinx_click.test_click_run_screenshot_leaves_an_unchanged_asset_alone(sphinx_app_myst, name, options)[source]ΒΆ

A rebuild drawing the same capture does not write the file again.

Writing the same bytes would still move the modification time of the file, which a tool watching the documentation tree reads as a change. A capture that differs is still written.

tests.sphinx.test_sphinx_click.RECORDED_SOURCE = '\n    ```{click:source}\n    :hide-source:\n    from click_extra.capture.recording import Frame\n\n    kettle = [Frame("filling", 0.2), Frame("boiled", 0.2)]\n    ```\n'ΒΆ

A stand-in recording: frames carrying their own durations, as one does.

tests.sphinx.test_sphinx_click.test_click_run_screenshot_record_writes_once(sphinx_app_myst)[source]ΒΆ

A recorded animation is written the first time and then left alone.

Which spinner glyph pairs with which screen is settled by the scheduler, so a recording cannot be reproduced and rewriting it would dirty the working tree for nothing anyone did.

tests.sphinx.test_sphinx_click.test_click_run_screenshot_record_holds_its_last_frame(sphinx_app_myst)[source]ΒΆ

A recording pauses on its final screen before starting over.

An animation that ends somewhere is worth reading, and a loop restarting the instant it arrives never lets anyone.

tests.sphinx.test_sphinx_click.test_click_run_screenshot_hold_overrides_the_pause(sphinx_app_myst)[source]ΒΆ

:screenshot-hold: states the pause a page would rather have.

tests.sphinx.test_sphinx_click.test_click_run_screenshot_blank_closes_the_cycle(sphinx_app_myst)[source]ΒΆ

A recording ends on an empty beat, so the loop’s turnover is visible.

Without it, a loop jumping from its last frame back to its first reads as one long animation doing something odd rather than as a repetition.

tests.sphinx.test_sphinx_click.test_click_run_screenshot_speed_scales_the_recorded_frames(sphinx_app_myst)[source]ΒΆ

:screenshot-speed: replays faster, leaving the pauses as stated.

The pauses are how long a reader is given, not part of what is replayed, so they are stated in real seconds and speed does not touch them.

tests.sphinx.test_sphinx_click.test_click_run_screenshot_emphasize_lines_bands_a_still(sphinx_app_myst)[source]ΒΆ

:screenshot-emphasize-lines: draws a band behind the lines it names.

tests.sphinx.test_sphinx_click.test_click_run_screenshot_emphasize_lines_bands_an_animation(sphinx_app_myst)[source]ΒΆ

A band marks a row of the screen, so an animation keeps it throughout.

Drawn once behind every frame rather than per frame: the emphasis is on the row, not on whatever a given frame happened to put there.

tests.sphinx.test_sphinx_click.test_click_run_screenshot_emphasize_lines_rejects_a_line_that_is_not_there(sphinx_app_myst)[source]ΒΆ

Naming a line the capture never drew fails the build rather than passing.

tests.sphinx.test_sphinx_click.test_click_run_screenshot_background(sphinx_app_myst)[source]ΒΆ

:screenshot-background: draws the capture on the chrome it names.

tests.sphinx.test_sphinx_click.test_click_run_screenshot_columns_auto(sphinx_app_myst)[source]ΒΆ

:screenshot-columns: auto widens the image to what the block printed.

Click wraps a CLI’s own text at its fixed width whatever the option says. What it decides is the picture, and a line the CLI never wrapped (the prompt of a long invocation) is the one that needs the room.

tests.sphinx.test_sphinx_click.test_click_run_screenshot_columns_rejects_an_unusable_width(value)[source]ΒΆ

A width narrower than the floor, or no width at all, is a build error.

The option reads through the parser the capture commands share, so the two reject the same widths with the same words.

tests.sphinx.test_sphinx_click.test_click_run_screenshot_frame_options(sphinx_app_myst)[source]ΒΆ

The :screenshot-*: options restate the window, the title included.

The hex color is quoted because a directive’s options are read as YAML, where an unquoted # opens a comment and leaves the option empty.

tests.sphinx.test_sphinx_click.test_click_run_screenshot_preset_swaps_the_prompt(sphinx_app_myst)[source]ΒΆ

A capture drawn as another terminal prompts the way that one does.

A block runs under a documentation build, so its own prompt is this platform’s $. The picture is of a Windows terminal, whose shell prompts with something else entirely.

tests.sphinx.test_sphinx_click.test_click_run_screenshot_preset_defaults_to_the_project_wide_one(sphinx_app_myst)[source]ΒΆ

A project drawing every capture as the same terminal states it once.

tests.sphinx.test_sphinx_click.test_click_run_screenshot_carries_no_watermark_by_default(sphinx_app_myst)[source]ΒΆ

A capture a click:run block writes carries no credit line by default.

The screenshot command credits click-extra on every image it writes. A block’s image sits on a page that already says what drew it.

tests.sphinx.test_sphinx_click.test_click_run_screenshot_watermark(sphinx_app_myst)[source]ΒΆ

A project wanting its captures credited states the line once.

tests.sphinx.test_sphinx_click.test_click_run_screenshot_opacity(sphinx_app_myst)[source]ΒΆ

A see-through window lets the page it is laid on show through its body.

tests.sphinx.test_sphinx_click.test_click_run_screenshot_opacity_rejects_what_is_not_one(argument)[source]ΒΆ

Anything outside the zero-to-one range fails the build instead of clamping.

tests.sphinx.test_sphinx_click.test_click_run_screenshot_timing_options_take_a_positive_number(option, argument, expected)[source]ΒΆ

A duration, a pace or a speed of zero or less fails the build.

tests.sphinx.test_sphinx_click.test_click_run_screenshot_background_rejects_an_unknown_chrome()[source]ΒΆ

A typo names the chromes it could have been, instead of drawing a default.

tests.sphinx.test_sphinx_click.test_click_run_mirror_region_round_trips()[source]ΒΆ

:mirror: inserts an image link below the fence, then leaves it alone.

tests.sphinx.test_sphinx_click.test_click_run_mirror_needs_both_options()[source]ΒΆ

A block missing either option gets no region.

:screenshot: alone maintains an asset some other surface embeds, without putting it on this page; :mirror: alone has no capture to point at.

tests.sphinx.test_sphinx_click.test_click_run_mirror_skips_a_nested_example()[source]ΒΆ

A click:run shown inside a longer fence is documentation, not a block.

tests.sphinx.test_sphinx_click.test_update_screenshot_blocks_writes_and_checks(tmp_path)[source]ΒΆ

The file-level refresher reports a stale page, then writes its region.

check leaves the page alone, a write links the capture under the given directory, and a page already current is not reported again.

tests.sphinx.test_sphinx_click.test_click_source_screenshot_pictures_its_own_code(sphinx_app_myst)[source]ΒΆ

A source block’s :screenshot: draws the code it declares.

A directive that runs something has output worth committing; one that only declares code has none, so its subject is the code itself.

tests.sphinx.test_sphinx_click.test_click_source_screenshot_takes_a_syntax_style(sphinx_app_myst)[source]ΒΆ

:screenshot-syntax-style: repaints the window along with the code.

tests.sphinx.test_sphinx_click.test_click_source_screenshot_bands_its_emphasized_lines(sphinx_app_myst)[source]ΒΆ

:emphasize-lines: marks the same lines on the page and in the image.

A source block has one content, so saying it twice would be the surprise.

tests.sphinx.test_sphinx_click.test_click_source_screenshot_is_deterministic(sphinx_app_myst)[source]ΒΆ

Two builds of one source block write the same bytes.

Nothing here runs a command or reads a clock, so a committed asset stays put and leaves the working tree clean.

tests.sphinx.test_sphinx_click.test_click_source_mirror_shows_the_snippet()[source]ΒΆ

A source block mirrors its capture the way a run block does.

Same marker pair, same derivation from the :screenshot: name: what changed is only which directives are allowed to ask.

tests.sphinx.test_sphinx_click.test_python_render_mirror_is_left_to_its_own_refresher()[source]ΒΆ

python:render keeps the one :mirror: that means something else.

It mirrors the markup the block generated, and a second refresher writing that region would undo the first on every alternate run.

tests.sphinx.test_sphinx_click_config moduleΒΆ

Tests for the click:config Sphinx directive.

class tests.sphinx.test_sphinx_click_config.BasketConfig(apples=3)[source]ΒΆ

Bases: object

Nested sub-table exercising the dotted-key expansion.

apples: int = 3ΒΆ

How many apples fit in the basket.

class tests.sphinx.test_sphinx_click_config.MarketConfig(city='Lisbon', stalls=<factory>, basket=BasketConfig())[source]ΒΆ

Bases: object

Toy schema reused across tests.

Defined at module level (not inside a click:source block) so inspect.getsource can recover the attribute docstrings.

city: str = 'Lisbon'ΒΆ

City where the market is held.

The market moves to the main square during summer, and to the covered hall the rest of the year.

stalls: list[str]ΒΆ

Stall types allowed on the premises.

basket: BasketConfigΒΆ

Parent table docstring, never rendered: only leaves get sections.

tests.sphinx.test_sphinx_click_config.MARKET_SEED = '```{click:source}\n:hide-source:\nfrom tests.sphinx.test_sphinx_click_config import market\n```\n'ΒΆ

Seed block importing the module-level CLI into the runner namespace.

class tests.sphinx.test_sphinx_click_config.PastryConfig(creme_brulee='vanilla|caramel', five_spice=5)[source]ΒΆ

Bases: object

Schema whose keys need slugging and whose default needs escaping.

creme_brulee: str = 'vanilla|caramel'ΒΆ

Flavors of the custard, separated by pipes.

five_spice: int = 5ΒΆ

How many spices go into the powder.

tests.sphinx.test_sphinx_click_config.PASTRY_CONFIG = '\n```{click:config} PastryConfig\nfrom tests.sphinx.test_sphinx_click_config import PastryConfig\n```\n'ΒΆ

Directive documenting PastryConfig.

tests.sphinx.test_sphinx_click_config.test_click_config_default_and_toml_literal(value, default, literal)[source]ΒΆ

A default renders in the table, and as the literal of its TOML example.

tests.sphinx.test_sphinx_click_config.test_click_config_renders_table_and_sections(sphinx_app_myst)[source]ΒΆ

The directive expands into a summary table + one section per option.

Each table link lands on the id docutils gives the option’s heading.

make_id writes the accented letters of crème-brûlée as their ASCII base, and drops the leading digit of 5-spice.

tests.sphinx.test_sphinx_click_config.test_click_config_keeps_a_piped_default_in_its_cell(sphinx_app_myst)[source]ΒΆ

A pipe in a default value stays text, rather than splitting its row.

tests.sphinx.test_sphinx_click_config.test_click_config_toml_examples(sphinx_app_myst)[source]ΒΆ

Each option gets a TOML example pinned to its default value.

The section header defaults to tool.{cli-name}, matching how click-extra and its downstream CLIs read their section from pyproject.toml.

tests.sphinx.test_sphinx_click_config.test_click_config_section_override_and_suppress(sphinx_app_myst)[source]ΒΆ

:section: overrides the example header; an empty value drops it.

tests.sphinx.test_sphinx_click_config.test_click_config_bare_schema_argument(sphinx_app_myst)[source]ΒΆ

A dataclass argument documents the schema without any CLI wired.

Without a CLI there is no name to derive the section header from, so the examples render bare assignments.

tests.sphinx.test_sphinx_click_config.test_click_config_no_table_and_no_examples(sphinx_app_myst)[source]ΒΆ

:no-table: and :no-examples: drop their blocks.

tests.sphinx.test_sphinx_click_config.test_click_config_exec_defined_schema_lacks_docstrings(sphinx_app_myst)[source]ΒΆ

A schema defined in an exec’d block renders without descriptions.

tests.sphinx.test_sphinx_click_config.test_click_config_errors_without_schema(sphinx_app_myst)[source]ΒΆ

A CLI with no config_schema raises a clear directive error.

tests.sphinx.test_sphinx_click_config.test_click_config_errors_on_non_schema(sphinx_app_myst)[source]ΒΆ

Resolving the argument to a non-dataclass raises a clear error.

tests.sphinx.test_sphinx_click_config.test_click_config_errors_on_unknown_name(sphinx_app_myst)[source]ΒΆ

An expression that can’t be evaluated raises a clear directive error.

tests.sphinx.test_sphinx_click_config.test_click_config_errors_in_rst(sphinx_app_rst)[source]ΒΆ

click:config raises a clear error when used in an rST document.

tests.sphinx.test_sphinx_click_config.test_click_config_heading_offset_adapts_to_surrounding_section(sphinx_app_myst)[source]ΒΆ

Nested inside an h2 section, option headings render at h3.

class tests.sphinx.test_sphinx_click_config.OrchardConfig(trees=12, rows=4, seasons=<factory>)[source]ΒΆ

Bases: object

Schema whose docstrings make Markdown headings, or look like they do.

trees: int = 12ΒΆ

How many trees grow in the orchard.

Pear and apple trees alternate along each row, so no row holds a single = kind of fruit.

rows: int = 4ΒΆ

How many rows the trees stand in.

# Pruning

Each row is pruned in winter.

seasons: list[str]ΒΆ

Harvest seasons.

# A comment in a code block
---
tests.sphinx.test_sphinx_click_config.test_click_config_warns_on_docstring_heading(sphinx_app_myst)[source]ΒΆ

Each heading in an option docstring is reported at its docstring line.

The lone = makes a setext heading of the paragraph above it, # Pruning is an ATX heading, and the lines of a code block are no heading at all.

tests.sphinx.test_sphinx_click_tree moduleΒΆ

Tests for the click:tree Sphinx directive.

tests.sphinx.test_sphinx_click_tree.KITCHEN_CLI = '```{click:source}\n:hide-source:\nfrom click import command, echo, group, option\n\n@group\ndef kitchen():\n    """Manage kitchen tools and recipes."""\n\n@kitchen.command\n@option("--minutes", type=int, default=5)\ndef boil(minutes):\n    """Boil water for tea."""\n    echo(f"Boiling for {minutes} minutes.")\n\n@kitchen.group\ndef pantry():\n    """Inspect pantry contents."""\n\n@pantry.command\ndef jars():\n    """List jars on the shelf."""\n    echo("Olives, honey, pickles.")\n```\n'ΒΆ

Toy CLI reused across tests. Defines a multi-level group so the walk exercises the recursive descent into nested click.Group commands.

tests.sphinx.test_sphinx_click_tree.test_click_tree_renders_summary_table_and_help_blocks(sphinx_app_myst)[source]ΒΆ

The directive expands into a GFM table + one help capture per command.

tests.sphinx.test_sphinx_click_tree.test_click_tree_inline_import_in_body(sphinx_app_myst)[source]ΒΆ

The directive body runs as a preamble, so a seed click:source is optional.

tests.sphinx.test_sphinx_click_tree.test_click_tree_no_table_and_no_root(sphinx_app_myst)[source]ΒΆ

:no-table: and :no-root: drop the summary table and root block.

tests.sphinx.test_sphinx_click_tree.test_click_tree_max_depth_truncates_walk(sphinx_app_myst)[source]ΒΆ

:max-depth: 1 stops the walk at one level below the root.

tests.sphinx.test_sphinx_click_tree.test_click_tree_label_and_anchor_prefix_override(sphinx_app_myst)[source]ΒΆ

:label-prefix: and :anchor-prefix: override the defaults.

tests.sphinx.test_sphinx_click_tree.test_click_tree_summary_keeps_a_piped_description_in_its_cell(sphinx_app_myst)[source]ΒΆ

A pipe in a command’s summary stays text, rather than splitting its row.

tests.sphinx.test_sphinx_click_tree.test_click_tree_summary_shows_the_whole_description(sphinx_app_myst)[source]ΒΆ

A summary past Click’s 45-character cut shows whole in its cell.

get_short_help_str() cuts there and appends an ellipsis, and the strip of the final period removed that ellipsis, which hid the cut. An ellipsis the author wrote stays.

Each row links to the id of its section, and no two rows share one.

The anchor is the id docutils’ make_id derives, which writes the accented letter of crΓ¨me as its ASCII base. Slugged one name at a time, make_id would also drop the leading digit of 5-spice and 7-spice, and give both the anchor of a spice command.

tests.sphinx.test_sphinx_click_tree.test_click_tree_walks_subcommands_like_the_tree_option(sphinx_app_myst)[source]ΒΆ

The walk lists what Group.list_commands returns, as --tree does.

A lazy subcommand is documented although the group never registers it, in the order the group lists it, and a hidden one is left out.

tests.sphinx.test_sphinx_click_tree.test_click_tree_errors_on_non_command(sphinx_app_myst)[source]ΒΆ

Resolving the argument to a non-Command raises a clear directive error.

tests.sphinx.test_sphinx_click_tree.test_click_tree_errors_on_unknown_name(sphinx_app_myst)[source]ΒΆ

An expression that can’t be evaluated raises a clear directive error.

tests.sphinx.test_sphinx_click_tree.test_click_tree_errors_in_rst(sphinx_app_rst)[source]ΒΆ

click:tree raises a clear error when used in an rST document.

tests.sphinx.test_sphinx_click_tree.test_click_tree_heading_offset_defaults_to_top_level(sphinx_app_myst)[source]ΒΆ

Below a single # Doc title the root renders at h2.

A directive in the document body, inside the title’s h1 section, emits its root one level below.

tests.sphinx.test_sphinx_click_tree.test_click_tree_heading_offset_adapts_to_surrounding_section(sphinx_app_myst)[source]ΒΆ

Nested inside an h3 section, the root renders at h4.

The default heading offset is computed from state.memo.section_level so the document outline stays consistent regardless of where the directive is placed.

tests.sphinx.test_sphinx_click_tree.test_click_tree_heading_offset_explicit_override(sphinx_app_myst)[source]ΒΆ

An explicit :heading-offset: wins over the auto-detected default.

Surrounding headings establish a deep level so the override’s effect is clearly observable in the rendered HTML (without MyST normalizing skipped heading levels).

tests.sphinx.test_sphinx_crosshair moduleΒΆ

Tests for the crosshair of two-axis tables.

tests.sphinx.test_sphinx_crosshair.test_crosshair_ships_with_every_page(sphinx_app_myst)[source]ΒΆ

Every page links the stylesheet and the script, written from their sources.

The static folder they share with the table stylesheet is listed once.

Return type:

None

tests.sphinx.test_sphinx_crosshair.test_script_targets_corner_tables_only()[source]ΒΆ

The script selects the tables click_extra.sphinx.tables marks.

Return type:

None

tests.sphinx.test_sphinx_doctrees moduleΒΆ

Tests for the document each node of a pickled page belongs to.

tests.sphinx.test_sphinx_doctrees.test_pickled_nodes_belong_to_their_page(sphinx_app_myst, block)[source]ΒΆ

Every node of a pickled page belongs to the page’s document.

Each block parses a list in a document of its own, then moves it into the page. docutils points the list at the page, and leaves each item below it pointing at the document it was parsed in.

tests.sphinx.test_sphinx_fail_on_warnings moduleΒΆ

Tests for failing a Sphinx build on the warning types a project lists.

tests.sphinx.test_sphinx_fail_on_warnings.DEAD_LABEL_PAGE = 'Orchard\n=======\n\nSee :ref:`the-walled-garden`.\n'ΒΆ

A reStructuredText page whose one defect is an undefined label: ref.ref.

tests.sphinx.test_sphinx_fail_on_warnings.CLEAN_PAGE = 'Orchard\n=======\n\nApples ripen in autumn.\n'ΒΆ

The same page, without the defect.

tests.sphinx.test_sphinx_fail_on_warnings.DEAD_FRAGMENT_PAGE = '# Orchard\n\nSee [the walled garden](#the-walled-garden).\n'ΒΆ

A MyST page whose one defect is a link to no anchor: myst.xref_missing.

tests.sphinx.test_sphinx_fail_on_warnings.build(tmp_path, page, *, listed=None, suppressed=None, suffix='.rst')[source]ΒΆ

Build a one-page project, and return its exit status and warning stream.

tests.sphinx.test_sphinx_fail_on_warnings.test_listed_types_decide_the_exit_status(tmp_path, listed, suppressed, status)[source]ΒΆ

A warning fails the build only when its type is listed and not suppressed.

tests.sphinx.test_sphinx_fail_on_warnings.test_clean_build_passes(tmp_path)[source]ΒΆ

A listed type fails nothing while no warning of that type is logged.

tests.sphinx.test_sphinx_fail_on_warnings.test_error_counts_each_warning_once(tmp_path)[source]ΒΆ

The error names the matched type, and counts a replayed warning once.

tests.sphinx.test_sphinx_fail_on_warnings.test_dead_myst_fragment_fails_the_build(tmp_path)[source]ΒΆ

The case the hook was written for: a `text <#anchor>`_ link to nothing.

tests.sphinx.test_sphinx_fail_on_warnings.test_collector_does_not_outlive_its_build(tmp_path)[source]ΒΆ

The collector leaves the sphinx logger once its build is over.

A second build cannot tell: creating its app clears every handler of that logger, a collector left behind included.

tests.sphinx.test_sphinx_linkcheck moduleΒΆ

Tests for the github.com authentication of the linkcheck builder.

tests.sphinx.test_sphinx_linkcheck.ORCHARD_AUTH = ('https://orchard\\.example\\.com/', ('gardener', 'spade'))ΒΆ

A linkcheck_auth entry a project declares in its own conf.py.

tests.sphinx.test_sphinx_linkcheck.linkcheck_auth(tmp_path, entries)[source]ΒΆ

Start a linkcheck build of a project declaring entries.

Return type:

list[Any]

Returns:

the linkcheck_auth the builder reads.

tests.sphinx.test_sphinx_linkcheck.test_auth_entry_follows_the_project_ones(tmp_path, monkeypatch)[source]ΒΆ

With a token, the github.com entry comes after the entries of conf.py.

Sphinx signs a request with the first entry matching its URL, so a project entry keeps precedence.

Return type:

None

tests.sphinx.test_sphinx_linkcheck.test_no_auth_entry_without_a_token(tmp_path, monkeypatch, token)[source]ΒΆ

Without a token, linkcheck_auth holds the entries of conf.py alone.

Return type:

None

tests.sphinx.test_sphinx_linkcheck.test_bearer_auth_signs_with_the_token(monkeypatch)[source]ΒΆ

The request carries the token the environment holds when it goes out.

Return type:

None

tests.sphinx.test_sphinx_linkcheck.test_github_url_pattern(url, signed)[source]ΒΆ

The token signs every page of github.com but a release download.

Return type:

None

tests.sphinx.test_sphinx_manpages moduleΒΆ

Tests for click_extra.sphinx.manpages.

tests.sphinx.test_sphinx_manpages.test_manpages_hook_writes_tree_into_outdir(tmp_path)[source]ΒΆ

An entry with just script writes the whole tree under man/.

tests.sphinx.test_sphinx_manpages.test_manpages_hook_honors_prog_name_and_output_dir(tmp_path)[source]ΒΆ

An entry can override both the basename and the subdirectory.

tests.sphinx.test_sphinx_manpages.test_manpages_hook_skips_non_html_builder(tmp_path)[source]ΒΆ

Non-HTML builders (like linkcheck) must not emit man pages.

tests.sphinx.test_sphinx_manpages.test_manpages_hook_empty_config_is_noop(tmp_path)[source]ΒΆ

An empty list leaves the build untouched.

tests.sphinx.test_sphinx_manpages.test_manpages_hook_skips_entry_without_script(tmp_path)[source]ΒΆ

An entry missing script is skipped (logged as a warning) instead of aborting the build.

tests.sphinx.test_sphinx_manpages.test_manpages_module_help_documents_config_shape()[source]ΒΆ

The module docstring spells out every supported key.

A safety net against silent removal: distributors and downstream projects depend on the docstring as the canonical reference, since it is what help(click_extra.sphinx.manpages) prints.

tests.sphinx.test_sphinx_manpages.test_manpages_hook_emits_html_siblings(tmp_path)[source]ΒΆ

When a renderer is available, every .1 gets a .1.html next to it whose body carries the section headings from the source roff.

tests.sphinx.test_sphinx_manpages.test_manpages_hook_respects_render_html_opt_out(tmp_path)[source]ΒΆ

render_html=False skips the HTML pass even when a renderer is present, keeping the build to roff only.

The directive emits a bullet list with one entry per (sub)command of every script declared in click_extra_manpages.

linkcheck ignores the links of the index instead of reporting them broken.

Only an HTML build writes the pages they point at, while linkcheck looks for a relative link in the source tree, where those pages never are.

Links resolve from wherever the builder publishes the page.

A second builder reusing pickled doctrees still gets its own layout.

Sphinx does not invalidate its doctree cache when the builder changes, so the directive never re-runs on the second pass. A link resolved at parse time would keep the first builder’s layout and point at nothing.

tests.sphinx.test_sphinx_manpages.test_manpages_directive_is_noop_when_config_empty(tmp_path)[source]ΒΆ

An empty config means no bullet list, no warning, build still finishes.

tests.sphinx.test_sphinx_manpages.test_manpages_directive_renders_inline_literals_as_code(tmp_path)[source]ΒΆ

Inline reST literals in a command’s short_help land as <code> spans in the rendered index, not as raw backticks rendered like quotes.

tests.sphinx.test_sphinx_matrix moduleΒΆ

Tests for click_extra.sphinx.matrix.

Split in two halves: the dependency-light matrix-generation logic (git tag walking, spec parsing, floor filtering) and the matrix Sphinx directive that surfaces it. Both live under tests/sphinx/ because importing click_extra.sphinx.matrix pulls in the Sphinx package; the sibling conftest.py skips the whole tree when Sphinx or MyST-Parser is absent.

tests.sphinx.test_sphinx_matrix.pytestmark = MarkDecorator(mark=Mark(name='skipif', args=(False,), kwargs={'reason': 'matrix generation walks git tags, so the whole module needs a git binary'}))ΒΆ

Skip the module when git is missing, instead of failing every test.

The sibling conftest.py skips the tree when Sphinx or MyST-Parser is absent. Git is the third thing this module needs, and the only one that is a binary rather than an import, so that guard cannot cover it.

tests.sphinx.test_sphinx_matrix.MATRIX_MODULE = 'click_extra.sphinx.matrix'ΒΆ

Dotted path the PyPI lookup is patched through.

Importing the module object instead would put a matrix name in scope, and ruff would then read every {matrix} fence in the fixtures as an f-string.

tests.sphinx.test_sphinx_matrix.LABEL_DATE_RE = re.compile(' \\(\\d{4}-\\d{2}-\\d{2}\\)')ΒΆ

The first-release date a row label carries after its lower bound.

tests.sphinx.test_sphinx_matrix.WIDGET_CORNER = '`proj` ↴ \\\\ `widget` β†’'ΒΆ

Top-left cell of a proj table tracking widget, backslash escaped.

tests.sphinx.test_sphinx_matrix.offline_pypi(monkeypatch)[source]ΒΆ

Anchor every table on uv.lock, with no call to PyPI.

The fixtures track a made-up widget dependency, and a real project of that name on PyPI would move their columns. The tests of the PyPI anchor stub the lookup again with the releases they need.

Return type:

None

tests.sphinx.test_sphinx_matrix.unreadable_pypi(monkeypatch)[source]ΒΆ

Make every PyPI lookup fail, over the read offline_pypi stubs.

The lookup answers required the way the real one does: a required read raises, and any other read returns no release.

Return type:

None

tests.sphinx.test_sphinx_matrix.git_repo(path)[source]ΒΆ

Initialize a bare-bones git repository at path.

Returns a run(*args) helper executing commands in that working tree, so each fixture only spells out the commits and tags it cares about.

Return type:

Callable[..., None]

tests.sphinx.test_sphinx_matrix.dated_tag(repo, tag, date)[source]ΒΆ

Commit the working tree of repo on date and tag it tag.

The dates decide when a range was superseded, which the undeclared cells of both axes read.

Return type:

None

tests.sphinx.test_sphinx_matrix.declare_python(repo, spec, *classifiers)[source]ΒΆ

Write a pyproject.toml declaring requires-python and classifiers.

Return type:

None

tests.sphinx.test_sphinx_matrix.declare_widget(repo, spec)[source]ΒΆ

Write a pyproject.toml requiring widget{spec}.

Picks whichever dialect can express the range: Poetry’s caret and tilde are not valid PEP 508, so they only ever appear in Poetry’s own table.

Return type:

None

tests.sphinx.test_sphinx_matrix.named_repo(path, pyproject)[source]ΒΆ

Tag one release in a git repository at path, then leave pyproject as its working-tree pyproject.toml, or no such file for None.

The tagged file declares the Python support a matrix renders. The working-tree file is the one the default package label is read from.

Return type:

Path

tests.sphinx.test_sphinx_matrix.table_cells(line)[source]ΒΆ

Split one line of a rendered GFM matrix into its stripped cells.

Return type:

list[str]

tests.sphinx.test_sphinx_matrix.table_header(table)[source]ΒΆ

Return the header cells of a rendered GFM matrix, corner label first.

Return type:

list[str]

tests.sphinx.test_sphinx_matrix.tagged_table_rows(table)[source]ΒΆ

Parse a rendered GFM matrix into {row label: [cells…]}.

Lets a test assert a whole row at once (spec, then the full βœ… / ❌ vector) instead of probing the table for loose substrings. The key drops the first-release date of the label, since the fixtures tag their commits on the day the test runs.

Return type:

dict[str, list[str]]

tests.sphinx.test_sphinx_matrix.test_parse_python_spec(spec, expected)[source]ΒΆ
Return type:

None

tests.sphinx.test_sphinx_matrix.test_python_versions_released_by_default_table()[source]ΒΆ
Return type:

None

tests.sphinx.test_sphinx_matrix.test_python_versions_released_by_sorted_ascending()[source]ΒΆ
Return type:

None

tests.sphinx.test_sphinx_matrix.test_python_versions_released_by_custom_table()[source]ΒΆ
Return type:

None

tests.sphinx.test_sphinx_matrix.test_python_release_dates_shape()[source]ΒΆ

Every entry must be X.Y β†’ ISO date string.

Return type:

None

tests.sphinx.test_sphinx_matrix.synthetic_repo(tmp_path)[source]ΒΆ

Build a tiny git repo with two tagged commits declaring different Python support sets, so python_matrix_groups sees an evolution.

Return type:

Path

tests.sphinx.test_sphinx_matrix.test_python_matrix_groups_synthetic(synthetic_repo)[source]ΒΆ
Return type:

None

tests.sphinx.test_sphinx_matrix.test_python_matrix_groups_returns_named_tuple(synthetic_repo)[source]ΒΆ
Return type:

None

tests.sphinx.test_sphinx_matrix.test_python_matrix_groups_reads_a_tag_that_is_no_utf8(synthetic_repo)[source]ΒΆ

A tag name that does not decode as UTF-8 leaves the walk going.

The tag goes in packed-refs: a loose ref is a file, and APFS refuses a file name that is no UTF-8.

Return type:

None

tests.sphinx.test_sphinx_matrix.test_python_matrix_groups_no_tags(tmp_path)[source]ΒΆ

A repo with no matching tags returns an empty list.

Return type:

None

tests.sphinx.test_sphinx_matrix.test_python_matrix_groups_version_floor(synthetic_repo)[source]ΒΆ

version_floor drops release tags below the bare version.

Return type:

None

tests.sphinx.test_sphinx_matrix.test_python_matrix_groups_ceiling_honored(tmp_path)[source]ΒΆ

A declared <X.Y ceiling excludes those versions from βœ….

Return type:

None

tests.sphinx.test_sphinx_matrix.test_python_matrix_groups_keeps_declared_spec(synthetic_repo)[source]ΒΆ

Each group carries its raw requires-python next to the set it attests, since the two drive different cells.

Return type:

None

tests.sphinx.test_sphinx_matrix.test_python_matrix_groups_respelled_floor_continues_range(tmp_path)[source]ΒΆ

Re-spelling a floor-only requires-python does not end its range.

The range lasts until 2.0.0, after Python 3.11 and 3.12 came out, so its capped support includes both. Split at the re-spelling, its older half would end in June 2022, before 3.11, and read 3.10 alone.

Return type:

None

tests.sphinx.test_sphinx_matrix.test_range_labels(bounds, expected)[source]ΒΆ
Return type:

None

tests.sphinx.test_sphinx_matrix.test_python_cell(version, expected)[source]ΒΆ
Return type:

None

tests.sphinx.test_sphinx_matrix.test_python_cell_spec_shapes(spec, version, expected)[source]ΒΆ
Return type:

None

tests.sphinx.test_sphinx_matrix.test_python_matrix_table_three_states(tmp_path)[source]ΒΆ

A release claiming less than its floor allows renders all three cells.

The classifiers stop at 3.11 while requires-python only rules out everything under 3.10, so 3.12 is neither supported nor forbidden.

Return type:

None

tests.sphinx.test_sphinx_matrix.test_python_matrix_table_synthetic(synthetic_repo)[source]ΒΆ
Return type:

None

tests.sphinx.test_sphinx_matrix.test_python_matrix_table_show_date(synthetic_repo, show_date)[source]ΒΆ

show_date follows each row label with its first release date.

Return type:

None

tests.sphinx.test_sphinx_matrix.test_python_matrix_table_column_order(synthetic_repo, column_order)[source]ΒΆ
Return type:

None

tests.sphinx.test_sphinx_matrix.test_python_matrix_table_row_order(synthetic_repo, row_order)[source]ΒΆ
Return type:

None

tests.sphinx.test_sphinx_matrix.test_python_matrix_table_invalid_order(synthetic_repo)[source]ΒΆ
Return type:

None

tests.sphinx.test_sphinx_matrix.test_python_matrix_table_python_floor(synthetic_repo)[source]ΒΆ

python_floor trims the low Python columns from the header.

Return type:

None

tests.sphinx.test_sphinx_matrix.test_python_matrix_table_empty(tmp_path)[source]ΒΆ

An empty repo produces the empty string, matching the if not groups: return "" early exit.

Return type:

None

tests.sphinx.test_sphinx_matrix.split_floor_repo(tmp_path)[source]ΒΆ

A repo raising its Python floor in the 1.0.1 patch release.

The newest release supports 3.11 and later, and 1.0.0 only 3.9, so the support envelope starts at 1.0.1, inside the 1.0 minor series.

Return type:

Path

tests.sphinx.test_sphinx_matrix.test_python_matrix_table_envelope(split_floor_repo)[source]ΒΆ

The ranges below the oldest one supporting the floor or a later Python go.

The oldest columns, which no remaining range supports, go with them.

Return type:

None

tests.sphinx.test_sphinx_matrix.test_python_matrix_table_full_history(split_floor_repo)[source]ΒΆ

The full history keeps every range and every column.

Return type:

None

tests.sphinx.test_sphinx_matrix.test_matrix_directive_full_history_option(sphinx_app_myst, split_floor_repo, full_history)[source]ΒΆ

:full-history: keeps the releases the envelope leaves out.

Return type:

None

tests.sphinx.test_sphinx_matrix.test_update_matrix_blocks_full_history_marker(split_floor_repo, tmp_path)[source]ΒΆ

The full-history marker flag keeps the releases the envelope drops.

Return type:

None

tests.sphinx.test_sphinx_matrix.test_matrix_python_directive_renders_table(sphinx_app_myst, synthetic_repo)[source]ΒΆ

{matrix} python renders the generated table as a real <table>.

Return type:

None

tests.sphinx.test_sphinx_matrix.test_matrix_python_directive_respects_floors(sphinx_app_myst, synthetic_repo)[source]ΒΆ

The hyphenated directive options map to the floor parameters.

tests.sphinx.test_sphinx_matrix.test_matrix_python_directive_order_options(sphinx_app_myst, synthetic_repo)[source]ΒΆ

The :column-order: / :row-order: options flip both axes.

tests.sphinx.test_sphinx_matrix.test_matrix_python_directive_no_tags_renders_nothing(sphinx_app_myst, tmp_path)[source]ΒΆ

A repository with no release tags yields no table (a build warning).

tests.sphinx.test_sphinx_matrix.test_matrix_python_directive_renders_embedded_table(sphinx_app_myst)[source]ΒΆ

An embedded table renders as a real <table> without any git access.

This is the self-updating steady state: the offline updater keeps the table in the source, and the build renders that copy verbatim.

Return type:

None

tests.sphinx.test_sphinx_matrix.test_update_matrix_blocks_populates_empty_block(synthetic_repo, tmp_path)[source]ΒΆ

The updater fills an empty block, keeping options and surrounding text.

Return type:

None

tests.sphinx.test_sphinx_matrix.test_update_matrix_blocks_idempotent(synthetic_repo, tmp_path)[source]ΒΆ

A second run over freshly written blocks reports no change.

Return type:

None

tests.sphinx.test_sphinx_matrix.test_update_matrix_blocks_check_mode(synthetic_repo, tmp_path)[source]ΒΆ

check=True flags a stale block without writing to disk.

Return type:

None

tests.sphinx.test_sphinx_matrix.test_update_matrix_blocks_leaves_bad_path_untouched(tmp_path)[source]ΒΆ

A block whose git generation fails is left byte-for-byte unchanged.

Return type:

None

tests.sphinx.test_sphinx_matrix.test_update_matrix_blocks_keeps_other_line_separators(tmp_path)[source]ΒΆ

Prose holding a line separator other than a newline is copied verbatim.

A Unicode line separator splits a line for str.splitlines, not for a Markdown reader: a refresh writing it back as a newline would rewrite the page, and report it stale on every check.

Return type:

None

tests.sphinx.test_sphinx_matrix.test_update_matrix_blocks_leaves_an_unreadable_pypi_untouched(synthetic_dep_repo, tmp_path, unreadable_pypi)[source]ΒΆ

An unreachable PyPI is a generation failure, not a stale block.

Return type:

None

tests.sphinx.test_sphinx_matrix.test_update_matrix_blocks_skips_examples_nested_in_code_block(synthetic_repo, tmp_path)[source]ΒΆ

Matrix examples shown inside a longer code fence are never refreshed.

Both forms are documented illustrations here, not live blocks, even though their generation would succeed: the fence-aware walk copies them verbatim.

Return type:

None

tests.sphinx.test_sphinx_matrix.test_refresh_directives_cli(synthetic_repo, tmp_path)[source]ΒΆ

click-extra refresh-directives refreshes in place; –check gates CI.

Return type:

None

tests.sphinx.test_sphinx_matrix.test_refresh_directives_cli_without_sphinx(tmp_path, monkeypatch)[source]ΒΆ

The command fails gracefully (not a traceback) when sphinx is absent.

Return type:

None

tests.sphinx.test_sphinx_matrix.test_to_specifier_set(spec, member, nonmember)[source]ΒΆ
Return type:

None

tests.sphinx.test_sphinx_matrix.test_to_specifier_set_unparsable(spec)[source]ΒΆ

An unparsable specifier yields None, which renders as an all-❌ row rather than raising out of the Sphinx build.

Return type:

None

tests.sphinx.test_sphinx_matrix.test_to_specifier_set_empty_matches_everything()[source]ΒΆ

An empty specifier is the universal set, not None.

Unreachable through the matrix itself, since a tag with no declared requirement is skipped before this point.

Return type:

None

tests.sphinx.test_sphinx_matrix.test_spec_identity(spec, other, expected)[source]ΒΆ

Two specifiers share an identity when they accept the same versions.

Return type:

None

tests.sphinx.test_sphinx_matrix.test_spec_floor(spec, expected)[source]ΒΆ
Return type:

None

tests.sphinx.test_sphinx_matrix.test_extract_requirement(declaration, expected)[source]ΒΆ
Return type:

None

tests.sphinx.test_sphinx_matrix.test_extract_requirement_canonicalizes_name()[source]ΒΆ

PEP 503 name normalization decides the match, so a dependency spelled with any separator is found under any other spelling.

Return type:

None

tests.sphinx.test_sphinx_matrix.test_extract_requirement_from_setup_py()[source]ΒΆ

A setup.py release has no tables to read, so its string literals are harvested and filtered by the same PEP 508 parse.

Return type:

None

tests.sphinx.test_sphinx_matrix.test_dependency_cell(spec, version, released, expected)[source]ΒΆ
Return type:

None

tests.sphinx.test_sphinx_matrix.test_dependency_cell_caps_later_majors(version, released, expected)[source]ΒΆ

A superseded range never attests a major newer than its cap.

Return type:

None

tests.sphinx.test_sphinx_matrix.test_newest_major()[source]ΒΆ

The newest major out by a day, and none without a dated release.

Return type:

None

tests.sphinx.test_sphinx_matrix.test_dependency_columns(rows, shown, expected)[source]ΒΆ
Return type:

None

tests.sphinx.test_sphinx_matrix.test_envelope(rows, full_history, expected)[source]ΒΆ

Rows come oldest first, and columns run from the oldest version.

Return type:

None

tests.sphinx.test_sphinx_matrix.test_column_candidates(specs, releases, locked, expected)[source]ΒΆ
Return type:

None

tests.sphinx.test_sphinx_matrix.test_latest_locked_version(tmp_path, dep_name, expected)[source]ΒΆ
Return type:

None

tests.sphinx.test_sphinx_matrix.test_latest_locked_version_without_lockfile(tmp_path)[source]ΒΆ

A project with no uv.lock locks nothing, rather than failing.

Return type:

None

tests.sphinx.test_sphinx_matrix.stub_releases(monkeypatch, *versions, dates=None)[source]ΒΆ

Make PyPI list versions as the stable releases of every dependency.

A release is undated unless dates gives its ISO publication date, so a stub without dates never produces an undeclared cell.

Return type:

None

tests.sphinx.test_sphinx_matrix.synthetic_dep_repo(tmp_path)[source]ΒΆ

A git repo whose widget dependency floor evolves across two tags, exercising both minor-grouped and patch-split column derivation.

Return type:

Path

tests.sphinx.test_sphinx_matrix.test_dependency_matrix_groups(synthetic_dep_repo)[source]ΒΆ
Return type:

None

tests.sphinx.test_sphinx_matrix.test_dependency_matrix_table_columns_and_cells(synthetic_dep_repo, monkeypatch)[source]ΒΆ
Return type:

None

tests.sphinx.test_sphinx_matrix.exotic_spec_repo(tmp_path)[source]ΒΆ

A repo whose widget requirement takes a different exotic shape at every tag, so one render exercises the whole specifier vocabulary.

The caret tag also migrates the declaration from Poetry to PEP 621 and back, the way a real project’s history crosses packaging backends.

Return type:

Path

tests.sphinx.test_sphinx_matrix.test_dependency_matrix_table_exotic_specs(exotic_spec_repo, monkeypatch)[source]ΒΆ

Each specifier shape resolves to the right βœ… / ❌ vector.

The exclusion hole of >=4.0,!=4.1.* isolates 4.1.0, and the 2.1.0 release no range accepts keeps its column between two that some do. The full history keeps the ranges the support envelope would leave out.

Return type:

None

tests.sphinx.test_sphinx_matrix.test_dependency_matrix_table_merges_equivalent_specs(tmp_path)[source]ΒΆ

Consecutive tags differing only in spelling form a single range.

Poetry’s ^2.0 and PEP 621’s >=2.0,<3.0.0 describe the same set, so they group into one range instead of two identical rows. This is what a packaging-backend migration looks like in the history.

Return type:

None

tests.sphinx.test_sphinx_matrix.narrowing_floor_repo(tmp_path)[source]ΒΆ

A repo whose widget floor narrows across three tags, locked at 4.0.0.

The caret range accepts 3.1 and the compatible-release range does not.

Return type:

Path

tests.sphinx.test_sphinx_matrix.test_dependency_matrix_table_merge_keeps_distinct_specs(tmp_path, monkeypatch, show_spec, expected)[source]ΒΆ

Ranges whose cells coincide merge, unless their specs differ.

Both ranges accept every release so far, and differ only above the newest one. A merged row shows the Spec cell of its oldest range, so merging them would claim <4 for releases that declared <5.

Return type:

None

tests.sphinx.test_sphinx_matrix.test_dependency_matrix_table_bins_split_ranges(narrowing_floor_repo, monkeypatch)[source]ΒΆ

The releases between two floors tell the ranges apart on their cells.

Return type:

None

tests.sphinx.test_sphinx_matrix.pinned_widget_repo(tmp_path, name, spec)[source]ΒΆ

A one-tag repo pinning widget to spec, locked at 2.4.0.

Return type:

Path

tests.sphinx.test_sphinx_matrix.test_dependency_matrix_table_pinned_spec(tmp_path, monkeypatch, spec, columns, cells)[source]ΒΆ
Return type:

None

tests.sphinx.test_sphinx_matrix.test_dependency_matrix_table_lone_ceiling(tmp_path)[source]ΒΆ

A lone ceiling anchors no column of its own.

Unlike a pin, it has no lower bound to place, so the only column left is the locked version, which the ceiling genuinely forbids. The all-❌ row is the honest rendering here, not a missing column.

Return type:

None

tests.sphinx.test_sphinx_matrix.test_dependency_matrix_table_suffixed_poetry_floor(tmp_path, monkeypatch)[source]ΒΆ

A Poetry caret on a post-release translates like any other caret.

Its floor keeps the suffix, so the release it follows falls out of range, and its ceiling ignores it, so the later 2.x release stays in.

Return type:

None

tests.sphinx.test_sphinx_matrix.test_dependency_matrix_table_shows_a_release_ahead_of_the_lock(tmp_path, monkeypatch)[source]ΒΆ

A release newer than the locked one gets a column of its own.

The table shows it before the lockfile adopts it, here as a major no range accepts yet. The locked version counts even when PyPI does not list it.

Return type:

None

tests.sphinx.test_sphinx_matrix.WIDGET_DATES = {'1.0.0': '2023-12-01', '2.0.0': '2024-05-01', '2.1.0': '2024-06-10', '3.0.0': '2025-01-01'}ΒΆ

Publication dates of the widget releases the dated repository sees.

tests.sphinx.test_sphinx_matrix.dated_dep_repo(tmp_path)[source]ΒΆ

A repo raising its widget floor at each of three dated tags.

Return type:

Path

tests.sphinx.test_sphinx_matrix.test_dependency_matrix_table_undeclared_after_superseded(dated_dep_repo, monkeypatch)[source]ΒΆ

A release out after a range was superseded reads – for that range, though its specifier accepts it. So does a release of a major out after the last release of the range: 1.0.0 never met widget 2.x, and 2.0.0 never met widget 3.0.0.

Return type:

None

tests.sphinx.test_sphinx_matrix.test_dependency_matrix_table_unmet_major_after_last_release(tmp_path, monkeypatch)[source]ΒΆ

A major out after the last release of a superseded range reads –.

widget 1.5.0 and 2.0.0 both come out after 1.1.0, the last release of the 1.x range, and before 2.0.0 supersedes it. Its open specifier accepts both, and the range met the 1.x major, so 1.5.0 reads βœ…. No release of the range ever met 2.0.0.

Return type:

None

tests.sphinx.test_sphinx_matrix.test_dependency_matrix_table_envelope(dated_dep_repo, monkeypatch)[source]ΒΆ

The envelope stops at the oldest range supporting the floor or later.

A range supports a dated release it accepts only when the release came out while the range was current, from a major out by its last release. Neither older range ever met widget 3.0.0, the floor of the newest range, so both go, and the columns only they accepted too.

Return type:

None

tests.sphinx.test_sphinx_matrix.ENVELOPE_WIDGET_DATES = {'1.0.0': '2021-12-01', '2.0.0': '2023-05-01', '3.0.0': '2024-12-01'}ΒΆ

Publication dates of the widget releases the envelope repository sees.

tests.sphinx.test_sphinx_matrix.envelope_repo(tmp_path)[source]ΒΆ

A repo declaring its Python support and a widget floor at each tag.

The Python envelope leaves out 1.0.0, which supports no Python from 3.11 on. The widget one keeps every release.

Return type:

Path

tests.sphinx.test_sphinx_matrix.test_envelope_list_across_axes(envelope_repo, monkeypatch)[source]ΒΆ

The release bound is the strictest one, and each version bound is read again over the releases left in scope.

Return type:

None

tests.sphinx.test_sphinx_matrix.test_envelope_list_without_cut(synthetic_dep_repo)[source]ΒΆ

With no envelope leaving out a release, the list has no release bound. An axis the history never declares is skipped, and a version of unknown date gets no date.

Return type:

None

tests.sphinx.test_sphinx_matrix.test_update_matrix_blocks_envelope_region(envelope_repo, tmp_path, monkeypatch)[source]ΒΆ

The refresh fills an envelope region between its markers, and settles.

Return type:

None

tests.sphinx.test_sphinx_matrix.test_update_matrix_blocks_leaves_an_envelope_region_untouched(envelope_repo, tmp_path, unreadable_pypi, args)[source]ΒΆ

An unreadable PyPI, or a region naming no axis, rewrites nothing.

Return type:

None

tests.sphinx.test_sphinx_matrix.test_dependency_matrix_groups_respelled_spec_continues_range(tmp_path, monkeypatch)[source]ΒΆ

A re-spelled specifier continues its range.

widget 1.5.0 came out after 1.1.0 re-spelled the specifier, while that range was still current, so it reads βœ… for the whole range. Split at the re-spelling, 1.0.0 would look superseded before 1.5.0 came out. The whole history keeps the range in the table, though it never met the 2.x major that the newest range floors.

Return type:

None

tests.sphinx.test_sphinx_matrix.test_dependency_matrix_table_headers_read_in_column_order(synthetic_dep_repo, monkeypatch, column_order, expected)[source]ΒΆ

A header reads from the bound its neighbors continue: the newest one while the columns run newest first, the oldest one otherwise.

Return type:

None

tests.sphinx.test_sphinx_matrix.pypi(httpserver, monkeypatch)[source]ΒΆ

Serve PyPI’s JSON API from the local test server.

tests.sphinx.test_sphinx_matrix.test_pypi_releases(pypi)[source]ΒΆ

The lookup asks for the normalized name and sorts the releases.

Return type:

None

tests.sphinx.test_sphinx_matrix.test_pypi_releases_dates(pypi)[source]ΒΆ

A release is dated by the first upload among its files not yanked.

Return type:

None

tests.sphinx.test_sphinx_matrix.test_pypi_releases_discards(pypi, tag, files)[source]ΒΆ

Pre-releases, yanked or empty releases and invalid versions are dropped.

Return type:

None

tests.sphinx.test_sphinx_matrix.test_pypi_releases_unreadable(pypi, body, status)[source]ΒΆ

An error or a malformed answer costs the columns, not the table.

A caller that cannot use the fallback columns hears about the failure.

Return type:

None

tests.sphinx.test_sphinx_matrix.test_to_specifier_set_poetry_conformance(spec, bounds)[source]ΒΆ

Every Poetry range translates to the interval Poetry documents.

The 0.x caret is the one that matters in practice: Poetry caps it at the next minor, since a 0. release is allowed to break on every minor.

Return type:

None

tests.sphinx.test_sphinx_matrix.test_to_specifier_set_poetry_bare_wildcard()[source]ΒΆ

Poetry’s bare * allows any version, so it has no bounds to check.

Return type:

None

tests.sphinx.test_sphinx_matrix.test_dependency_matrix_table_show_date(synthetic_dep_repo, show_date)[source]ΒΆ

show_date dates the rows without changing how they merge.

Return type:

None

tests.sphinx.test_sphinx_matrix.test_dependency_matrix_table_column_order(synthetic_dep_repo, column_order)[source]ΒΆ
Return type:

None

tests.sphinx.test_sphinx_matrix.test_dependency_matrix_table_row_order(synthetic_dep_repo, row_order)[source]ΒΆ
Return type:

None

tests.sphinx.test_sphinx_matrix.test_dependency_matrix_table_empty(tmp_path)[source]ΒΆ
Return type:

None

tests.sphinx.test_sphinx_matrix.test_matrix_dependency_directive_renders(sphinx_app_myst, synthetic_dep_repo)[source]ΒΆ

{matrix} <dep> renders the dependency matrix as a real <table>.

tests.sphinx.test_sphinx_matrix.test_update_matrix_blocks_marker_form(synthetic_repo, tmp_path)[source]ΒΆ

The <!-- matrix AXIS opts --> comment form refreshes to a raw table.

Return type:

None

tests.sphinx.test_sphinx_matrix.test_walk_tags_dates_an_annotated_tag(tmp_path)[source]ΒΆ

A tag’s date is its commit’s author date, through an annotated tag too.

The tag object of an annotated tag carries a tagger date of its own, which is not the one the row shows.

Return type:

None

tests.sphinx.test_sphinx_matrix.test_update_matrix_blocks_reads_git_twice_per_refresh(synthetic_repo, tmp_path, monkeypatch)[source]ΒΆ

One refresh lists the tags and reads their files once, whatever the blocks.

Two pages carrying three blocks, with floors of their own, share the same history: the tag listing is one git for-each-ref and every tag’s files one git cat-file --batch.

Return type:

None

tests.sphinx.test_sphinx_matrix.test_update_matrix_blocks_marker_order_options(synthetic_repo, tmp_path)[source]ΒΆ

column-order / row-order marker options flip the refreshed table.

Return type:

None

tests.sphinx.test_sphinx_matrix.test_update_matrix_blocks_marker_show_date(synthetic_repo, tmp_path, flag)[source]ΒΆ

The show-date marker flag dates the refreshed rows.

Return type:

None

tests.sphinx.test_sphinx_matrix.test_matrix_directive_show_date_option(sphinx_app_myst, synthetic_repo)[source]ΒΆ

The :show-date: directive option dates the rendered rows.

Return type:

None

tests.sphinx.test_sphinx_matrix.test_marker_form_renders_natively_in_sphinx(sphinx_app_myst)[source]ΒΆ

A marker region’s raw table renders as a real <table> with no directive involved (so it renders on GitHub the same way).

Return type:

None

tests.sphinx.test_sphinx_matrix.test_resolve_root_relative_base_dir(synthetic_repo, monkeypatch)[source]ΒΆ

A relative base_dir still resolves to the real repo folder, so the default package label is never the empty Path(".").name.

Return type:

None

tests.sphinx.test_sphinx_matrix.test_render_block_default_package_label(tmp_path, pyproject, options, expected)[source]ΒΆ

Without a package option, the label is the name the project declares in its pyproject.toml. The folder name is the fallback.

Return type:

None

tests.sphinx.test_sphinx_matrix.test_update_matrix_blocks_label_ignores_checkout_name(tmp_path)[source]ΒΆ

A copy of a project under another folder name agrees with the table refreshed in the first checkout, so its check reports nothing stale.

Return type:

None

tests.sphinx.test_sphinx_matrix.test_render_block_raises_without_git(tmp_path, monkeypatch)[source]ΒΆ

With git absent from PATH, generation raises an error the callers catch.

Return type:

None

tests.sphinx.test_sphinx_matrix.test_update_matrix_blocks_preserves_table_without_git(tmp_path, monkeypatch)[source]ΒΆ

Refreshing is non-destructive when git is unavailable: an embedded table stays put rather than being wiped by a failed regeneration.

tests.sphinx.test_sphinx_matrix.test_matrix_directive_renders_embedded_without_git(sphinx_app_myst, monkeypatch)[source]ΒΆ

A populated block renders at build time with no git on PATH: the shallow-clone / no-git CI case the embedded copy is designed for.

tests.sphinx.test_sphinx_mermaid moduleΒΆ

Tests for the autoclasstree override that keeps d3 zoom off class diagrams.

tests.sphinx.test_sphinx_mermaid.DIAGRAM = 'Class diagram of orchard.Pear.'ΒΆ

Text the stand-in autoclasstree renders for each diagram.

class tests.sphinx.test_sphinx_mermaid.StubClassDiagram(name, arguments, options, content, lineno, content_offset, block_text, state, state_machine)[source]ΒΆ

Bases: Directive

Stand-in for the autoclasstree directive of sphinxcontrib-mermaid.

required_arguments = 1ΒΆ

Number of required directive arguments.

run(**kwargs)[source]ΒΆ
Return type:

list[Node]

tests.sphinx.test_sphinx_mermaid.stub_setup(app)[source]ΒΆ

Register what the override reads of sphinxcontrib-mermaid.

Return type:

dict[str, bool]

tests.sphinx.test_sphinx_mermaid.mermaid_stub(monkeypatch)[source]ΒΆ

Serve a stand-in for sphinxcontrib-mermaid, which the test group lacks.

The stand-in only holds the directive and the config value the override reads.

Return type:

None

tests.sphinx.test_sphinx_mermaid.build(tmp_path, *, loaded, d3_zoom)[source]ΒΆ

Build a page, with an autoclasstree diagram when the stand-in is loaded.

click_extra.sphinx comes first in extensions, before the directive it overrides is registered. d3_zoom sets mermaid_d3_zoom, left to its default when None.

Return type:

tuple[str, bool]

Returns:

the HTML of the page, and whether autoclasstree is registered.

tests.sphinx.test_sphinx_mermaid.test_class_diagrams_skip_the_zoom(tmp_path, loaded, d3_zoom, overridden)[source]ΒΆ

The override wraps each diagram only with sphinxcontrib-mermaid and zoom on.

The page then links the stylesheet the wrapper hooks into. Otherwise the directive renders as sphinxcontrib-mermaid draws it, or not at all.

Return type:

None

tests.sphinx.test_sphinx_myst_docstrings moduleΒΆ

Tests for the MyST-to-reST docstring conversion hook.

tests.sphinx.test_sphinx_myst_docstrings.test_xref_conversion(myst, expected)[source]ΒΆ
tests.sphinx.test_sphinx_myst_docstrings.test_colon_fence_conversion(myst, expected_fragments)[source]ΒΆ
tests.sphinx.test_sphinx_myst_docstrings.test_colon_fence_preserves_blank_lines()[source]ΒΆ
tests.sphinx.test_sphinx_myst_docstrings.test_colon_fence_blank_line_before_body()[source]ΒΆ

Converted directive inserts blank line between header and body.

tests.sphinx.test_sphinx_myst_docstrings.test_backtick_fence_conversion(myst, expected_fragments)[source]ΒΆ
tests.sphinx.test_sphinx_myst_docstrings.test_mixed_colon_outer_backtick_inner()[source]ΒΆ

Colon fence wrapping a backtick-fenced code block.

tests.sphinx.test_sphinx_myst_docstrings.test_plain_code_fence_conversion(myst, expected_fragments)[source]ΒΆ
tests.sphinx.test_sphinx_myst_docstrings.test_plain_code_fence_blank_line_before_body()[source]ΒΆ

Converted plain code fence inserts blank line between header and body.

tests.sphinx.test_sphinx_myst_docstrings.test_plain_code_fence_not_directive()[source]ΒΆ

Plain code fences must not be confused with directive fences.

tests.sphinx.test_sphinx_myst_docstrings.test_plain_code_fence_idempotent()[source]ΒΆ

Already-converted code-block directive passes through unchanged.

tests.sphinx.test_sphinx_myst_docstrings.test_directive_options_follow_the_header(myst, expected)[source]ΒΆ

reST reads options on the lines right under the header, never after a blank line: a blank line there turns them into content.

tests.sphinx.test_sphinx_myst_docstrings.test_role_opening_a_body_is_not_an_option()[source]ΒΆ

A body opening on a role keeps it as content: an option needs a space after its colon-wrapped name.

tests.sphinx.test_sphinx_myst_docstrings.test_code_block_content_is_verbatim(myst, expected)[source]ΒΆ

Code is not prose: no backtick, role, link or footnote in it converts.

tests.sphinx.test_sphinx_myst_docstrings.test_closing_fence_does_not_open_a_code_block()[source]ΒΆ

The bare line closing a directive fence pairs with that fence.

Read as the opener of a plain code fence instead, it would hold everything up to the next bare fence as code, the directive after it included.

tests.sphinx.test_sphinx_myst_docstrings.test_footnote_reference_conversion(myst, expected)[source]ΒΆ
tests.sphinx.test_sphinx_myst_docstrings.test_footnote_definition_conversion(myst, expected)[source]ΒΆ
tests.sphinx.test_sphinx_myst_docstrings.test_footnote_ref_and_def_combined()[source]ΒΆ

Footnote reference and definition in the same docstring.

tests.sphinx.test_sphinx_myst_docstrings.test_footnote_def_not_matched_as_ref()[source]ΒΆ

Footnote definition must not also produce a spurious reference.

reST has no nested markup, so backticks are stripped from link labels.

tests.sphinx.test_sphinx_myst_docstrings.test_inline_code_conversion(myst, expected)[source]ΒΆ
tests.sphinx.test_sphinx_myst_docstrings.test_inline_code_not_converted(text)[source]ΒΆ
tests.sphinx.test_sphinx_myst_docstrings.test_double_backtick_span_keeps_its_backticks(myst, expected)[source]ΒΆ

A double-backtick span keeps its single backticks single.

Doubled, they would end the reST literal early: the conversion must parse into whole literals, with no warning.

tests.sphinx.test_sphinx_myst_docstrings.test_inline_code_no_cross_contamination_with_xref(myst, expected)[source]ΒΆ

Closing backtick of a cross-ref must not pair with inline code.

A backtick span starting with _ must not be read as a hyperlink ref.

The reST hyperlink-reference pattern ` `label`_ ` would otherwise let the protection regex span the gap between two inline-code spans (consuming the first span’s closing backtick and the second span’s leading underscore), corrupting both. A hyperlink ref’s opening backtick is anchored at a non-word boundary, but that alone is not enough: when the first span’s content ends in a non-word character (`<stdout>`, `f()`), its closing backtick also clears that lookbehind. The ref’s trailing marker (_/__) not being glued to an identifier is what rejects the false match while still matching real ` `label`_ ` references.

tests.sphinx.test_sphinx_myst_docstrings.test_rst_literals_are_opaque(text)[source]ΒΆ

Double-backtick reST literals pass through every step verbatim.

tests.sphinx.test_sphinx_myst_docstrings.test_nested_protected_spans_are_restored(text)[source]ΒΆ

A reST literal inside a span protected later comes back whole.

Both are stashed behind placeholders: restored in the wrong order, the inner one would leave its NUL-delimited placeholder in the output.

tests.sphinx.test_sphinx_myst_docstrings.test_role_shaped_code_span_not_protected_as_role(myst, expected)[source]ΒΆ

Role-shaped text inside a code span is code, wherever the span holds it.

tests.sphinx.test_sphinx_myst_docstrings.test_idempotent_rst_passthrough(text)[source]ΒΆ
tests.sphinx.test_sphinx_myst_docstrings.test_idempotent_already_converted()[source]ΒΆ

Running the converter twice produces the same result.

tests.sphinx.test_sphinx_myst_docstrings.test_idempotent_full_rst_docstring()[source]ΒΆ

A complete reST docstring passes through unchanged.

tests.sphinx.test_sphinx_myst_docstrings.test_mixed_myst_attribute_then_rst_metadata()[source]ΒΆ

Simulates generate_docstring() output: MyST attribute docstring concatenated with reST metadata lines.

tests.sphinx.test_sphinx_myst_docstrings.test_real_detection_function()[source]ΒΆ
tests.sphinx.test_sphinx_myst_docstrings.test_all_conversions_combined()[source]ΒΆ

A docstring exercising every conversion step in one pass.

tests.sphinx.test_sphinx_myst_docstrings.test_real_caution_with_code_block()[source]ΒΆ
tests.sphinx.test_sphinx_myst_docstrings.test_myst_inside_field_lists(myst, expected)[source]ΒΆ

MyST inline constructs inside field list entries are converted.

tests.sphinx.test_sphinx_myst_docstrings.test_full_docstring_with_myst_field_lists()[source]ΒΆ

Realistic docstring with MyST in both prose and field list entries.

tests.sphinx.test_sphinx_myst_docstrings.test_unsupported_constructs_pass_through(myst, description)[source]ΒΆ

Unsupported MyST constructs pass through unchanged.

tests.sphinx.test_sphinx_myst_docstrings.test_curly_braces_in_inline_code()[source]ΒΆ

Inline code containing { and } characters.

A standalone :word: in single backticks is safe: it gets doubled to {word} because the xref regex needs the :word:``target pattern (two backtick-delimited spans). Double-backtick input also passes through.

The dangerous case is :word:``text where the braces plus adjacent backtick-delimited span mimics the xref pattern. The convert-to-myst command intentionally keeps these as double backticks to avoid this.

tests.sphinx.test_sphinx_myst_docstrings.test_plain_code_fence_empty_body()[source]ΒΆ

Plain code fence with an empty body.

tests.sphinx.test_sphinx_myst_docstrings.test_longer_fence_holds_a_shorter_one(myst, expected)[source]ΒΆ

A fence closes on a run of its own length, as in any MyST document.

tests.sphinx.test_sphinx_myst_docstrings.test_blank_line_opening_a_body_goes_with_the_header()[source]ΒΆ

MyST drops the blank line opening a directive body, options or not.

tests.sphinx.test_sphinx_myst_docstrings.test_nested_same_type_fences_not_supported()[source]ΒΆ

Nested fences of the same length are not reliably converted.

A colon fence inside a colon fence, or a backtick fence inside a backtick fence, may not parse correctly: a fence closes on the first bare run of its character at least as long as its opener.

tests.sphinx.test_sphinx_myst_docstrings.test_directive_inside_field_list_not_supported()[source]ΒΆ

Fenced directives inside field list entries do not render correctly.

Field list entries in Sphinx are paragraph-level constructs. Block-level MyST content (admonitions, code blocks) inside them is converted by the regex but won’t render correctly in Sphinx.

A URL holding a balanced pair of parentheses is kept whole.

tests.sphinx.test_sphinx_myst_docstrings.test_consecutive_field_list_entries_all_converted()[source]ΒΆ

Multiple consecutive field list entries each get their content converted.

tests.sphinx.test_sphinx_myst_docstrings.test_empty_field_list_content()[source]ΒΆ

Field list entries with empty or whitespace-only content.

tests.sphinx.test_sphinx_myst_docstrings.test_xref_adjacent_to_field_list_colon()[source]ΒΆ

Cross-reference immediately after the field list colon.

tests.sphinx.test_sphinx_myst_docstrings.test_multiple_xrefs_in_single_field_entry()[source]ΒΆ

Multiple cross-references in one field list entry.

Markdown link with backtick-wrapped label inside a field list entry.

tests.sphinx.test_sphinx_myst_docstrings.test_setup_rejects_wrong_extension_order()[source]ΒΆ

Extension must error if sphinx_autodoc_typehints loaded first.

tests.sphinx.test_sphinx_myst_docstrings.test_setup_accepts_correct_order()[source]ΒΆ

Extension loads normally when sphinx_autodoc_typehints is absent.

tests.sphinx.test_sphinx_python moduleΒΆ

Tests for the python:* Sphinx directive family.

Covers python:source, python:run, and the three render variants:

  • python:render (host parser)

  • python:render-myst (forced MyST, regardless of host)

  • python:render-rst (forced reST, regardless of host)

tests.sphinx.test_sphinx_python.test_python_run_renders_stdout(sphinx_app_myst)[source]ΒΆ

python:run captures print output and renders it in a code block.

tests.sphinx.test_sphinx_python.test_python_source_seeds_namespace_for_python_run(sphinx_app_myst)[source]ΒΆ

python:source runs silently; a follow-up python:run reuses its imports.

tests.sphinx.test_sphinx_python.test_python_run_language_override(sphinx_app_myst)[source]ΒΆ

:language: overrides the default text lexer for the result block.

tests.sphinx.test_sphinx_python.test_python_run_screenshot_writes_the_asset(sphinx_app_myst)[source]ΒΆ

:screenshot: on python:run writes the capture, as on click:run.

The :mirror: refresher links the asset below whichever directive names it, so the block has to write it or the page links an image that is not there.

tests.sphinx.test_sphinx_python.test_python_run_emphasize_lines_split(sphinx_app_myst)[source]ΒΆ

:emphasize-lines: highlights source only; :emphasize-result-lines: highlights result only: independently, on the same block.

tests.sphinx.test_sphinx_python.test_python_render_passes_block_level_html(sphinx_app_myst)[source]ΒΆ

python:render passes block-level raw HTML through unchanged.

A naked print('<div>...</div>') should reach the rendered page without any {raw} html wrapping. Locks down the natural-form pattern so a future MyST upgrade or extension reordering can’t silently regress it.

tests.sphinx.test_sphinx_python.test_python_render_host_myst_injects_table(sphinx_app_myst)[source]ΒΆ

python:render parses captured stdout with the host (MyST) parser.

tests.sphinx.test_sphinx_python.test_python_render_host_myst_injects_heading(sphinx_app_myst)[source]ΒΆ

A heading printed by python:render becomes a real heading node.

tests.sphinx.test_sphinx_python.test_python_render_host_rst_injects_admonition(sphinx_app_rst)[source]ΒΆ

python:render in an rST host: stdout is parsed as reST.

tests.sphinx.test_sphinx_python.test_python_render_myst_in_rst_host(sphinx_app_rst)[source]ΒΆ

python:render-myst forces MyST parsing inside an rST host document.

This is the headline use case: an rST file embeds Python that prints MyST markup and the directive parses it as MyST regardless of host.

tests.sphinx.test_sphinx_python.test_python_render_rst_in_myst_host(sphinx_app_myst)[source]ΒΆ

python:render-rst forces reST parsing inside a MyST host document.

tests.sphinx.test_sphinx_python.test_python_render_myst_in_myst_host_still_works(sphinx_app_myst)[source]ΒΆ

python:render-myst works in MyST hosts too; it always picks MyST.

tests.sphinx.test_sphinx_python.test_python_render_rst_in_rst_host_still_works(sphinx_app_rst)[source]ΒΆ

python:render-rst works in rST hosts too; it always picks reST.

tests.sphinx.test_sphinx_python.test_exec_directives_disabled_by_default(tmp_path)[source]ΒΆ

Without the opt-in flag, click:* and python:* are not registered.

The Sphinx build still succeeds but neither family’s directive body is ever executed. This is the desired security default: a project that adds click_extra.sphinx to its extensions list does not silently gain build-time arbitrary Python execution.

The exact rendering of an unrecognized directive is parser-dependent (MyST silently swallows it; reST emits a system message), so the assertion focuses on the security-relevant invariant: the directive body’s print output never reaches the rendered HTML.

tests.sphinx.test_sphinx_python.test_exec_directives_enabled_with_opt_in(tmp_path)[source]ΒΆ

Setting click_extra_enable_exec_directives = True activates them.

tests.sphinx.test_sphinx_python.test_python_runner_isolated_from_click_runner(sphinx_app_myst)[source]ΒΆ

The Python and Click runners hold independent namespaces.

tests.sphinx.test_sphinx_python.test_mirror_src_rewrite_inserts_region()[source]ΒΆ

A mirror-src comment with no region yet gets one, generator kept hidden.

tests.sphinx.test_sphinx_python.test_mirror_src_rewrite_is_idempotent()[source]ΒΆ

Re-running over an already-filled mirror-src region is a no-op.

tests.sphinx.test_sphinx_python.test_mirror_src_first_sight_stops_at_the_next_generator()[source]ΒΆ

A new generator above a refreshed one gets its own region.

The terminator below the second generator closes that generator’s region: read as the end of the first one’s, it would replace the prose and the second generator between them.

tests.sphinx.test_sphinx_python.test_mirror_src_via_update_mirror_blocks(tmp_path)[source]ΒΆ

The offline refresher fills a mirror-src region, then round-trips clean.

tests.sphinx.test_sphinx_python.test_mirror_src_rewrite_skips_example_nested_in_code_block()[source]ΒΆ

A mirror-src comment shown inside a longer code-block fence is never run.

tests.sphinx.test_sphinx_python.test_rewrite_mirrors_refreshes_every_mirror_src_spelling(opening)[source]ΒΆ

A comment the region walk accepts is refreshed, whatever space follows <!--.

tests.sphinx.test_sphinx_python.test_mirror_rewrite_inserts_region()[source]ΒΆ

A mirror block with no region yet gets one inserted below the fence.

tests.sphinx.test_sphinx_python.test_mirror_rewrite_is_idempotent()[source]ΒΆ

Re-running over an already-mirrored document is a no-op.

tests.sphinx.test_sphinx_python.test_mirror_rewrite_replaces_stale_region()[source]ΒΆ

A stale region is refreshed from the block’s current output.

tests.sphinx.test_sphinx_python.test_mirror_rewrite_skips_example_nested_in_code_block()[source]ΒΆ

A mirror block shown inside a longer code-block fence is never executed.

tests.sphinx.test_sphinx_python.test_python_render_mirror_renders_fresh_without_touching_source(sphinx_app_myst)[source]ΒΆ

:mirror: renders the table once; the build never writes to the source.

tests.sphinx.test_sphinx_python.test_update_mirror_blocks_populates_and_idempotent(tmp_path)[source]ΒΆ

The offline refresher inserts the region, then round-trips clean.

tests.sphinx.test_sphinx_python.test_update_mirror_blocks_check_mode(tmp_path)[source]ΒΆ

check=True reports the stale file without writing it.

tests.sphinx.test_sphinx_python.test_update_mirror_blocks_imports_sibling_module(tmp_path)[source]ΒΆ

A mirror block imports a helper module living next to the page.

Matches the Sphinx build, where the conf.py directory is importable, so a docs_update.py-style generator module works offline too. The path entry is scoped to the execution and removed afterwards.

tests.sphinx.test_sphinx_python.test_refresh_directives_cli_refreshes_mirror_blocks(tmp_path)[source]ΒΆ

click-extra refresh-directives covers mirror regions too.

tests.sphinx.test_sphinx_python.test_refresh_directives_cli_reads_and_writes_a_page_once(tmp_path, monkeypatch)[source]ΒΆ

Every kind of block of a page is refreshed in one read and one write.

The matrix, mirror and screenshot refreshers share one pass over the page.

tests.sphinx.test_sphinx_python.test_python_render_mirror_show_source_still_single_table(sphinx_app_myst)[source]ΒΆ

:mirror: :show-source: shows the Python but still renders one table.

tests.sphinx.test_sphinx_tables moduleΒΆ

Tests for the styling of corner-labeled tables.

tests.sphinx.test_sphinx_tables.test_corner_tables_keep_their_first_column_whole(sphinx_app_myst)[source]ΒΆ

Only a table whose first header cell holds the corner label is marked.

The glyph in any other header cell marks nothing, and every page links the stylesheet the mark hooks into.

Return type:

None

tests.sphinx.test_sphinx_tables.test_matrix_cells_are_tinted_by_state(sphinx_app_myst)[source]ΒΆ

A state glyph alone in a body cell of a corner table marks that cell.

A glyph next to other text marks nothing, and nor does a glyph in a table without a corner label.

Return type:

None

tests.sphinx.test_sphinx_tables.test_every_state_has_a_tint(glyph)[source]ΒΆ

Each cell state of a matrix maps to a class the stylesheet tints.

Return type:

None

tests.sphinx.test_sphinx_tabs moduleΒΆ

Tests for the vertical layout of sphinx-design tab-sets.

tests.sphinx.test_sphinx_tabs.test_vertical_tabs_stylesheet_is_linked(sphinx_app_myst)[source]ΒΆ

Every page links the stylesheet, which the build writes.

Return type:

None

tests.sphinx.test_sphinx_tabs.test_vertical_tabs_rules_stay_on_their_tab_set()[source]ΒΆ

Every rule targets a tab-set marked with the class, or a direct child of it.

Other tab-sets keep their layout, and so does a tab-set nested inside a pane of a vertical one.

Return type:

None

tests.sphinx.test_sphinx_tabs.test_vertical_tabs_class_is_deprecated(sphinx_app_myst, classes, warns)[source]ΒΆ

A tab-set marked with the class warns about its removal, other nodes do not.

A docutils container takes the classes that sphinx-design gives the node of a tab-set, so the test needs no sphinx-design.

Return type:

None

tests.sphinx.test_sphinx_todos moduleΒΆ

Tests for the todolist deduplication hook and the unrendered-todo check.

tests.sphinx.test_sphinx_todos.TODO_SOURCE_RE = re.compile('<p class="todo-source">\\(The <a class="reference internal" href="([^"]+)">.*?located in (.*?), line (\\d+)\\.\\)</p>', re.DOTALL)ΒΆ

Captures the page, the origin and the line of every rendered todo entry.

sphinx.ext.todo emits one such paragraph per entry it puts on a todolist, so counting them counts the entries.

tests.sphinx.test_sphinx_todos.COMPOST_MODULE = '"""Turn fallen fruit into compost.\n\n.. todo::\n   Turn the heap once a week.\n"""\n'ΒΆ

A module docstring with a todo on its third line.

tests.sphinx.test_sphinx_todos.GRAFTING_MODULE = '"""Fruit grafting."""\n\n\ndef _graft(branch):\n    """Join ``branch`` to a rootstock.\n\n    .. todo::\n       Seal the cut with wax.\n    """\n    return branch\n'ΒΆ

A module whose only todo sits in a private function, which :members: skips.

tests.sphinx.test_sphinx_todos.VARIETIES_MODULE = '"""Fruit varieties."""\n\n\nclass Fruit:\n    """A fruit."""\n\n\nAPPLE = Fruit()\n"""A crisp apple.\n\n.. todo::\n   Pick the reddest one first.\n"""\n\nAPPLE.__doc__ = """A crisp apple.\n\n.. todo::\n   Pick the reddest one first.\n"""\n'ΒΆ

A module whose attribute docstring the instance carries too.

A registry of documented instances copies it this way, so that autodoc finds the docstring under a path that re-exports the attribute, where no source carries it. autodoc labels each rendering with the path it documented.

tests.sphinx.test_sphinx_todos.VARIETIES_INIT = '"""An orchard."""\n\nfrom .varieties import APPLE\n\n__all__ = ["APPLE"]\n'ΒΆ

A package re-exporting the attribute of VARIETIES_MODULE.

tests.sphinx.test_sphinx_todos.BOWLS_MODULE = '"""Fruit bowls."""\n\n\nclass Fruit:\n    """A fruit."""\n\n\nBOWL = Fruit()\n\nPEAR = BOWL\n"""A pear.\n\n.. todo::\n   Wait for autumn.\n"""\n\nQUINCE = BOWL\n"""A quince.\n\n.. todo::\n   Cook it first.\n"""\n'ΒΆ

Two attributes bound to one object, each with a todo of its own on one line.

tests.sphinx.test_sphinx_todos.UNRENDERED_RE = re.compile('(\\S+):(\\d+): WARNING: click_extra\\.sphinx: no page renders the docstring of (\\S+), so no todolist can list this todo\\.')ΒΆ

Captures the file, the line and the owner of every unrendered-todo warning.

tests.sphinx.test_sphinx_todos.build_project(tmp_path, package, pages, *, files=None, conf=(), dedupe=None, todo_extension=True)[source]ΒΆ

Build a throwaway project documenting package, and return the build.

pages maps a docname to its reStructuredText body. A todos page carrying the todolist is always appended, and every page is wired into the root toctree.

package names the generated package, and must differ between tests: the modules are imported by autodoc into the running interpreter, where sys.modules would otherwise serve the first test’s copy to every later one.

files maps a path inside the package to its source, written over the orchard’s own __init__.py and harvest.py. conf appends lines to the generated conf.py.

Returns the output directory, the warning stream and the exit status.

tests.sphinx.test_sphinx_todos.build_orchard(tmp_path, package, pages, **options)[source]ΒΆ

Build a project with build_project, and return its todo entries.

Returns the (page, origin, line) triples the todolist page rendered, in document order.

tests.sphinx.test_sphinx_todos.unrendered_todos(warnings)[source]ΒΆ

Return the (file name, line, owner) of each unrendered-todo warning.

tests.sphinx.test_sphinx_todos.automodule(target, no_index=False)[source]ΒΆ

Render an automodule block for target.

tests.sphinx.test_sphinx_todos.fake_node(source, line=1)[source]ΒΆ

A todo node reduced to the two attributes the identity helpers read.

tests.sphinx.test_sphinx_todos.test_todo_identity_ignores_the_import_path_of_a_docstring()[source]ΒΆ

Two renderings of one docstring share an identity whatever reached it.

tests.sphinx.test_sphinx_todos.test_todo_identity_reads_the_source_form_without_a_file()[source]ΒΆ

A source autodoc wrote without a file yields its label like one with a file.

tests.sphinx.test_sphinx_todos.test_is_reexport(source, expected)[source]ΒΆ

Only a docstring reached through a package __init__ ranks as re-exported.

tests.sphinx.test_sphinx_todos.test_full_api_page_and_feature_page_yield_one_entry_each(tmp_path)[source]ΒΆ

A module documented twice across pages lists each todo once.

tests.sphinx.test_sphinx_todos.test_reexported_members_yield_one_entry_each(tmp_path)[source]ΒΆ

A member documented under both its package and its module lists once.

tests.sphinx.test_sphinx_todos.test_surviving_entry_attributes_to_the_defining_module(tmp_path)[source]ΒΆ

The kept rendering names the module defining the object, not the package.

tests.sphinx.test_sphinx_todos.test_reexported_attribute_yields_one_entry(tmp_path)[source]ΒΆ

An attribute documented under its package and its module lists once.

The two renderings of its docstring carry different labels, the paths autodoc documented: only the object behind both labels matches them.

tests.sphinx.test_sphinx_todos.test_attributes_sharing_an_object_keep_an_entry_each(tmp_path)[source]ΒΆ

Two docstrings of one object keep their entries, though the object matches.

tests.sphinx.test_sphinx_todos.test_dedupe_switched_off_restores_every_rendering(tmp_path)[source]ΒΆ

click_extra_dedupe_todos = False gives Sphinx’s raw output back.

tests.sphinx.test_sphinx_todos.test_distinct_todos_all_survive(tmp_path)[source]ΒΆ

Deduplication collapses repeats, never two different directives.

tests.sphinx.test_sphinx_todos.test_build_succeeds_without_the_todo_extension(tmp_path)[source]ΒΆ

The hook is inert on a project that never registered the todo domain.

tests.sphinx.test_sphinx_todos.test_docstring_todos(source, expected)[source]ΒΆ

Each todo is found at its line, under the path autodoc labels it with.

tests.sphinx.test_sphinx_todos.test_docstring_todos_rejects_invalid_source()[source]ΒΆ

A module that does not parse raises, for the caller to skip it.

tests.sphinx.test_sphinx_todos.test_package_modules_walks_without_importing(tmp_path, monkeypatch)[source]ΒΆ

Every module of a package is found, private ones included, none imported.

tests.sphinx.test_sphinx_todos.test_unrendered_todos_warn_at_their_line(tmp_path)[source]ΒΆ

A todo in a docstring no page renders is reported at its own line.

tests.sphinx.test_sphinx_todos.test_rendered_todos_do_not_warn(tmp_path)[source]ΒΆ

No todo a page renders is reported, a re-exported one included.

tests.sphinx.test_sphinx_todos.test_todo_rendered_under_another_path_does_not_warn(tmp_path)[source]ΒΆ

A docstring autodoc labels with another path still counts as rendered.

With its __module__ overridden, pick is labeled with the path of the package, not with the path of the module that defines it.

tests.sphinx.test_sphinx_todos.test_unrendered_todo_check_stays_silent(tmp_path, package, options)[source]ΒΆ

The check is inert when no todo renders, and suppress_warnings hides it.

tests.sphinx.test_sphinx_todos.test_listed_unrendered_todo_fails_the_build(tmp_path)[source]ΒΆ

Listing the warning in click_extra_fail_on_warnings fails the build.

tests.sphinx.test_sphinx_viewcode moduleΒΆ

Tests for the sphinx.ext.viewcode pages a build publishes.

tests.sphinx.test_sphinx_viewcode.FRUITS_MODULE = 'import re\n\nSEED = re.compile(r"\\d+")\n"""Pattern of a seed count."""\n\n\ndef ripen(fruit):\n    """Ripen a fruit."""\n'ΒΆ

A module documenting a constant whose value is an instance of re.Pattern.

viewcode looks for SEED in the module of that class, re, and finds nothing to link to there.

tests.sphinx.test_sphinx_viewcode.PUBLISHED_PAGES = ['_modules/fruits.html', '_modules/index.html']ΒΆ

The module page of fruits, and the index linking to it.

tests.sphinx.test_sphinx_viewcode.write_project(srcdir)[source]ΒΆ

Write a project whose last document read documents fruits.

No later document purges the unused re entry, so a serial read keeps it too.

Return type:

None

tests.sphinx.test_sphinx_viewcode.module_pages(outdir)[source]ΒΆ

List the viewcode pages of a build, relative to its output directory.

Return type:

list[str]

tests.sphinx.test_sphinx_viewcode.test_serial_read_publishes_linked_modules_only(tmp_path, monkeypatch)[source]ΒΆ

A serial read publishes no page for the module it read for nothing.

tests.sphinx.test_sphinx_viewcode.test_parallel_read_publishes_the_pages_of_a_serial_one(tmp_path)[source]ΒΆ

A parallel read publishes the same pages as a serial one.

Its workers merge their entries after every purge has run, which is the case of sphinx-doc/sphinx#14675. The build runs in a process of its own: forking the test process, which runs other threads, can deadlock the workers.