Skip to content

fix(http-client-python): api_version validation decorator reads correct config attribute name#11392

Open
l0lawrence wants to merge 9 commits into
mainfrom
l0lawrence-fix-api-version-validation-attr
Open

fix(http-client-python): api_version validation decorator reads correct config attribute name#11392
l0lawrence wants to merge 9 commits into
mainfrom
l0lawrence-fix-api-version-validation-attr

Conversation

@l0lawrence

@l0lawrence l0lawrence commented Jul 24, 2026

Copy link
Copy Markdown
Member

Root cause

The generated _validation.py @api_version_validation decorator (from validation.py.jinja2) hardcoded:

client_api_version = client._config.api_version

But the config attribute name is generated from the API-version parameter's client_name (config.py.jinja2: self.{{ parameter.client_name }} = {{ parameter.client_name }}). Most specs name the param apiVersionself.api_version, so it works.

Some specs name the versioning parameter version instead — e.g. Azure Storage Blob, declared as @apiVersion @header("x-ms-version") version: string. Those clients get self.version and not self.api_version, so client._config.api_version raised AttributeError, which the decorator catches and silently no-ops. Result: all api-version validation was silently skipped for those clients.

Caveat****: single shared decorator per package

_validation.py contains a single shared @api_version_validation decorator for the whole package, so only one api-version attribute name can be baked in. _api_version_config_attr_name() therefore bakes the name only when all clients in the package agree on it; if a package ever had multiple clients using different api-version attribute names, the helper falls back to the conventional api_version. In practice a package's clients share one api-version name, which matches what _configuration.py generates.

…ct config attribute name

The generated _validation.py @api_version_validation decorator hardcoded
`client._config.api_version`, but the config attribute name is derived from the
API-version parameter's client_name. Specs that name the versioning parameter
something other than `apiVersion` (e.g. Azure Storage Blob's
`@apiVersion @Header("x-ms-version") version: string`, which produces
`self.version`) hit an AttributeError that the decorator silently swallowed,
disabling all API-version validation for those clients.

Thread the real attribute name into the decorator via a `client_api_version_name`
kwarg, emitted only when it differs from the default `api_version`. Also fix a
latent NameError in the decorator's `unsupported` error-message branch that
referenced an out-of-scope `version` variable.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 9e983f91-eed5-4191-b531-0eca9e696313
@microsoft-github-policy-service microsoft-github-policy-service Bot added the emitter:client:python Issue for the Python client emitter: @typespec/http-client-python label Jul 24, 2026
@pkg-pr-new

pkg-pr-new Bot commented Jul 24, 2026

Copy link
Copy Markdown

Open in StackBlitz

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

commit: 3d6b98d

@github-actions

github-actions Bot commented Jul 24, 2026

Copy link
Copy Markdown
Contributor

All changed packages have been documented.

  • @typespec/http-client-python
Show changes

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

Fix the generated _validation.py @api_version_validation decorator so it reads the correct client config attribute for the API version. It previously hardcoded client._config.api_version, but the attribute name is derived from the API-version parameter's client_name. For specs that name the versioning parameter something other than apiVersion (e.g. self.version), the lookup raised AttributeError that the decorator silently swallowed, disabling all API-version validation for those clients. The emitter now bakes the real attribute name into the generated decorator so it reads config.<name> directly.

@azure-sdk-automation

azure-sdk-automation Bot commented Jul 24, 2026

Copy link
Copy Markdown

You can try these changes here

🛝 Playground 🌐 Website 🛝 VSCode Extension

@github-actions

github-actions Bot commented Jul 24, 2026

Copy link
Copy Markdown
Contributor

Python emitter diff

Baseline gh:4da8bc856581babb8cb705ed9a0199141dff296b vs this PR.

Diff summary: 4 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.

…ion attribute fix

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Copilot-Session: 9e983f91-eed5-4191-b531-0eca9e696313
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Copilot-Session: 9e983f91-eed5-4191-b531-0eca9e696313
…he pylint suppression

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Copilot-Session: 9e983f91-eed5-4191-b531-0eca9e696313
…tattr

Thread a client_api_version_getter (lambda config: config.<name>) into the decorator so the generated code reads self._config.<name> directly rather than via a getattr string lookup.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Copilot-Session: 9e983f91-eed5-4191-b531-0eca9e696313
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Copilot-Session: 9e983f91-eed5-4191-b531-0eca9e696313
Render config.<name> directly instead of threading a decorator kwarg; resolve the api-version attribute name once at package level from ConfigParameter.client_name.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Copilot-Session: 9e983f91-eed5-4191-b531-0eca9e696313
Read client._config.<name> directly; the baked-in short attribute name keeps the line under black's limit so the protected-access suppression stays attached.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Copilot-Session: 9e983f91-eed5-4191-b531-0eca9e696313
names = {
parameter.client_name
for client in self.code_model.clients
for parameter in client.config.parameters.parameters

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

is there a cleaner way to get the config api_version name?

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant