Skip to content

Commit

Permalink
feat: add instanceMethod (#68)
Browse files Browse the repository at this point in the history
Co-authored-by: Elias Sjögreen <elias@5monkeys.se>
  • Loading branch information
sigmaSd and eliassjogreen committed Aug 14, 2024
1 parent 22ef420 commit cf7a8a1
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 0 deletions.
28 changes: 28 additions & 0 deletions src/python.ts
Original file line number Diff line number Diff line change
Expand Up @@ -975,6 +975,34 @@ export class Python {
callback(cb: PythonJSCallback): Callback {
return new Callback(cb);
}

/**
* Creates a Python instance method from a JavaScript callback.
*
* @description
* This method takes a JavaScript callback function and creates a Python instance method.
*
* The method returns both the created Python instance method and the Callback object.
* The Callback object is returned to allow the user to explicitly call its `destroy`
* method when it's no longer needed, ensuring proper resource management and
* freeing of memory.
*
* @example
* const [pyMethod, callback] = instanceMethod(myJSFunction);
* // Use pyMethod as needed
* // ...
* // When done, explicitly free the callback
* callback.destroy();
*/
instanceMethod(cb: PythonJSCallback): [PyObject, Callback] {
const pythonCb = python.callback(cb);
const method = new PyObject(
py.PyInstanceMethod_New(
PyObject.from(pythonCb).handle,
),
);
return [method, pythonCb];
}
}

/**
Expand Down
5 changes: 5 additions & 0 deletions src/symbols.ts
Original file line number Diff line number Diff line change
Expand Up @@ -249,4 +249,9 @@ export const SYMBOLS = {
parameters: ["buffer", "pointer", "pointer"],
result: "pointer",
},

PyInstanceMethod_New: {
parameters: ["pointer"],
result: "pointer",
},
} as const;
20 changes: 20 additions & 0 deletions test/test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -325,6 +325,26 @@ Deno.test("exceptions", async (t) => {
});
});

Deno.test("instance method", () => {
const { A } = python.runModule(
`
class A:
def b(self):
return 4
`,
"cb_test.py",
);

const [m, cb] = python.instanceMethod((_args, self) => {
return self.b();
});
// Modifying PyObject modifes A
PyObject.from(A).setAttr("a", m);

assertEquals(new A().a.call().valueOf(), 4);
cb.destroy();
});

Deno.test("callbacks have signature", async (t) => {
const inspect = python.import("inspect");

Expand Down

0 comments on commit cf7a8a1

Please sign in to comment.