Skip to content

fix: support python @classmethod decorator#112

Open
CrackTC wants to merge 2 commits intoantgroup:mainfrom
CrackTC:fix/python-classmethod
Open

fix: support python @classmethod decorator#112
CrackTC wants to merge 2 commits intoantgroup:mainfrom
CrackTC:fix/python-classmethod

Conversation

@CrackTC
Copy link
Copy Markdown
Collaborator

@CrackTC CrackTC commented Apr 1, 2026

No description provided.

Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request introduces executeSingleCall and buildNewObject to the PythonAnalyzer to support Python class methods and object instantiation. The executeSingleCall method handles the injection of the class reference into the argument list for methods decorated with @classmethod. A review comment identifies a potential crash due to a missing null check on fclos._this and a logic bug where the class argument is not correctly prepended when the argument list is empty.

Comment on lines +257 to +274
executeSingleCall(fclos: any, argvalues: any, state: any, node: any, scope: any) {
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)
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

high

The implementation of executeSingleCall has two significant issues:

  1. Potential Crash: fclos._this is accessed directly at line 260 without a null/undefined check. If _this is not set for the closure, the analyzer will throw an exception and crash.
  2. Logic Bug in Argument Injection: The logic for injecting the class argument (cls) into argvalues fails when argvalues is empty (line 268). In Python, a @classmethod always receives the class as its first argument, even if no other arguments are passed. Additionally, using else if (argvalues[0]) is risky as it relies on truthiness; it is safer to check the array length or handle the empty case explicitly.
  executeSingleCall(fclos: any, argvalues: any, state: any, node: any, scope: any) {
    if (fclos.decorators?.some((d: any) => d.name === 'classmethod')) {
      let cls
      const _this = fclos._this
      if (_this) {
        if (_this.vtype === 'object' && _this.__class) {
          cls = _this.__class
        } else if (_this.vtype === 'class') {
          cls = _this
        }
      }
      if (cls) {
        if (argvalues.length > 0 && argvalues[0]?.vtype === 'undefine') {
          argvalues[0] = cls
        } else {
          argvalues.unshift(cls)
        }
      }
    }
    return super.executeSingleCall(fclos, argvalues, state, node, scope)
  }

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant