bindings/python: Update PyO3 dependency to 0.24.0

This commit is contained in:
Pekka Enberg 2025-03-15 08:30:15 +02:00
parent 731fbaf3c7
commit a81ed4a523
3 changed files with 51 additions and 82 deletions

24
Cargo.lock generated
View file

@ -2432,9 +2432,9 @@ dependencies = [
[[package]]
name = "pyo3"
version = "0.22.6"
version = "0.24.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f402062616ab18202ae8319da13fa4279883a2b8a9d9f83f20dbade813ce1884"
checksum = "7f1c6c3591120564d64db2261bec5f910ae454f01def849b9c22835a84695e86"
dependencies = [
"anyhow",
"cfg-if",
@ -2451,9 +2451,9 @@ dependencies = [
[[package]]
name = "pyo3-build-config"
version = "0.22.6"
version = "0.24.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b14b5775b5ff446dd1056212d778012cbe8a0fbffd368029fd9e25b514479c38"
checksum = "e9b6c2b34cf71427ea37c7001aefbaeb85886a074795e35f161f5aecc7620a7a"
dependencies = [
"once_cell",
"target-lexicon",
@ -2461,9 +2461,9 @@ dependencies = [
[[package]]
name = "pyo3-ffi"
version = "0.22.6"
version = "0.24.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9ab5bcf04a2cdcbb50c7d6105de943f543f9ed92af55818fd17b660390fc8636"
checksum = "5507651906a46432cdda02cd02dd0319f6064f1374c9147c45b978621d2c3a9c"
dependencies = [
"libc",
"pyo3-build-config",
@ -2471,9 +2471,9 @@ dependencies = [
[[package]]
name = "pyo3-macros"
version = "0.22.6"
version = "0.24.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0fd24d897903a9e6d80b968368a34e1525aeb719d568dba8b3d4bfa5dc67d453"
checksum = "b0d394b5b4fd8d97d48336bb0dd2aebabad39f1d294edd6bcd2cccf2eefe6f42"
dependencies = [
"proc-macro2",
"pyo3-macros-backend",
@ -2483,9 +2483,9 @@ dependencies = [
[[package]]
name = "pyo3-macros-backend"
version = "0.22.6"
version = "0.24.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "36c011a03ba1e50152b4b394b479826cad97e7a21eb52df179cd91ac411cbfbe"
checksum = "fd72da09cfa943b1080f621f024d2ef7e2773df7badd51aa30a2be1f8caa7c8e"
dependencies = [
"heck",
"proc-macro2",
@ -3104,9 +3104,9 @@ dependencies = [
[[package]]
name = "target-lexicon"
version = "0.12.16"
version = "0.13.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "61c41af27dd6d1e27b1b16b489db798443478cef1f06a660c96db617ba5de3b1"
checksum = "e502f78cdbb8ba4718f566c418c52bc729126ffd16baee5baa718cf25dd5a69a"
[[package]]
name = "tempfile"

View file

@ -18,9 +18,9 @@ extension-module = ["pyo3/extension-module"]
[dependencies]
anyhow = "1.0"
limbo_core = { path = "../../core", features = ["io_uring"] }
pyo3 = { version = "0.22.4", features = ["anyhow"] }
pyo3 = { version = "0.24.0", features = ["anyhow"] }
[build-dependencies]
version_check = "0.9.5"
# used where logic has to be version/distribution specific, e.g. pypy
pyo3-build-config = { version = "0.22.4" }
pyo3-build-config = { version = "0.24.0" }

View file

@ -1,8 +1,7 @@
use anyhow::Result;
use errors::*;
use pyo3::prelude::*;
use pyo3::types::PyList;
use pyo3::types::PyTuple;
use pyo3::types::{PyBytes, PyList, PyTuple};
use std::cell::RefCell;
use std::rc::Rc;
use std::sync::Arc;
@ -28,25 +27,7 @@ struct Description {
null_ok: Option<String>,
}
impl IntoPy<Py<PyTuple>> for Description {
fn into_py(self, py: Python<'_>) -> Py<PyTuple> {
PyTuple::new_bound(
py,
vec![
self.name.into_py(py),
self.type_code.into_py(py),
self.display_size.into_py(py),
self.internal_size.into_py(py),
self.precision.into_py(py),
self.scale.into_py(py),
self.null_ok.into_py(py),
],
)
.into()
}
}
#[pyclass]
#[pyclass(unsendable)]
pub struct Cursor {
/// This read/write attribute specifies the number of rows to fetch at a time with `.fetchmany()`.
/// It defaults to `1`, meaning it fetches a single row at a time.
@ -81,8 +62,12 @@ pub struct Cursor {
smt: Option<Rc<RefCell<limbo_core::Statement>>>,
}
// SAFETY: The limbo_core crate guarantees that `Cursor` is thread-safe.
unsafe impl Send for Cursor {}
#[pyclass(unsendable)]
#[derive(Clone)]
pub struct Connection {
conn: Rc<limbo_core::Connection>,
io: Arc<dyn limbo_core::IO>,
}
#[allow(unused_variables, clippy::arc_with_non_send_sync)]
#[pymethods]
@ -135,7 +120,7 @@ impl Cursor {
})? {
limbo_core::StepResult::Row => {
let row = stmt.row().unwrap();
let py_row = row_to_py(py, &row);
let py_row = row_to_py(py, &row)?;
return Ok(Some(py_row));
}
limbo_core::StepResult::IO => {
@ -171,7 +156,7 @@ impl Cursor {
})? {
limbo_core::StepResult::Row => {
let row = stmt.row().unwrap();
let py_row = row_to_py(py, &row);
let py_row = row_to_py(py, &row)?;
results.push(py_row);
}
limbo_core::StepResult::IO => {
@ -230,16 +215,6 @@ fn stmt_is_ddl(sql: &str) -> bool {
sql.starts_with("CREATE") || sql.starts_with("ALTER") || sql.starts_with("DROP")
}
#[pyclass]
#[derive(Clone)]
pub struct Connection {
conn: Rc<limbo_core::Connection>,
io: Arc<dyn limbo_core::IO>,
}
// SAFETY: The limbo_core crate guarantees that `Connection` is thread-safe.
unsafe impl Send for Connection {}
#[pymethods]
impl Connection {
pub fn cursor(&self) -> Result<Cursor> {
@ -298,21 +273,24 @@ pub fn connect(path: &str) -> Result<Connection> {
}
}
fn row_to_py(py: Python, row: &limbo_core::Row) -> PyObject {
let py_values: Vec<PyObject> = row
.get_values()
.iter()
.map(|value| match value {
limbo_core::OwnedValue::Null => py.None(),
limbo_core::OwnedValue::Integer(i) => i.to_object(py),
limbo_core::OwnedValue::Float(f) => f.to_object(py),
limbo_core::OwnedValue::Text(s) => s.as_str().to_object(py),
limbo_core::OwnedValue::Blob(b) => b.to_object(py),
fn row_to_py(py: Python, row: &limbo_core::Row) -> Result<PyObject> {
let mut py_values = Vec::new();
for value in row.get_values() {
match value {
limbo_core::OwnedValue::Null => py_values.push(py.None()),
limbo_core::OwnedValue::Integer(i) => py_values.push(i.into_pyobject(py)?.into()),
limbo_core::OwnedValue::Float(f) => py_values.push(f.into_pyobject(py)?.into()),
limbo_core::OwnedValue::Text(s) => py_values.push(s.as_str().into_pyobject(py)?.into()),
limbo_core::OwnedValue::Blob(b) => {
py_values.push(PyBytes::new(py, b.as_slice()).into())
}
_ => unreachable!(),
})
.collect();
PyTuple::new_bound(py, &py_values).to_object(py)
}
}
Ok(PyTuple::new(py, &py_values)
.unwrap()
.into_pyobject(py)?
.into())
}
#[pymodule]
@ -321,24 +299,15 @@ fn _limbo(m: &Bound<PyModule>) -> PyResult<()> {
m.add_class::<Connection>()?;
m.add_class::<Cursor>()?;
m.add_function(wrap_pyfunction!(connect, m)?)?;
m.add("Warning", m.py().get_type_bound::<Warning>())?;
m.add("Error", m.py().get_type_bound::<Error>())?;
m.add("InterfaceError", m.py().get_type_bound::<InterfaceError>())?;
m.add("DatabaseError", m.py().get_type_bound::<DatabaseError>())?;
m.add("DataError", m.py().get_type_bound::<DataError>())?;
m.add(
"OperationalError",
m.py().get_type_bound::<OperationalError>(),
)?;
m.add("IntegrityError", m.py().get_type_bound::<IntegrityError>())?;
m.add("InternalError", m.py().get_type_bound::<InternalError>())?;
m.add(
"ProgrammingError",
m.py().get_type_bound::<ProgrammingError>(),
)?;
m.add(
"NotSupportedError",
m.py().get_type_bound::<NotSupportedError>(),
)?;
m.add("Warning", m.py().get_type::<Warning>())?;
m.add("Error", m.py().get_type::<Error>())?;
m.add("InterfaceError", m.py().get_type::<InterfaceError>())?;
m.add("DatabaseError", m.py().get_type::<DatabaseError>())?;
m.add("DataError", m.py().get_type::<DataError>())?;
m.add("OperationalError", m.py().get_type::<OperationalError>())?;
m.add("IntegrityError", m.py().get_type::<IntegrityError>())?;
m.add("InternalError", m.py().get_type::<InternalError>())?;
m.add("ProgrammingError", m.py().get_type::<ProgrammingError>())?;
m.add("NotSupportedError", m.py().get_type::<NotSupportedError>())?;
Ok(())
}