From fdc679fb236c01ecb5bd0eca9216ed79427cf2c5 Mon Sep 17 00:00:00 2001 From: CrackTC Date: Wed, 4 Feb 2026 16:14:17 +0800 Subject: [PATCH 1/2] fix: support python @classmethod decorator --- .../analyzer/python/common/python-analyzer.ts | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/engine/analyzer/python/common/python-analyzer.ts b/src/engine/analyzer/python/common/python-analyzer.ts index 427ad6df..c1fba6e0 100644 --- a/src/engine/analyzer/python/common/python-analyzer.ts +++ b/src/engine/analyzer/python/common/python-analyzer.ts @@ -246,6 +246,21 @@ class PythonAnalyzer extends (Analyzer as any) { return SymbolValue(new_node) } + /** + * + * @param fclos + * @param argvalues + * @param state + * @param node + * @param scope + */ + executeSingleCall(fclos: any, argvalues: any, state: any, node: any, scope: any) { + if (fclos.decorators?.some((d: any) => d.name === 'classmethod') && argvalues[0]?.vtype === 'undefine') { + argvalues[0] = fclos._this + } + return super.executeSingleCall(fclos, argvalues, state, node, scope) + } + /** * * @param scope From f28e2898432bbcd9e362140f4bba7e8a67b54250 Mon Sep 17 00:00:00 2001 From: CrackTC Date: Tue, 17 Mar 2026 19:47:01 +0800 Subject: [PATCH 2/2] fix: add __class field to new object & improve classmethod decorator handling --- .../analyzer/python/common/python-analyzer.ts | 33 +++++++++++++++++-- 1 file changed, 31 insertions(+), 2 deletions(-) diff --git a/src/engine/analyzer/python/common/python-analyzer.ts b/src/engine/analyzer/python/common/python-analyzer.ts index c1fba6e0..0a8cf451 100644 --- a/src/engine/analyzer/python/common/python-analyzer.ts +++ b/src/engine/analyzer/python/common/python-analyzer.ts @@ -255,8 +255,20 @@ class PythonAnalyzer extends (Analyzer as any) { * @param scope */ executeSingleCall(fclos: any, argvalues: any, state: any, node: any, scope: any) { - if (fclos.decorators?.some((d: any) => d.name === 'classmethod') && argvalues[0]?.vtype === 'undefine') { - argvalues[0] = fclos._this + if (fclos.decorators?.some((d: any) => d.name === 'classmethod')) { + let cls + if (fclos._this.vtype === 'object' && fclos._this.__class) { + cls = fclos._this.__class + } else if (fclos._this.vtype === 'class') { + cls = fclos._this + } + if (cls) { + if (argvalues[0]?.vtype === 'undefine') { + argvalues[0] = cls + } else if (argvalues[0]) { + argvalues.unshift(cls) + } + } } return super.executeSingleCall(fclos, argvalues, state, node, scope) } @@ -370,6 +382,23 @@ class PythonAnalyzer extends (Analyzer as any) { return res } + /** + * + * @param fdef + * @param argvalues + * @param fclos + * @param state + * @param node + * @param scope + */ + buildNewObject(fdef: any, argvalues: any, fclos: any, state: any, node: any, scope: any) { + const result = super.buildNewObject(fdef, argvalues, fclos, state, node, scope) + if (fclos.vtype === 'class') { + result.__class = fclos + } + return result + } + /** * * @param scope