diff --git a/.chronus/changes/copilot-fix-python-emitter-xml-bug-2026-9-21-8-26-3.md b/.chronus/changes/copilot-fix-python-emitter-xml-bug-2026-9-21-8-26-3.md deleted file mode 100644 index 831b89593c3..00000000000 --- a/.chronus/changes/copilot-fix-python-emitter-xml-bug-2026-9-21-8-26-3.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -changeKind: fix -packages: - - "@typespec/http-client-python" ---- - -Preserve raw byte streaming for XML responses using the legacy bytes encoding instead of deserializing them as XML string scalars. diff --git a/.chronus/changes/http-client-python-sse-pylint-2026-10-14.md b/.chronus/changes/http-client-python-sse-pylint-2026-10-14.md deleted file mode 100644 index 5b6470c1957..00000000000 --- a/.chronus/changes/http-client-python-sse-pylint-2026-10-14.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -changeKind: fix -packages: - - "@typespec/http-client-python" ---- - -Prevent Pylint `too-many-statements` errors in generated synchronous and asynchronous structured-stream operations with SSE event dispatch. Scope the suppression to operation implementations, leaving overload declarations and non-structured-stream operations unchanged. diff --git a/.chronus/changes/python-3-15-support-2026-10-12.md b/.chronus/changes/python-3-15-support-2026-10-12.md deleted file mode 100644 index 8929234664c..00000000000 --- a/.chronus/changes/python-3-15-support-2026-10-12.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -changeKind: feature -packages: - - "@typespec/http-client-python" ---- - -Add Python 3.15 to generated package classifiers. diff --git a/.chronus/changes/python-discriminator-string-literals-2026-10-22.md b/.chronus/changes/python-discriminator-string-literals-2026-10-22.md deleted file mode 100644 index c0a0775d430..00000000000 --- a/.chronus/changes/python-discriminator-string-literals-2026-10-22.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -changeKind: fix -packages: - - "@typespec/http-client-python" ---- - -Escape string literals and wire names in generated Python declarations, discriminator initializers, field metadata, and templates to preserve specification values as data. diff --git a/.chronus/changes/python-discriminator-vartype-2026-10-7.md b/.chronus/changes/python-discriminator-vartype-2026-10-7.md deleted file mode 100644 index c5926d3851d..00000000000 --- a/.chronus/changes/python-discriminator-vartype-2026-10-7.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -changeKind: fix -packages: - - "@typespec/http-client-python" ---- - -Fix the `:vartype` docstring of constant enum values (such as discriminator properties on polymorphic subclasses) to reference the enum class instead of a non-existent module-level symbol named after the enum member. diff --git a/.chronus/changes/python-fixCasingEnum-2026-3-9-16-6-39.md b/.chronus/changes/python-fixCasingEnum-2026-3-9-16-6-39.md deleted file mode 100644 index c0979d3298d..00000000000 --- a/.chronus/changes/python-fixCasingEnum-2026-3-9-16-6-39.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -changeKind: fix -packages: - - "@typespec/http-client-python" ---- - -Preserve underscores before numeric enum segments and acronyms such as `A2A` without changing numeric identifiers such as `int32`. diff --git a/.github/skills/http-client-python-bump-and-release/SKILL.md b/.github/skills/http-client-python-bump-and-release/SKILL.md index 1026d0c6bb5..6b7bbed0269 100644 --- a/.github/skills/http-client-python-bump-and-release/SKILL.md +++ b/.github/skills/http-client-python-bump-and-release/SKILL.md @@ -14,7 +14,7 @@ Create a PR to bump dependencies and release a new version of the http-client-py Before starting, verify that `npm-check-updates` is available: ```bash -npx npm-check-updates --version +npx --no-install npm-check-updates --version ``` If the command fails or prompts for installation, install it globally: @@ -23,6 +23,10 @@ If the command fails or prompts for installation, install it globally: npm install -g npm-check-updates ``` +The version script also requires pnpm and the repository's workspace dependencies, even though the emitter uses npm. Verify that `pnpm --version` and `pnpm exec chronus --version` work from `{REPO}`. If pnpm is missing, install the version declared in the root `package.json`'s `packageManager` field. If Chronus is missing, run `pnpm install --frozen-lockfile` from `{REPO}` before continuing. + +Use the CFS feed `https://pkgs.dev.azure.com/azure-sdk/public/_packaging/azure-sdk-for-js/npm/registry/` for dependency queries and installation. From the package directory, verify that `npm config get registry` reports this feed; it is configured in the package's `.npmrc`. Do not silently fall back to npmjs.org if the feed is unavailable. + ## Workflow 1. Navigate to the package directory: @@ -31,25 +35,29 @@ npm install -g npm-check-updates cd {REPO}/packages/http-client-python ``` -2. Reset and sync with main: +2. Inspect the worktree and fetch main without discarding local changes: ```bash - git reset HEAD && git checkout . && git checkout origin/main && git pull origin main + git status --short + git fetch origin main ``` + Preserve unrelated local work. Do not run `git reset` or `git checkout .` as release preparation. + 3. Create release branch (use current date in MM-DD format): ```bash - git checkout -b publish/python-release-{MM-DD} + git switch -c publish/python-release-{MM-DD} origin/main ``` 4. Update dependencies: ```bash - npx npm-check-updates -u --filter @typespec/*,@azure-tools/* --packageFile package.json + npx npm-check-updates -u --filter '@typespec/*,@azure-tools/*' --packageFile package.json --registry https://pkgs.dev.azure.com/azure-sdk/public/_packaging/azure-sdk-for-js/npm/registry/ ``` 5. Update `peerDependencies` in package.json: + - Do not assume step 4 updated peer dependencies: in the release run it updated development dependencies but left peer lower bounds unchanged. Use the latest versions reported in step 4 for the corresponding peers. - If format is `">=0.a.b <1.0.0"`: Update only the `0.a.b` portion, keep the range format unchanged - If format is `"^1.a.b"`: Update to the latest version @@ -82,14 +90,22 @@ npm install -g npm-check-updates - Bump dependencies of `@typespec/*` and `@azure-tools/*` to latest versions ``` - - Verify that the version in `package.json` matches the new `CHANGELOG.md` heading. + Verify that the version in `package.json` matches the new `CHANGELOG.md` heading. Consumed Python change files under `.chronus/changes/` are expected deletions; include them in the release commit. -8. Build and commit: +8. Install, build, validate, and commit: ```bash - npm install && npm run build && git add -u && git commit -m "bump version" + npm install --registry=https://pkgs.dev.azure.com/azure-sdk/public/_packaging/azure-sdk-for-js/npm/registry/ && npm run build + npm run lint + npm run test:emitter ``` + Run formatting from `{REPO}` using the `pnpm-format` skill. If `packages/prettier-plugin-typespec/dist/index.js` is missing, build the formatter first with `pnpm -r --filter '@typespec/prettier-plugin-typespec...' build`, then run `pnpm format`. Do not repeat dependency installation or build the entire monorepo for this missing-plugin error. + + Verify that `package-lock.json` and its root package entry match the manifest version, peer dependencies, and development dependencies. Review `git diff --check` and the changed-file list; stage only the release manifest, lockfile, changelog, and consumed Python change files. Commit using a conventional message such as `chore(python): bump version to ` and the required co-author trailer. + + Check the lockfile diff for registry changes: preserve existing CFS URLs and resolve new or updated packages through CFS, without migrating unrelated pre-existing npmjs.org entries. Changing the registry and rerunning `npm install --package-lock-only` did not repair existing npmjs.org URLs in the release run. If correcting such a lockfile, obtain the exact CFS tarball URLs from feed metadata and verify their contents against the lockfile integrity hashes before replacing URLs; do not blindly rewrite hosts or change package versions. + 9. Push and create PR: ```bash @@ -99,6 +115,8 @@ npm install -g npm-check-updates 10. Create PR with title `[python] release new version` and no description. + Verify the created PR's title, description, base/head branches, and draft state rather than relying on the creation tool's output. The release run's PR tool inserted a placeholder despite receiving an empty body; if this happens, clear it with `gh api --method PATCH repos/microsoft/typespec/pulls/ -f body=''` and verify again. If the tool creates a draft, mark it ready with `gh pr ready ` unless the user requested a draft. + ## Post-Process Review 1. After the pull request is created, review the complete release run: commands executed, command output, manual interventions, validation results, changed files, commit, push, cleanup, and PR creation. @@ -110,4 +128,4 @@ npm install -g npm-check-updates 3. Do not change the skill based on preference, speculation, or an unobserved edge case. For every update, record the observed evidence and explain why the edit improves future releases. 4. Keep any skill update minimal, validate its formatting and frontmatter, and keep it separate from the completed release PR unless the user explicitly asks to include it there. 5. If the review finds no evidence-backed improvement, leave the skill unchanged and state that no update was warranted. -6. Return the branch name, released package version, `@typespec/http-client-python` version, commit hash, pull request URL, review findings, and any skill update to the user. +6. Return the branch name, prepared `@typespec/http-client-python` version, commit hash, pull request URL, review findings, and any skill update to the user. Creating a release PR does not mean the package has been published. diff --git a/packages/http-client-python/CHANGELOG.md b/packages/http-client-python/CHANGELOG.md index 0e31d6dd18b..b250e190e62 100644 --- a/packages/http-client-python/CHANGELOG.md +++ b/packages/http-client-python/CHANGELOG.md @@ -1,5 +1,20 @@ # Change Log - @typespec/http-client-python +## 0.40.0 + +### Features + +- [#12161](https://github.com/microsoft/typespec/pull/12161) Add Python 3.15 to generated package classifiers. + +### Bug Fixes + +- [#12326](https://github.com/microsoft/typespec/pull/12326) Preserve raw byte streaming for XML responses using the legacy bytes encoding instead of deserializing them as XML string scalars. +- [#12281](https://github.com/microsoft/typespec/pull/12281) Prevent Pylint `too-many-statements` errors in generated synchronous and asynchronous structured-stream operations with SSE event dispatch. Scope the suppression to operation implementations, leaving overload declarations and non-structured-stream operations unchanged. +- [#12342](https://github.com/microsoft/typespec/pull/12342) Escape string literals and wire names in generated Python declarations, discriminator initializers, field metadata, and templates to preserve specification values as data. +- [#12127](https://github.com/microsoft/typespec/pull/12127) Fix the `:vartype` docstring of constant enum values (such as discriminator properties on polymorphic subclasses) to reference the enum class instead of a non-existent module-level symbol named after the enum member. +- [#10329](https://github.com/microsoft/typespec/pull/10329) Preserve underscores before numeric enum segments and acronyms such as `A2A` without changing numeric identifiers such as `int32`. + + ## 0.39.0 ### Features diff --git a/packages/http-client-python/package-lock.json b/packages/http-client-python/package-lock.json index 52142076ede..db7100e7823 100644 --- a/packages/http-client-python/package-lock.json +++ b/packages/http-client-python/package-lock.json @@ -1,12 +1,12 @@ { "name": "@typespec/http-client-python", - "version": "0.39.0", + "version": "0.40.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@typespec/http-client-python", - "version": "0.39.0", + "version": "0.40.0", "hasInstallScript": true, "license": "MIT", "dependencies": { @@ -18,11 +18,11 @@ }, "devDependencies": { "@azure-tools/azure-http-specs": "0.1.0-alpha.46", - "@azure-tools/typespec-autorest": "~0.73.0", + "@azure-tools/typespec-autorest": "~0.73.2", "@azure-tools/typespec-azure-core": "~0.73.0", "@azure-tools/typespec-azure-resource-manager": "~0.73.0", "@azure-tools/typespec-azure-rulesets": "~0.73.0", - "@azure-tools/typespec-client-generator-core": "~0.73.0", + "@azure-tools/typespec-client-generator-core": "~0.73.1", "@types/js-yaml": "~4.0.5", "@types/node": "~25.0.2", "@types/semver": "7.5.8", @@ -50,11 +50,11 @@ "node": ">=22.0.0" }, "peerDependencies": { - "@azure-tools/typespec-autorest": ">=0.73.0 <1.0.0", + "@azure-tools/typespec-autorest": ">=0.73.2 <1.0.0", "@azure-tools/typespec-azure-core": ">=0.73.0 <1.0.0", "@azure-tools/typespec-azure-resource-manager": ">=0.73.0 <1.0.0", "@azure-tools/typespec-azure-rulesets": ">=0.73.0 <1.0.0", - "@azure-tools/typespec-client-generator-core": ">=0.73.0 <1.0.0", + "@azure-tools/typespec-client-generator-core": ">=0.73.1 <1.0.0", "@typespec/compiler": "^1.17.0", "@typespec/events": ">=0.87.0 <1.0.0", "@typespec/http": "^1.17.0", @@ -89,13 +89,13 @@ } }, "node_modules/@azure-tools/typespec-autorest": { - "version": "0.73.0", - "resolved": "https://pkgs.dev.azure.com/azure-sdk/public/_packaging/azure-sdk-for-js/npm/registry/@azure-tools/typespec-autorest/-/typespec-autorest-0.73.0.tgz", - "integrity": "sha512-SvctS7ALld55xASlCNZ23KJJ2pfpSGIcnEhUzykS2p7QEMe9I2zCSNReQg/TklSVHsl303iO7LI6RoUqtQ/oOw==", + "version": "0.73.2", + "resolved": "https://pkgs.dev.azure.com/azure-sdk/public/_packaging/azure-sdk-for-js/npm/registry/@azure-tools/typespec-autorest/-/typespec-autorest-0.73.2.tgz", + "integrity": "sha512-Qm9m+4Ok2XxLvOm5l9dr6EmTN15ArGaktefSKZ5uNU2lt26RDntj2GP2tkudXjDijwqYGKnGsIU8l5wK9yMOvQ==", "dev": true, "license": "MIT", "dependencies": { - "@azure-tools/typespec-azure-examples": "^0.2.0", + "@azure-tools/typespec-azure-examples": "^0.2.2", "yaml": "^2.9.0" }, "engines": { @@ -134,13 +134,14 @@ } }, "node_modules/@azure-tools/typespec-azure-examples": { - "version": "0.2.0", - "resolved": "https://pkgs.dev.azure.com/azure-sdk/public/_packaging/azure-sdk-for-js/npm/registry/@azure-tools/typespec-azure-examples/-/typespec-azure-examples-0.2.0.tgz", - "integrity": "sha512-omv0wP/9+v3PEGy1lP/TD49hblBRc2PsCyaFekquwrIjCFP0ZNYyFD1tnxIWZkJBn2b+7zoc86I2t/aYj8LFpA==", + "version": "0.2.2", + "resolved": "https://pkgs.dev.azure.com/azure-sdk/public/_packaging/azure-sdk-for-js/npm/registry/@azure-tools/typespec-azure-examples/-/typespec-azure-examples-0.2.2.tgz", + "integrity": "sha512-7T6JLezY3uMbhCcyLU4rDQACt5eTjJLMMuKgq1ma1tYhoZmLX2yu5TcOUqfFkzkxypWI7JOdG7kgQHKhvPTduQ==", "dev": true, "license": "MIT", "dependencies": { "ajv": "^8.20.0", + "ajv-formats": "^3.0.1", "picocolors": "^1.1.1", "yaml": "^2.9.0", "yargs": "^18.1.0" @@ -152,12 +153,20 @@ }, "engines": { "node": ">=22.0.0" + }, + "peerDependencies": { + "@typespec/compiler": "^1.17.0" + }, + "peerDependenciesMeta": { + "@typespec/compiler": { + "optional": true + } } }, "node_modules/@azure-tools/typespec-azure-examples/node_modules/cliui": { "version": "9.0.1", "resolved": "https://pkgs.dev.azure.com/azure-sdk/public/_packaging/azure-sdk-for-js/npm/registry/cliui/-/cliui-9.0.1.tgz", - "integrity": "sha1-b3iQ84b28feZU63B943sRvzC0pE=", + "integrity": "sha512-k7ndgKhwoQveBL+/1tqGJYNz097I7WOvwbmmU2AR5+magtbjPWQTS1C5vzGkBC8Ym8UWRzfKUzUUqFLypY4Q+w==", "dev": true, "license": "ISC", "dependencies": { @@ -172,7 +181,7 @@ "node_modules/@azure-tools/typespec-azure-examples/node_modules/cliui/node_modules/string-width": { "version": "7.2.0", "resolved": "https://pkgs.dev.azure.com/azure-sdk/public/_packaging/azure-sdk-for-js/npm/registry/string-width/-/string-width-7.2.0.tgz", - "integrity": "sha1-tbuOIWXOJ11NQ0dt0nAK2Qkdttw=", + "integrity": "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==", "dev": true, "license": "MIT", "dependencies": { @@ -190,7 +199,7 @@ "node_modules/@azure-tools/typespec-azure-examples/node_modules/emoji-regex": { "version": "10.6.0", "resolved": "https://pkgs.dev.azure.com/azure-sdk/public/_packaging/azure-sdk-for-js/npm/registry/emoji-regex/-/emoji-regex-10.6.0.tgz", - "integrity": "sha1-vz1uj3+P0ipl2XA0dbwBRzV6aw0=", + "integrity": "sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A==", "dev": true, "license": "MIT" }, @@ -232,7 +241,7 @@ "node_modules/@azure-tools/typespec-azure-examples/node_modules/yargs-parser": { "version": "22.0.0", "resolved": "https://pkgs.dev.azure.com/azure-sdk/public/_packaging/azure-sdk-for-js/npm/registry/yargs-parser/-/yargs-parser-22.0.0.tgz", - "integrity": "sha1-h7gglAUbBWdxc0bs0A/RSASzV8g=", + "integrity": "sha512-rwu/ClNdSMpkSrUb+d6BRsSkLUq1fmfsY6TOpYzTwvwkg1/NRG85KBy3kq++A8LKQwX6lsu+aWad+2khvuXrqw==", "dev": true, "license": "ISC", "engines": { @@ -278,9 +287,9 @@ } }, "node_modules/@azure-tools/typespec-client-generator-core": { - "version": "0.73.0", - "resolved": "https://pkgs.dev.azure.com/azure-sdk/public/_packaging/azure-sdk-for-js/npm/registry/@azure-tools/typespec-client-generator-core/-/typespec-client-generator-core-0.73.0.tgz", - "integrity": "sha512-gvuoW1V/PyYgPIJTOZFrVWBwoEpZyJrrhm5XklE/Q7IembferuRoGtwYsnesG5kplDjSlSX9pYbn09NU+bdcVg==", + "version": "0.73.1", + "resolved": "https://pkgs.dev.azure.com/azure-sdk/public/_packaging/azure-sdk-for-js/npm/registry/@azure-tools/typespec-client-generator-core/-/typespec-client-generator-core-0.73.1.tgz", + "integrity": "sha512-3HybxFUoKcF5Y2C1zCSO7i2I6gbFe9SZmDbqSSA6oV2pdCDm6jikEQdRbBnyM70U6ZXY0TFPX5kcV266QDvnfQ==", "dev": true, "license": "MIT", "dependencies": { @@ -2644,6 +2653,24 @@ "url": "https://github.com/sponsors/epoberezkin" } }, + "node_modules/ajv-formats": { + "version": "3.0.1", + "resolved": "https://pkgs.dev.azure.com/azure-sdk/public/_packaging/azure-sdk-for-js/npm/registry/ajv-formats/-/ajv-formats-3.0.1.tgz", + "integrity": "sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ajv": "^8.0.0" + }, + "peerDependencies": { + "ajv": "^8.0.0" + }, + "peerDependenciesMeta": { + "ajv": { + "optional": true + } + } + }, "node_modules/ansi-regex": { "version": "6.2.2", "resolved": "https://pkgs.dev.azure.com/azure-sdk/public/_packaging/azure-sdk-for-js/npm/registry/ansi-regex/-/ansi-regex-6.2.2.tgz", diff --git a/packages/http-client-python/package.json b/packages/http-client-python/package.json index 658262ab694..64b4ac9438d 100644 --- a/packages/http-client-python/package.json +++ b/packages/http-client-python/package.json @@ -1,6 +1,6 @@ { "name": "@typespec/http-client-python", - "version": "0.39.0", + "version": "0.40.0", "author": "Microsoft Corporation", "description": "TypeSpec emitter for Python SDKs", "homepage": "https://typespec.io", @@ -66,11 +66,11 @@ "emitter" ], "peerDependencies": { - "@azure-tools/typespec-autorest": ">=0.73.0 <1.0.0", + "@azure-tools/typespec-autorest": ">=0.73.2 <1.0.0", "@azure-tools/typespec-azure-core": ">=0.73.0 <1.0.0", "@azure-tools/typespec-azure-resource-manager": ">=0.73.0 <1.0.0", "@azure-tools/typespec-azure-rulesets": ">=0.73.0 <1.0.0", - "@azure-tools/typespec-client-generator-core": ">=0.73.0 <1.0.0", + "@azure-tools/typespec-client-generator-core": ">=0.73.1 <1.0.0", "@typespec/compiler": "^1.17.0", "@typespec/http": "^1.17.0", "@typespec/openapi": "^1.17.0", @@ -104,11 +104,11 @@ "tsx": "^4.23.13" }, "devDependencies": { - "@azure-tools/typespec-autorest": "~0.73.0", + "@azure-tools/typespec-autorest": "~0.73.2", "@azure-tools/typespec-azure-core": "~0.73.0", "@azure-tools/typespec-azure-resource-manager": "~0.73.0", "@azure-tools/typespec-azure-rulesets": "~0.73.0", - "@azure-tools/typespec-client-generator-core": "~0.73.0", + "@azure-tools/typespec-client-generator-core": "~0.73.1", "@azure-tools/azure-http-specs": "0.1.0-alpha.46", "@typespec/compiler": "^1.17.0", "@typespec/http": "^1.17.0",