From c3ae19b0e54da92f1e52e8dec1d24528d85c50f8 Mon Sep 17 00:00:00 2001 From: Dean Srebnik <49134864+load1n9@users.noreply.github.com> Date: Fri, 24 Feb 2023 13:31:01 -0500 Subject: [PATCH] fix: ffi breaking changes (#31) * fix: ffi breaking changes * fix: pyobject type assertion --- LICENSE | 2 +- README.md | 8 ++--- deno.json | 6 +++- src/python.ts | 83 ++++++++++++++++++++++++++++++--------------------- src/util.ts | 2 +- test/deps.ts | 2 +- 6 files changed, 61 insertions(+), 42 deletions(-) diff --git a/LICENSE b/LICENSE index dedb8d3..adc1f58 100644 --- a/LICENSE +++ b/LICENSE @@ -1,7 +1,7 @@ MIT License Copyright (c) 2021 DjDeveloperr -Copyright (c) 2022 the denosaurs team +Copyright (c) 2023 the denosaurs team Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/README.md b/README.md index edbc57c..dc669b6 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ # deno_python [![Tags](https://img.shields.io/github/release/denosaurs/deno_python)](https://github.com/denosaurs/deno_python/releases) -[![deno doc](https://doc.deno.land/badge.svg)](https://doc.deno.land/https/deno.land/x/python@0.2.3/mod.ts) +[![deno doc](https://doc.deno.land/badge.svg)](https://doc.deno.land/https/deno.land/x/python/mod.ts) [![checks](https://github.com/denosaurs/deno_python/actions/workflows/checks.yml/badge.svg)](https://github.com/denosaurs/deno_python/actions/workflows/checks.yml) [![License](https://img.shields.io/github/license/denosaurs/deno_python)](https://github.com/denosaurs/deno_python/blob/master/LICENSE) @@ -12,7 +12,7 @@ Python interpreter bindings for Deno. Import any locally installed Python package, for example, `matplotlib`: ```ts -import { python } from "https://deno.land/x/python@0.2.3/mod.ts"; +import { python } from "https://deno.land/x/python/mod.ts"; const np = python.import("numpy"); const plt = python.import("matplotlib.pyplot"); @@ -35,7 +35,7 @@ deno run -A --unstable ## Documentation Check out the docs -[here](https://doc.deno.land/https://deno.land/x/python@0.2.3/mod.ts). +[here](https://doc.deno.land/https://deno.land/x/python/mod.ts). ## Python Installation @@ -70,4 +70,4 @@ Pull request, issues and feedback are very welcome. Code style is formatted with Copyright 2021, DjDeveloperr. -Copyright 2022, the Denosaurs team. All rights reserved. MIT license. +Copyright 2023, the Denosaurs team. All rights reserved. MIT license. diff --git a/deno.json b/deno.json index aff6ace..14dfab9 100644 --- a/deno.json +++ b/deno.json @@ -1,5 +1,9 @@ { "tasks": { - "test": "deno test --unstable -A test/test.ts" + "test": "deno test --unstable -A test/test.ts", + "example_hello_python": "deno run -A --unstable examples/hello_python.ts", + "example_matplotlib": "deno run -A --unstable examples/matplotlib.ts", + "example_run_code": "deno run -A --unstable examples/run_code.ts", + "example_tensorflow": "deno run -A --unstable examples/tensorflow.ts" } } diff --git a/src/python.ts b/src/python.ts index 949064e..e0703fb 100644 --- a/src/python.ts +++ b/src/python.ts @@ -149,11 +149,11 @@ export class Callback { kwargs: Deno.PointerValue, ) => { return PyObject.from(callback( - kwargs === 0 ? {} : Object.fromEntries( + kwargs === null ? {} : Object.fromEntries( new PyObject(kwargs).asDict() .entries(), ), - ...(args === 0 ? [] : new PyObject(args).valueOf()), + ...(args === null ? [] : new PyObject(args).valueOf()), )).handle; }, ); @@ -193,8 +193,7 @@ export class PyObject { * Check if the object is NULL (pointer) or None type in Python. */ get isNone() { - return this.handle === 0 || - this.handle === 0n || + return this.handle === null || this.handle === python.None[ProxiedPyObject].handle; } @@ -290,7 +289,7 @@ export class PyObject { this.handle, parseInt(name), ); - if (item !== 0) { + if (item !== null) { return new PyObject(item).proxy; } } @@ -302,7 +301,7 @@ export class PyObject { this.handle, slice.handle, ); - if (item !== 0) { + if (item !== null) { return new PyObject(item).proxy; } } @@ -319,7 +318,7 @@ export class PyObject { this.handle, cstr(name), ); - if (value !== 0) { + if (value !== null) { return new PyObject(value).proxy; } } @@ -443,20 +442,24 @@ export class PyObject { ); view.setBigUint64( 0, - BigInt(Deno.UnsafePointer.of(nameBuf)), + BigInt(Deno.UnsafePointer.value(Deno.UnsafePointer.of(nameBuf)!)), + LE, + ); + view.setBigUint64( + 8, + BigInt(Deno.UnsafePointer.value(v.unsafe.pointer)), LE, ); - view.setBigUint64(8, BigInt(v.unsafe.pointer), LE); view.setInt32(16, 0x1 | 0x2, LE); view.setBigUint64( 20, - BigInt(Deno.UnsafePointer.of(nameBuf)), + BigInt(Deno.UnsafePointer.value(Deno.UnsafePointer.of(nameBuf)!)), LE, ); const fn = py.PyCFunction_NewEx( struct, PyObject.from(null).handle, - 0n, + null, ); return new PyObject(fn); } else if (v instanceof PyObject) { @@ -526,7 +529,7 @@ export class PyObject { const obj = new PyObject( py.PyObject_GetAttrString(this.handle, cstr(name)), ); - if (obj.handle === 0) { + if (obj.handle === null) { py.PyErr_Clear(); return undefined; } else { @@ -592,11 +595,7 @@ export class PyObject { */ asString() { const str = py.PyUnicode_AsUTF8(this.handle); - if (str === 0) { - return null; - } else { - return Deno.UnsafePointerView.getCString(str as bigint); - } + return str !== null ? Deno.UnsafePointerView.getCString(str) : null; } /** @@ -635,7 +634,7 @@ export class PyObject { *[Symbol.iterator]() { const iter = py.PyObject_GetIter(this.handle); let item = py.PyIter_Next(iter); - while (item !== 0) { + while (item !== null) { yield new PyObject(item); item = py.PyIter_Next(iter); } @@ -677,23 +676,39 @@ export class PyObject { valueOf() { const type = py.PyObject_Type(this.handle); - if (type === python.None[ProxiedPyObject].handle) { + if (Deno.UnsafePointer.equals(type, python.None[ProxiedPyObject].handle)) { return null; - } else if (type === python.bool[ProxiedPyObject].handle) { + } else if ( + Deno.UnsafePointer.equals(type, python.bool[ProxiedPyObject].handle) + ) { return this.asBoolean(); - } else if (type === python.int[ProxiedPyObject].handle) { + } else if ( + Deno.UnsafePointer.equals(type, python.int[ProxiedPyObject].handle) + ) { return this.asLong(); - } else if (type === python.float[ProxiedPyObject].handle) { + } else if ( + Deno.UnsafePointer.equals(type, python.float[ProxiedPyObject].handle) + ) { return this.asDouble(); - } else if (type === python.str[ProxiedPyObject].handle) { + } else if ( + Deno.UnsafePointer.equals(type, python.str[ProxiedPyObject].handle) + ) { return this.asString(); - } else if (type === python.list[ProxiedPyObject].handle) { + } else if ( + Deno.UnsafePointer.equals(type, python.list[ProxiedPyObject].handle) + ) { return this.asArray(); - } else if (type === python.dict[ProxiedPyObject].handle) { + } else if ( + Deno.UnsafePointer.equals(type, python.dict[ProxiedPyObject].handle) + ) { return this.asDict(); - } else if (type === python.set[ProxiedPyObject].handle) { + } else if ( + Deno.UnsafePointer.equals(type, python.set[ProxiedPyObject].handle) + ) { return this.asSet(); - } else if (type === python.tuple[ProxiedPyObject].handle) { + } else if ( + Deno.UnsafePointer.equals(type, python.tuple[ProxiedPyObject].handle) + ) { return this.asTuple(); } else { return this.proxy; @@ -777,7 +792,7 @@ export class PythonError extends Error { */ export function maybeThrowError() { const error = py.PyErr_Occurred(); - if (error === 0) { + if (error === null) { return; } @@ -788,9 +803,9 @@ export function maybeThrowError() { pointers.subarray(2, 3), ); - const type = new PyObject(pointers[0]), - value = new PyObject(pointers[1]), - traceback = new PyObject(pointers[2]); + const type = new PyObject(Deno.UnsafePointer.create(pointers[0])), + value = new PyObject(Deno.UnsafePointer.create(pointers[1])), + traceback = new PyObject(Deno.UnsafePointer.create(pointers[2])); let errorMessage = (value ?? type).toString() ?? "Unknown error"; if (!traceback.isNone) { @@ -880,7 +895,7 @@ export class Python { ) .handle, ); - if (module === 0) { + if (module === null) { throw new PythonError("Failed to run module"); } return new PyObject(module)?.proxy; @@ -891,7 +906,7 @@ export class Python { */ importObject(name: string) { const mod = py.PyImport_ImportModule(cstr(name)); - if (mod === 0) { + if (mod === null) { maybeThrowError(); throw new PythonError(`Failed to import module ${name}`); } @@ -949,7 +964,7 @@ function toSlice(sliceList: string): PyObject { const pyTuple_Pack = new Deno.UnsafeFnPointer( // TODO: this isn't really a `bigint`, but Deno's type definitions // haven't been updated to support `number` yet - py.PyTuple_Pack as bigint, + py.PyTuple_Pack!, { parameters: ["i32", ...pySlicesHandle.map(() => "pointer" as const)], result: "pointer", diff --git a/src/util.ts b/src/util.ts index 9a88a7b..a4a6101 100644 --- a/src/util.ts +++ b/src/util.ts @@ -22,7 +22,7 @@ export function postSetup(lib: string) { gnu_get_libc_version: { parameters: [], result: "pointer" }, }); const ptrView = new Deno.UnsafePointerView( - BigInt(libc.symbols.gnu_get_libc_version()), + libc.symbols.gnu_get_libc_version()!, ); const glibcVersion = parseFloat(ptrView.getCString()); diff --git a/test/deps.ts b/test/deps.ts index 70cc439..8afbb88 100644 --- a/test/deps.ts +++ b/test/deps.ts @@ -1 +1 @@ -export * from "https://deno.land/std@0.139.0/testing/asserts.ts"; +export * from "https://deno.land/std@0.178.0/testing/asserts.ts";