From 225480de648e34a6b7e4514f0f525849932cb8ff Mon Sep 17 00:00:00 2001 From: iscai-msft Date: Mon, 23 Feb 2026 17:12:36 -0500 Subject: [PATCH 1/5] allow client options on child clients to override parent client --- packages/http-client-python/emitter/src/code-model.ts | 6 ++++-- packages/http-client-python/emitter/src/http.ts | 11 ++++++++++- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/packages/http-client-python/emitter/src/code-model.ts b/packages/http-client-python/emitter/src/code-model.ts index e75848495fb..bc393bf2274 100644 --- a/packages/http-client-python/emitter/src/code-model.ts +++ b/packages/http-client-python/emitter/src/code-model.ts @@ -222,14 +222,16 @@ function emitOperationGroups( const apiVersions = serviceApiVersions.length > 0 ? serviceApiVersions : operationGroup.apiVersions; for (const method of operationGroup.methods) { - operations = operations.concat(emitMethod(context, rootClient, method, name, apiVersions)); + operations = operations.concat( + emitMethod(context, operationGroup, method, name, apiVersions), + ); } operationGroups.push({ name: name, className: name, propertyName: operationGroup.name, operations: operations, - operationGroups: emitOperationGroups(context, operationGroup, rootClient, name, apiVersions), + operationGroups: emitOperationGroups(context, operationGroup, operationGroup, name, apiVersions), clientNamespace: getClientNamespace(context, operationGroup.namespace), }); } diff --git a/packages/http-client-python/emitter/src/http.ts b/packages/http-client-python/emitter/src/http.ts index 99184365d16..3f4b96c7cfa 100644 --- a/packages/http-client-python/emitter/src/http.ts +++ b/packages/http-client-python/emitter/src/http.ts @@ -379,7 +379,16 @@ function emitHttpOperation( for (const exception of operation.exceptions) { exceptions.push(emitHttpResponse(context, exception.statusCodes, exception, undefined, true)!); } - const includeRootSlash = getClientOptions(rootClient, "includeRootSlash") !== false; + // Walk up the client hierarchy to find the option, allowing sub-clients to + // override values set on the root client. + let includeRootSlashOption: unknown; + let current: SdkClientType | undefined = rootClient; + while (current) { + includeRootSlashOption = getClientOptions(current, "includeRootSlash"); + if (includeRootSlashOption !== undefined) break; + current = current.parent; + } + const includeRootSlash = includeRootSlashOption !== false; const result = { url: includeRootSlash ? operation.path : operation.path.replace(/^\//, ""), From 939af4b3f9c9794d6b4d967fc8e0c6e1d9954435 Mon Sep 17 00:00:00 2001 From: iscai-msft Date: Mon, 23 Feb 2026 17:13:15 -0500 Subject: [PATCH 2/5] add changeset --- .../python-clientOptionInterface-2026-1-23-17-13-8.md | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 .chronus/changes/python-clientOptionInterface-2026-1-23-17-13-8.md diff --git a/.chronus/changes/python-clientOptionInterface-2026-1-23-17-13-8.md b/.chronus/changes/python-clientOptionInterface-2026-1-23-17-13-8.md new file mode 100644 index 00000000000..4893c3313cb --- /dev/null +++ b/.chronus/changes/python-clientOptionInterface-2026-1-23-17-13-8.md @@ -0,0 +1,7 @@ +--- +changeKind: fix +packages: + - "@typespec/http-client-python" +--- + +Allow client options on child clients to override parent clients \ No newline at end of file From dd05d7a12d056c274984990fbc68b05d3c816e57 Mon Sep 17 00:00:00 2001 From: iscai-msft Date: Tue, 24 Feb 2026 12:09:43 -0500 Subject: [PATCH 3/5] format --- packages/http-client-python/emitter/src/code-model.ts | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/packages/http-client-python/emitter/src/code-model.ts b/packages/http-client-python/emitter/src/code-model.ts index bc393bf2274..d2a92ae048f 100644 --- a/packages/http-client-python/emitter/src/code-model.ts +++ b/packages/http-client-python/emitter/src/code-model.ts @@ -231,7 +231,13 @@ function emitOperationGroups( className: name, propertyName: operationGroup.name, operations: operations, - operationGroups: emitOperationGroups(context, operationGroup, operationGroup, name, apiVersions), + operationGroups: emitOperationGroups( + context, + operationGroup, + operationGroup, + name, + apiVersions, + ), clientNamespace: getClientNamespace(context, operationGroup.namespace), }); } From f7b0e8192683f5a9a6c8c9487239abc1f14a823f Mon Sep 17 00:00:00 2001 From: iscai-msft Date: Tue, 24 Feb 2026 12:55:37 -0500 Subject: [PATCH 4/5] fix operation group passing --- .../emitter/src/code-model.ts | 62 +++++++++---------- 1 file changed, 28 insertions(+), 34 deletions(-) diff --git a/packages/http-client-python/emitter/src/code-model.ts b/packages/http-client-python/emitter/src/code-model.ts index d2a92ae048f..7edeecb0443 100644 --- a/packages/http-client-python/emitter/src/code-model.ts +++ b/packages/http-client-python/emitter/src/code-model.ts @@ -39,7 +39,7 @@ function emitBasicMethod( context: PythonSdkContext, rootClient: SdkClientType, method: SdkBasicServiceMethod, - operationGroupName: string, + operationGroup: SdkClientType, serviceApiVersions: string[], ): Record[] { if (method.operation.kind !== "http") @@ -50,7 +50,7 @@ function emitBasicMethod( context, rootClient, method, - operationGroupName, + operationGroup.name, serviceApiVersions, ); default: @@ -62,14 +62,20 @@ function emitLroMethod( context: PythonSdkContext, rootClient: SdkClientType, method: SdkLroServiceMethod, - operationGroupName: string, + operationGroup: SdkClientType, serviceApiVersions: string[], ): Record[] { if (method.operation.kind !== "http") throw new Error("We only support HTTP operations right now"); switch (method.operation.kind) { case "http": - return emitLroHttpMethod(context, rootClient, method, operationGroupName, serviceApiVersions); + return emitLroHttpMethod( + context, + rootClient, + method, + operationGroup.name, + serviceApiVersions, + ); default: throw new Error("We only support HTTP operations right now"); } @@ -79,7 +85,7 @@ function emitPagingMethod( context: PythonSdkContext, rootClient: SdkClientType, method: SdkPagingServiceMethod, - operationGroupName: string, + operationGroup: SdkClientType, serviceApiVersions: string[], ): Record[] { if (method.operation.kind !== "http") @@ -90,7 +96,7 @@ function emitPagingMethod( context, rootClient, method, - operationGroupName, + operationGroup.name, serviceApiVersions, ); default: @@ -102,7 +108,7 @@ function emitLroPagingMethod( context: PythonSdkContext, rootClient: SdkClientType, method: SdkLroPagingServiceMethod, - operationGroupName: string, + operationGroup: SdkClientType, serviceApiVersions: string[], ): Record[] { if (method.operation.kind !== "http") @@ -113,7 +119,7 @@ function emitLroPagingMethod( context, rootClient, method, - operationGroupName, + operationGroup.name, serviceApiVersions, ); default: @@ -183,25 +189,19 @@ function emitMethodParameter( function emitMethod( context: PythonSdkContext, rootClient: SdkClientType, + operationGroup: SdkClientType, method: SdkServiceMethod, - operationGroupName: string, serviceApiVersions: string[], ): Record[] { switch (method.kind) { case "basic": - return emitBasicMethod(context, rootClient, method, operationGroupName, serviceApiVersions); + return emitBasicMethod(context, rootClient, method, operationGroup, serviceApiVersions); case "lro": - return emitLroMethod(context, rootClient, method, operationGroupName, serviceApiVersions); + return emitLroMethod(context, rootClient, method, operationGroup, serviceApiVersions); case "paging": - return emitPagingMethod(context, rootClient, method, operationGroupName, serviceApiVersions); + return emitPagingMethod(context, rootClient, method, operationGroup, serviceApiVersions); default: - return emitLroPagingMethod( - context, - rootClient, - method, - operationGroupName, - serviceApiVersions, - ); + return emitLroPagingMethod(context, rootClient, method, operationGroup, serviceApiVersions); } } @@ -211,43 +211,37 @@ function emitOperationGroups( context: PythonSdkContext, client: SdkClientType, rootClient: SdkClientType, - prefix: string, serviceApiVersions: string[], ): Record[] | undefined { const operationGroups: Record[] = []; for (const operationGroup of client.children ?? []) { - const name = `${prefix}${operationGroup.name}`; + operationGroup.name = `${client.name}${operationGroup.name}`; let operations: Record[] = []; const apiVersions = serviceApiVersions.length > 0 ? serviceApiVersions : operationGroup.apiVersions; for (const method of operationGroup.methods) { operations = operations.concat( - emitMethod(context, operationGroup, method, name, apiVersions), + emitMethod(context, rootClient, operationGroup, method, apiVersions), ); } operationGroups.push({ - name: name, - className: name, + name: operationGroup.name, + className: operationGroup.name, propertyName: operationGroup.name, operations: operations, - operationGroups: emitOperationGroups( - context, - operationGroup, - operationGroup, - name, - apiVersions, - ), + operationGroups: emitOperationGroups(context, operationGroup, rootClient, apiVersions), clientNamespace: getClientNamespace(context, operationGroup.namespace), }); } // root client should deal with mixin operation group - if (prefix === "") { + if (client === rootClient) { + const mixinGroup = { ...client, name: "" } as SdkClientType; let operations: Record[] = []; for (const method of client.methods) { operations = operations.concat( - emitMethod(context, rootClient, method, "", serviceApiVersions), + emitMethod(context, rootClient, mixinGroup, method, serviceApiVersions), ); } if (operations.length > 0) { @@ -309,7 +303,7 @@ function emitClient( const endpointParameter = initParameters.find((x) => x.kind === "endpoint") as | SdkEndpointParameter | undefined; - const operationGroups = emitOperationGroups(context, client, client, "", client.apiVersions); + const operationGroups = emitOperationGroups(context, client, client, client.apiVersions); let url: string | undefined; if (endpointParameter?.type.kind === "union") { url = (endpointParameter.type.variantTypes[0] as SdkEndpointType).serverUrl; From f81be2785f8e5857753c0b59e367c7977a85ea49 Mon Sep 17 00:00:00 2001 From: iscai-msft Date: Tue, 24 Feb 2026 15:25:07 -0500 Subject: [PATCH 5/5] hopefully fix diffs --- packages/http-client-python/emitter/src/code-model.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/http-client-python/emitter/src/code-model.ts b/packages/http-client-python/emitter/src/code-model.ts index 7edeecb0443..bfd56b06337 100644 --- a/packages/http-client-python/emitter/src/code-model.ts +++ b/packages/http-client-python/emitter/src/code-model.ts @@ -216,7 +216,7 @@ function emitOperationGroups( const operationGroups: Record[] = []; for (const operationGroup of client.children ?? []) { - operationGroup.name = `${client.name}${operationGroup.name}`; + const name = `${client.name}${operationGroup.name}`; let operations: Record[] = []; const apiVersions = serviceApiVersions.length > 0 ? serviceApiVersions : operationGroup.apiVersions; @@ -226,8 +226,8 @@ function emitOperationGroups( ); } operationGroups.push({ - name: operationGroup.name, - className: operationGroup.name, + name: name, + className: name, propertyName: operationGroup.name, operations: operations, operationGroups: emitOperationGroups(context, operationGroup, rootClient, apiVersions),