feat(python): switched to abi3 mode to allow multiple python versions with single wheel.

abi3 does not support `PyFunction` so added workaround checking for `is_callable()`
This commit is contained in:
cschen 2024-09-06 00:24:37 +02:00
parent e946ee195b
commit c1c9902b45
4 changed files with 33 additions and 27 deletions

View file

@ -50,7 +50,7 @@ napi = { version = "2.16", features = ["full"], optional = true }
napi-derive = { version="2.16", optional = true} napi-derive = { version="2.16", optional = true}
# glue (python) # glue (python)
pyo3 = { version = "0.22", features = ["extension-module", "experimental-async"], optional = true} pyo3 = { version = "0.22", features = ["extension-module", "abi3-py38"], optional = true}
# extra # extra
async-trait = { version = "0.1", optional = true } async-trait = { version = "0.1", optional = true }

View file

@ -1,18 +1,18 @@
[project] [project]
name = "codemp" name = "codemp"
version = "0.0.1" version = "0.0.5"
description = "code multiplexer" description = "code multiplexer"
requires-python = ">=3.8" requires-python = ">= 3.8"
license = "GPL-3.0-only" license = "GPL-3.0-only"
keywords = ["codemp", "cooperative", "rust", "python"] keywords = ["codemp", "cooperative", "rust", "python"]
authors = [ authors = [
{ name = "Camillo Schenone", email = "cschen@codemp.dev" }, { name = "cschen", email = "cschen@codemp.dev" },
{ name = "alemi", email = "me@alemi.dev" }, { name = "alemi", email = "me@alemi.dev" },
{ name = "zaaarf", email = "me@zaaarf.foo" }, { name = "zaaarf", email = "me@zaaarf.foo" },
{ name = "frelodev", email = "frelodev@gmail.com" }, { name = "frelodev", email = "frelodev@gmail.com" },
] ]
maintainers = [ maintainers = [
{ name = "Camillo Schenone", email = "cschen@codemp.dev" }, { name = "cschen", email = "cschen@codemp.dev" },
] ]
classifiers = [ classifiers = [
"Programming Language :: Python" "Programming Language :: Python"

View file

@ -3,8 +3,8 @@ use crate::api::Cursor;
use crate::api::TextChange; use crate::api::TextChange;
use crate::buffer::Controller as BufferController; use crate::buffer::Controller as BufferController;
use crate::cursor::Controller as CursorController; use crate::cursor::Controller as CursorController;
use pyo3::exceptions::PyValueError;
use pyo3::prelude::*; use pyo3::prelude::*;
use pyo3::types::PyFunction;
use super::Promise; use super::Promise;
use crate::a_sync_allow_threads; use crate::a_sync_allow_threads;
@ -49,15 +49,18 @@ impl CursorController {
} }
#[pyo3(name = "callback")] #[pyo3(name = "callback")]
fn pycallback(&self, py: Python, cb: Py<PyFunction>) { fn pycallback(&self, py: Python, cb: PyObject) -> PyResult<()> {
py.allow_threads(move || { if !cb.bind_borrowed(py).is_callable() {
self.callback(move |ctl| { return Err(PyValueError::new_err("The object passed must be callable."));
Python::with_gil(|py| { }
// TODO what to do with this error?
let _ = cb.call1(py, (ctl,)); self.callback(move |ctl| {
}) Python::with_gil(|py| {
// TODO what to do with this error?
let _ = cb.call1(py, (ctl,));
}) })
}) });
Ok(())
} }
#[pyo3(name = "clear_callback")] #[pyo3(name = "clear_callback")]
@ -116,15 +119,18 @@ impl BufferController {
} }
#[pyo3(name = "callback")] #[pyo3(name = "callback")]
fn pycallback(&self, py: Python, cb: Py<PyFunction>) { fn pycallback(&self, py: Python, cb: PyObject) -> PyResult<()> {
py.allow_threads(move || { if !cb.bind_borrowed(py).is_callable() {
self.callback(move |ctl| { return Err(PyValueError::new_err("The object passed must be callable."));
Python::with_gil(|py| { }
// TODO what to do with this error?
let _ = cb.call1(py, (ctl,)); self.callback(move |ctl| {
}) Python::with_gil(|py| {
// TODO what to do with this error?
let _ = cb.call1(py, (ctl,));
}) })
}) });
Ok(())
} }
#[pyo3(name = "clear_callback")] #[pyo3(name = "clear_callback")]

View file

@ -13,11 +13,8 @@ use crate::{
Client, Workspace, Client, Workspace,
}; };
use pyo3::exceptions::{PyConnectionError, PyRuntimeError, PySystemError};
use pyo3::prelude::*; use pyo3::prelude::*;
use pyo3::{
exceptions::{PyConnectionError, PyRuntimeError, PySystemError},
types::PyFunction,
};
use std::sync::OnceLock; use std::sync::OnceLock;
use tokio::sync::{mpsc, oneshot}; use tokio::sync::{mpsc, oneshot};
@ -158,7 +155,10 @@ fn connect(host: String, username: String, password: String) -> PyResult<Promise
} }
#[pyfunction] #[pyfunction]
fn set_logger(logging_cb: Py<PyFunction>, debug: bool) -> bool { fn set_logger(py: Python, logging_cb: PyObject, debug: bool) -> bool {
if !logging_cb.bind_borrowed(py).is_callable() {
return false;
}
let (tx, mut rx) = mpsc::unbounded_channel(); let (tx, mut rx) = mpsc::unbounded_channel();
let level = if debug { let level = if debug {
tracing::Level::DEBUG tracing::Level::DEBUG