From 4f42c501a07a6b40fa046ff40d86ca0933b0f837 Mon Sep 17 00:00:00 2001 From: Lubos Date: Tue, 17 Mar 2026 03:17:05 +0100 Subject: [PATCH] feat: add class method node --- .../__snapshots__/opencode/default/sdk_gen.py | 20 +++++++++---------- .../src/plugins/@hey-api/sdk/v1/node.ts | 4 ++-- .../openapi-python/src/py-dsl/decl/func.ts | 11 +++++++--- packages/openapi-python/src/py-dsl/index.ts | 15 +++++++++----- .../openapi-python/src/py-dsl/utils/name.ts | 2 ++ .../src/py-dsl/utils/reserved.ts | 6 ++++++ 6 files changed, 38 insertions(+), 20 deletions(-) diff --git a/packages/openapi-python-tests/sdks/__snapshots__/opencode/default/sdk_gen.py b/packages/openapi-python-tests/sdks/__snapshots__/opencode/default/sdk_gen.py index d991666bd..122cbf391 100644 --- a/packages/openapi-python-tests/sdks/__snapshots__/opencode/default/sdk_gen.py +++ b/packages/openapi-python-tests/sdks/__snapshots__/opencode/default/sdk_gen.py @@ -35,7 +35,7 @@ class Global(Client): class Project(Client): - def list_(self): + def list(self): """ List all projects @@ -64,7 +64,7 @@ class Project(Client): class Pty(Client): - def list_(self): + def list(self): """ List PTY sessions @@ -158,7 +158,7 @@ class Tool(Client): return self.client.get("/experimental/tool/ids") - def list_(self): + def list(self): """ List tools @@ -202,7 +202,7 @@ class Vcs(Client): class Session(Client): - def list_(self): + def list(self): """ List sessions @@ -443,7 +443,7 @@ class Permission(Client): return self.client.post("/permission/{requestID}/reply") - def list_(self): + def list(self): """ List pending permissions @@ -454,7 +454,7 @@ class Permission(Client): class Command(Client): - def list_(self): + def list(self): """ List commands @@ -485,7 +485,7 @@ class Oauth(Client): class Provider(Client): - def list_(self): + def list(self): """ List providers @@ -538,7 +538,7 @@ class Find(Client): class File(Client): - def list_(self): + def list(self): """ List files @@ -681,7 +681,7 @@ class Formatter(Client): class Control(Client): - def next_(self): + def next(self): """ Get next TUI request @@ -797,7 +797,7 @@ class Tui(Client): class Auth_2(Client): - def set_(self): + def set(self): """ Set auth credentials diff --git a/packages/openapi-python/src/plugins/@hey-api/sdk/v1/node.ts b/packages/openapi-python/src/plugins/@hey-api/sdk/v1/node.ts index 4fea0385a..79858d29f 100644 --- a/packages/openapi-python/src/plugins/@hey-api/sdk/v1/node.ts +++ b/packages/openapi-python/src/plugins/@hey-api/sdk/v1/node.ts @@ -72,7 +72,7 @@ function childToNode( const cachedProp = plugin.external('functools.cached_property'); return [ - $.func(memberName) + $.method(memberName) .decorator(cachedProp) .param('self') .returns(refChild) @@ -196,7 +196,7 @@ export function toNode( } else { if (index > 0 || node.hasBody) node.newline(); const method = implementFn({ - node: $.func(createFnSymbol(plugin, item), (m) => + node: $.method(createFnSymbol(plugin, item), (m) => attachComment({ node: m, operation, diff --git a/packages/openapi-python/src/py-dsl/decl/func.ts b/packages/openapi-python/src/py-dsl/decl/func.ts index 4a552488c..66d08769c 100644 --- a/packages/openapi-python/src/py-dsl/decl/func.ts +++ b/packages/openapi-python/src/py-dsl/decl/func.ts @@ -1,4 +1,4 @@ -import type { AnalysisContext, NodeName } from '@hey-api/codegen-core'; +import type { AnalysisContext, NodeName, NodeNameSanitizer } from '@hey-api/codegen-core'; import { isSymbol } from '@hey-api/codegen-core'; import { py } from '../../ts-python'; @@ -22,10 +22,15 @@ const Mixed = AsyncMixin( export class FuncPyDsl extends Mixed { readonly '~dsl' = 'FuncPyDsl'; - override readonly nameSanitizer = safeRuntimeName; + override readonly nameSanitizer: NodeNameSanitizer; - constructor(name: NodeName, fn?: (f: FuncPyDsl) => void) { + constructor( + name: NodeName, + fn?: (f: FuncPyDsl) => void, + options?: { nameSanitizer?: NodeNameSanitizer }, + ) { super(); + this.nameSanitizer = options?.nameSanitizer ?? safeRuntimeName; this.name.set(name); if (isSymbol(name)) { name.setKind('function'); diff --git a/packages/openapi-python/src/py-dsl/index.ts b/packages/openapi-python/src/py-dsl/index.ts index 6c6e96147..fa00f201a 100644 --- a/packages/openapi-python/src/py-dsl/index.ts +++ b/packages/openapi-python/src/py-dsl/index.ts @@ -71,6 +71,7 @@ import { WithPyDsl } from './stmt/with'; // import { TypeTemplatePyDsl } from './type/template'; // import { TypeTuplePyDsl } from './type/tuple'; import { LazyPyDsl } from './utils/lazy'; +import { safeKeywordName } from './utils/name'; const pyDsl = { /** Creates an array literal expression (e.g. `[1, 2, 3]`). */ @@ -147,12 +148,12 @@ const pyDsl = { /** Creates an import statement. */ import: (...args: ConstructorParameters) => new ImportPyDsl(...args), - /** Creates a keyword argument expression (e.g. `name=value`). */ - kwarg: (...args: ConstructorParameters) => new KwargPyDsl(...args), - /** Creates an initialization block or statement. */ // init: (...args: ConstructorParameters) => new InitTsDsl(...args), + /** Creates a keyword argument expression (e.g. `name=value`). */ + kwarg: (...args: ConstructorParameters) => new KwargPyDsl(...args), + /** Creates a lazy, context-aware node with deferred evaluation. */ lazy: (...args: ConstructorParameters>) => new LazyPyDsl(...args), @@ -166,8 +167,12 @@ const pyDsl = { /** Creates an enum member declaration. */ // member: (...args: ConstructorParameters) => new EnumMemberTsDsl(...args), - /** Creates a method declaration inside a class or object. */ - // method: (...args: ConstructorParameters) => new MethodTsDsl(...args), + /** Creates a class method declaration. */ + method: ((name: NodeName, fn?: (f: FuncPyDsl) => void) => + new FuncPyDsl(name, fn, { nameSanitizer: safeKeywordName })) as { + (name: NodeName): FuncPyDsl; + (name: NodeName, fn: (f: FuncPyDsl) => void): FuncPyDsl; + }, /** Creates a negation expression (`-x`). */ // neg: (...args: ConstructorParameters) => new PrefixTsDsl(...args).neg(), diff --git a/packages/openapi-python/src/py-dsl/utils/name.ts b/packages/openapi-python/src/py-dsl/utils/name.ts index ffb7864e4..657fe0926 100644 --- a/packages/openapi-python/src/py-dsl/utils/name.ts +++ b/packages/openapi-python/src/py-dsl/utils/name.ts @@ -51,3 +51,5 @@ const safeName = (name: string, reserved: ReservedList): string => { }; export const safeRuntimeName = (name: string): string => safeName(name, reserved.runtime); + +export const safeKeywordName = (name: string): string => safeName(name, reserved.keywords); diff --git a/packages/openapi-python/src/py-dsl/utils/reserved.ts b/packages/openapi-python/src/py-dsl/utils/reserved.ts index ba9b74499..b53f94547 100644 --- a/packages/openapi-python/src/py-dsl/utils/reserved.ts +++ b/packages/openapi-python/src/py-dsl/utils/reserved.ts @@ -29,12 +29,18 @@ export class ReservedList { } const runtimeReserved = new ReservedList([...keywords.pythonKeywords, ...keywords.pythonBuiltins]); +const keywordReserved = new ReservedList([...keywords.pythonKeywords]); /** * Reserved names for identifiers. These names will not be used * for variables, functions, classes, or other identifiers in generated code. */ export const reserved = { + /** + * Reserved names for Python language keywords. These names are syntactically + * invalid as identifiers in any scope. + */ + keywords: keywordReserved, /** * Reserved names for runtime identifiers. These names will not be used * for variables, functions, classes, or other runtime identifiers in -- 2.51.2