Skip to content

fix(python): escape quotes in enum documentation - #11897

Merged
Libba Lawrence (l0lawrence) merged 5 commits into
microsoft:mainfrom
rksharma-owg:codex/escape-python-docstring-quotes
Sep 29, 2026
Merged

Libba Lawrence (l0lawrence) merged 5 commits into
microsoft:mainfrom
rksharma-owg:codex/escape-python-docstring-quotes

Conversation

@rksharma-owg

@rksharma-owg RKS (rksharma-owg) commented Sep 9, 2026 •

Copy link
Copy Markdown
Contributor

Enum and enum member documentation containing triple quotes can terminate its generated Python docstring. For syntactically valid input, the formatter accepts the following documentation as class-body statements; trailing single quotes can also make member docstrings invalid Python.

Add a reusable docstring-wrapping macro that escapes quotes after the existing prose wrapping and backslash escaping, and use it for enum classes, members, and Literal[...] enum descriptions in TypedDict output. This preserves ordinary documentation.

Fixes #11881. Related to #10784; this change specifically covers quotes at the enum rendering boundary.

Validation:

  • 18 template regression cases pass. Nine original cases failed against the base templates; five added Literal-enum cases fail against the previous PR head. Cases cover ordinary prose, embedded delimiters, statement-shaped documentation, trailing quotes, backslashes, and multiple paragraphs. The tests inspect the formatted Python AST and documentation contents, rather than relying only on formatting success.
  • Package build and wheel creation pass.
  • All 23 emitter tests pass.
  • Python generator Pylint, TypeScript Oxlint, test formatting, changeset formatting, and git diff --check pass. Linters were invoked directly to work around local optional-dependency and path-with-spaces problems in the wrapper.
  • Full SDK regeneration passes for both flavors: 124 Azure specs / 133 generation tasks and 65 unbranded specs / 73 generation tasks. Regeneration leaves the working tree clean.
  • Earlier broader unit run (not repeated for this review update): 528 passed, 3 failed. Running the same suite against the base generator gives 516 passed and the same 3 failures (the difference is the 12 added tests). Existing failures are test_polymorphic_deserialization, test_enumeration_results_blobs_unwrapped, and test_models_mode_typeddict_does_not_write_empty_models_folder. The local test run uses --confcutdir=tests/unit to avoid starting the unrelated mock API server.
  • The full generated-SDK CI matrix was not run locally; upstream CI status is tracked on the PR.

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
Successfully started running 1 pipeline(s).
1 pipeline(s) were filtered out due to trigger conditions.
There may be pipelines that require an authorized user to comment /azp run to run.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

Enum descriptions rendered as Literal[...] in types.py.jinja2 still use unescaped wrap_string inside """...""", leaving the same triple-quote breakout risk in typeddict mode.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Pull request overview

Fixes a Python emitter correctness issue where enum/enum-member documentation containing """ can prematurely terminate generated docstrings, causing subsequent text to be treated as executable Python at import time.

Changes:

  • Add a reusable wrap_docstring Jinja macro that escapes double quotes after existing wrapping/backslash escaping.
  • Use wrap_docstring for enum class and enum member docstrings in enum.py.jinja2.
  • Add regression tests that parse the formatted Python AST to ensure documentation stays within a string literal, plus a .chronus fix entry.
File summaries
File Description
packages/http-client-python/tests/unit/test_enum_docstrings.py Adds AST-based regressions ensuring enum docs remain string literals even with embedded """, backslashes, and trailing quotes.
packages/http-client-python/generator/pygen/codegen/templates/operation_tools.jinja2 Introduces wrap_docstring macro to escape quotes after wrapping.
packages/http-client-python/generator/pygen/codegen/templates/enum.py.jinja2 Switches enum and enum member docstring emission to the new wrap_docstring helper.
.chronus/changes/escape-python-enum-docstrings.md Records a fix changeset for @typespec/http-client-python.
Review details
  • Files reviewed: 4/4 changed files
  • Comments generated: 1
  • Review effort level: Lite

💡 Configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Cover Literal enum rendering with the same AST and documentation-preservation checks as class and member docstrings.

Assisted-by: OpenAI Codex (model: GPT-6 Astra, autonomous)
Copilot AI review requested due to automatic review settings September 9, 2026 19:17
@rksharma-owg

