From dc1a0bb1751bcc5f2a7c4666fd8e54e1d2cdbb59 Mon Sep 17 00:00:00 2001 From: Libba Lawrence Date: Tue, 9 Jun 2026 15:33:46 -0700 Subject: [PATCH] fix(http-client-python): insert annotations before code blocks in docstrings Required. and other annotations were appended after RST code blocks, breaking Sphinx rendering. They are now inserted into the prose before the code block. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- ...uired-after-code-block-2026-6-9-15-20-0.md | 7 ++++ .../generator/pygen/codegen/models/utils.py | 24 ++++++++++--- .../tests/unit/test_add_to_description.py | 35 +++++++++++++++++++ 3 files changed, 61 insertions(+), 5 deletions(-) create mode 100644 .chronus/changes/fix-sphinx-required-after-code-block-2026-6-9-15-20-0.md create mode 100644 packages/http-client-python/tests/unit/test_add_to_description.py diff --git a/.chronus/changes/fix-sphinx-required-after-code-block-2026-6-9-15-20-0.md b/.chronus/changes/fix-sphinx-required-after-code-block-2026-6-9-15-20-0.md new file mode 100644 index 00000000000..cf2ec9852d7 --- /dev/null +++ b/.chronus/changes/fix-sphinx-required-after-code-block-2026-6-9-15-20-0.md @@ -0,0 +1,7 @@ +--- +changeKind: fix +packages: + - "@typespec/http-client-python" +--- + +Fix Sphinx docstring rendering when a `Required.` (or other) annotation followed a code block. The annotation is now inserted into the prose before the code block instead of being appended after it. diff --git a/packages/http-client-python/generator/pygen/codegen/models/utils.py b/packages/http-client-python/generator/pygen/codegen/models/utils.py index 82e80b85577..46aa53f749c 100644 --- a/packages/http-client-python/generator/pygen/codegen/models/utils.py +++ b/packages/http-client-python/generator/pygen/codegen/models/utils.py @@ -11,10 +11,20 @@ OrderedSet = dict[T, None] +CODE_BLOCK_MARKER = ".. code-block::" + + def add_to_description(description: str, entry: str) -> str: - if description: - return f"{description} {entry}" - return entry + if not description: + return entry + # When the description contains a code block, the entry (e.g. "Required.") must be + # inserted into the prose *before* the code block. Appending it after the code block + # (e.g. "]. Required.") leaves it dangling at the end of the rendered block and breaks + # Sphinx rendering. + if CODE_BLOCK_MARKER in description: + prose, _, code_block = description.partition(CODE_BLOCK_MARKER) + return f"{prose.rstrip()} {entry}\n\n{CODE_BLOCK_MARKER}{code_block}" + return f"{description} {entry}" def add_to_pylint_disable(curr_str: str, entry: str) -> str: @@ -34,6 +44,10 @@ class NamespaceType(str, Enum): LOCALS_LENGTH_LIMIT = 25 -REQUEST_BUILDER_BODY_VARIABLES_LENGTH = 6 # how many body variables are present in a request builder +REQUEST_BUILDER_BODY_VARIABLES_LENGTH = ( + 6 # how many body variables are present in a request builder +) -OPERATION_BODY_VARIABLES_LENGTH = 14 # how many body variables are present in an operation +OPERATION_BODY_VARIABLES_LENGTH = ( + 14 # how many body variables are present in an operation +) diff --git a/packages/http-client-python/tests/unit/test_add_to_description.py b/packages/http-client-python/tests/unit/test_add_to_description.py new file mode 100644 index 00000000000..c6d1ed781d0 --- /dev/null +++ b/packages/http-client-python/tests/unit/test_add_to_description.py @@ -0,0 +1,35 @@ +# ------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for +# license information. +# -------------------------------------------------------------------------- +"""Tests for add_to_description code-block handling.""" +from pygen.codegen.models.utils import add_to_description + + +def test_add_to_description_empty() -> None: + assert add_to_description("", "Required.") == "Required." + + +def test_add_to_description_plain() -> None: + assert add_to_description("The tools.", "Required.") == "The tools. Required." + + +def test_add_to_description_inserts_before_code_block() -> None: + description = "The tools to use.\n\n.. code-block:: json\n\n [\n 1\n ]" + result = add_to_description(description, "Required.") + assert result == ( + "The tools to use. Required.\n\n.. code-block:: json\n\n [\n 1\n ]" + ) + # The annotation must not be appended after the closing of the code block. + assert not result.rstrip().endswith("Required.") + + +def test_add_to_description_multiple_code_blocks_inserts_before_first() -> None: + description = ( + "Prose.\n\n.. code-block:: json\n\n [1]\n\n.. code-block:: json\n\n [2]" + ) + result = add_to_description(description, "Required.") + assert result == ( + "Prose. Required.\n\n.. code-block:: json\n\n [1]\n\n.. code-block:: json\n\n [2]" + )