Skip to content

Commit 4edb7a7

Browse files
Merge branch 'main' into ii
2 parents 365af98 + 22ef420 commit 4edb7a7

File tree

2 files changed

+30
-4
lines changed

2 files changed

+30
-4
lines changed

src/python.ts

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -458,9 +458,9 @@ export class PyObject {
458458
const view = new DataView(pyMethodDef.buffer);
459459
const LE =
460460
new Uint8Array(new Uint32Array([0x12345678]).buffer)[0] !== 0x7;
461-
const nameBuf = new TextEncoder().encode(
462-
"JSCallback:" + (v.callback.name || "anonymous") + "\0",
463-
);
461+
462+
const name = "JSCallback:" + (v.callback.name || "anonymous");
463+
const nameBuf = new TextEncoder().encode(`${name}\0`);
464464
view.setBigUint64(
465465
0,
466466
BigInt(Deno.UnsafePointer.value(Deno.UnsafePointer.of(nameBuf)!)),
@@ -472,9 +472,19 @@ export class PyObject {
472472
LE,
473473
);
474474
view.setInt32(16, 0x1 | 0x2, LE);
475+
// https://github.com/python/cpython/blob/f27593a87c344f3774ca73644a11cbd5614007ef/Objects/typeobject.c#L688
476+
const SIGNATURE_END_MARKER = ")\n--\n\n";
477+
// We're not using the correct arguments name, but just using dummy ones (because they're not accessible in js)
478+
const fnArgs = [...Array(v.callback.length).keys()]
479+
.map((_, i) => String.fromCharCode(97 + i)).join(",");
480+
const docBuf = `${name}(${fnArgs}${SIGNATURE_END_MARKER}\0`;
475481
view.setBigUint64(
476482
24,
477-
BigInt(Deno.UnsafePointer.value(Deno.UnsafePointer.of(nameBuf)!)),
483+
BigInt(
484+
Deno.UnsafePointer.value(
485+
Deno.UnsafePointer.of(new TextEncoder().encode(docBuf))!,
486+
),
487+
),
478488
LE,
479489
);
480490
const fn = py.PyCFunction_NewEx(

test/test.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -344,3 +344,19 @@ class A:
344344
assertEquals(new A().a.call().valueOf(), 4);
345345
cb.destroy();
346346
});
347+
348+
Deno.test("callbacks have signature", async (t) => {
349+
const inspect = python.import("inspect");
350+
351+
await t.step("empty arguments", () => {
352+
const fn = python.callback(() => {});
353+
assertEquals(inspect.signature(fn).toString(), "()");
354+
fn.destroy();
355+
});
356+
357+
await t.step("with no arguments", () => {
358+
const fn = python.callback((_f, _b, _c) => {});
359+
assertEquals(inspect.signature(fn).toString(), "(a, b, c)");
360+
fn.destroy();
361+
});
362+
});

0 commit comments

Comments
 (0)