Copy link
Copy Markdown
Contributor Author

Posted on behalf of RKS (@rksharma-owg) by OpenAI Codex.

Addressed the TypedDict/Literal enum path in b89dbca: types.py.jinja2 now uses wrap_docstring for literal enum descriptions. The AST regression suite covers all three enum documentation sites; 18 cases pass, and five of the added Literal cases failed on the previous PR head.

Package build/wheel creation, all 23 emitter tests, targeted Pylint/Black checks, and full Azure/unbranded SDK regeneration passed. Regeneration produced no generated-file changes. The focused Python tests use --confcutdir=tests/unit to avoid the unrelated mock-server startup fixture. The full generated-SDK CI matrix was not run locally.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟢 Approval recommended

The change is narrowly scoped to enum docstring rendering, includes a reusable helper, adds targeted regression tests that would fail on reversion, and includes an appropriate .chronus fix entry.

Review details
  • Files reviewed: 5/5 changed files
  • Comments generated: 0 new
  • Review effort level: Lite

@microsoft-github-policy-service microsoft-github-policy-service Bot added the stale Mark a PR that hasn't been recently updated and will be closed. label Sep 26, 2026
@microsoft-github-policy-service

Copy link
Copy Markdown
Contributor

Hi @RKS (@rksharma-owg). Your PR has had no update for 14 days and it is marked as a stale PR. If it is not updated within 14 additional days, the PR will automatically be closed. If you want to refresh the PR, please remove the stale label.

@rksharma-owg

Copy link
Copy Markdown
Contributor Author

The PR remains active, and the reported checks pass on the current head (b89dbca). I tried to remove the stale label as the bot suggests, but GitHub denied that action for my contributor account. Could a maintainer remove the label when convenient? I can address any review feedback.

@pkg-pr-new

pkg-pr-new Bot commented Sep 28, 2026 •

Copy link
Copy Markdown

Open in StackBlitz

npm i https://pkg.pr.new/@typespec/http-client-python@11897

commit: 1996bc9

@github-actions

Copy link
Copy Markdown
Contributor

All changed packages have been documented.

  • ✅ @typespec/http-client-python
Show changes

@typespec/http-client-python - fix ✏️

Escape quotes in enum and enum member documentation so embedded Python string delimiters remain documentation in generated code.

@l0lawrence

Copy link
Copy Markdown
Member

RKS (@rksharma-owg) thanks for the pr, can you merge the most recent main into your pr to unblock the CI run

Copilot AI review requested due to automatic review settings September 29, 2026 03:55
@rksharma-owg

Copy link
Copy Markdown
Contributor Author

Merged current main (a902c450) into this PR at 9548918e. Thanks for pointing out the stale branch.

Fork preflight on that exact commit passed on Linux and Windows, including regeneration, generated tests, emitter tests, type checks, lint, and formatting. The new upstream workflows for 9548918e currently show action_required with zero jobs, so they are still awaiting maintainer approval to run.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

🟡 Changes recommended

Regression tests bypass the shipped serializer paths and should validate the actual integration.

Review effort: Lite
Findings: 1 High severity · 1 Medium severity

Open (2)

Comment thread packages/http-client-python/tests/unit/test_enum_docstrings.py
Copilot AI review requested due to automatic review settings September 29, 2026 05:11

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

🟢 Approval recommended

All reviewed changes have no unresolved blocking issues.

Review effort: Lite
Findings: 1 High severity

Open (1)
Resolved since last review (1)

@github-actions

Copy link
Copy Markdown
Contributor

Python emitter diff

Baseline gh:a902c450ae5d68d15d6dc1da2e46c8fc28d724f0 vs this PR.

Diff summary: 2 file(s), +4 / -4

Rendered diff: inline on the run summary, or the emitter-diff-html artifact.

Informational check (eng/emitter-diff); does not block the PR.

@l0lawrence
Libba Lawrence (l0lawrence) added this pull request to the merge queue Sep 29, 2026
Merged via the queue into microsoft:main with commit 1b3f984 Sep 29, 2026
32 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

emitter:client:python Issue for the Python client emitter: @typespec/http-client-python stale Mark a PR that hasn't been recently updated and will be closed.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: Python emitter does not escape triple quotes in enum member documentation

3 participants