Upgrade to PyO3 0.23

This commit is contained in:
Simon Hausmann 2025-04-03 10:55:55 +02:00 committed by Simon Hausmann
parent ad74c31ed4
commit 0c51f69b0a
6 changed files with 45 additions and 39 deletions

View file

@ -55,7 +55,7 @@ slint-interpreter = { workspace = true, features = [
"internal",
] }
i-slint-compiler = { workspace = true }
pyo3 = { version = "0.22", features = [
pyo3 = { version = "0.23", features = [
"extension-module",
"indexmap",
"chrono",

View file

@ -33,6 +33,7 @@ struct RgbColor {
}
#[derive(FromPyObject)]
#[pyclass]
enum PyColorInput {
ColorStr(String),
// This variant must come before RgbColor
@ -73,6 +74,7 @@ pub struct PyColor {
#[pymethods]
impl PyColor {
#[new]
#[pyo3(signature = (maybe_value=None))]
fn py_new(maybe_value: Option<PyColorInput>) -> PyResult<Self> {
let Some(value) = maybe_value else {
return Ok(Self { color: Default::default() });
@ -168,6 +170,7 @@ impl From<slint_interpreter::Color> for PyColor {
}
#[derive(FromPyObject)]
#[pyclass]
enum PyBrushInput {
SolidColor(PyColor),
}
@ -191,6 +194,7 @@ pub struct PyBrush {
#[pymethods]
impl PyBrush {
#[new]
#[pyo3(signature = (maybe_value=None))]
fn py_new(maybe_value: Option<PyBrushInput>) -> PyResult<Self> {
let Some(value) = maybe_value else {
return Ok(Self { brush: Default::default() });

View file

@ -6,6 +6,7 @@ use std::collections::HashMap;
use std::path::PathBuf;
use std::rc::Rc;
use pyo3::IntoPyObjectExt;
use pyo3_stub_gen::derive::{gen_stub_pyclass, gen_stub_pyclass_enum, gen_stub_pymethods};
use slint_interpreter::{ComponentHandle, Value};
@ -125,7 +126,8 @@ impl PyDiagnostic {
}
#[gen_stub_pyclass_enum]
#[pyclass(name = "DiagnosticLevel")]
#[pyclass(name = "DiagnosticLevel", eq, eq_int)]
#[derive(PartialEq)]
pub enum PyDiagnosticLevel {
Error,
Warning,
@ -155,11 +157,11 @@ impl CompilationResult {
}
#[getter]
fn structs_and_enums(&self, py: Python<'_>) -> HashMap<String, PyObject> {
fn structs_and_enums<'py>(&self, py: Python<'py>) -> HashMap<String, Bound<'py, PyAny>> {
let structs_and_enums =
self.result.structs_and_enums(i_slint_core::InternalToken {}).collect::<Vec<_>>();
fn convert_type(py: Python<'_>, ty: &Type) -> Option<(String, PyObject)> {
fn convert_type<'py>(py: Python<'py>, ty: &Type) -> Option<(String, Bound<'py, PyAny>)> {
match ty {
Type::Struct(s) if s.name.is_some() && s.node.is_some() => {
let struct_instance = PyStruct::from(slint_interpreter::Struct::from_iter(
@ -173,7 +175,7 @@ impl CompilationResult {
return Some((
s.name.as_ref().unwrap().to_string(),
struct_instance.into_py(py),
struct_instance.into_bound_py_any(py).unwrap(),
));
}
Type::Enumeration(_en) => {
@ -188,7 +190,7 @@ impl CompilationResult {
.iter()
.filter_map(|ty| convert_type(py, ty))
.into_iter()
.collect::<HashMap<String, PyObject>>()
.collect::<HashMap<String, Bound<'py, PyAny>>>()
}
#[getter]
@ -254,7 +256,8 @@ impl ComponentDefinition {
}
#[gen_stub_pyclass_enum]
#[pyclass(name = "ValueType")]
#[pyclass(name = "ValueType", eq, eq_int)]
#[derive(PartialEq)]
pub enum PyValueType {
Void,
Number,
@ -416,8 +419,8 @@ impl GcVisibleCallbacks {
let callables = callables.borrow();
let callable = callables.get(&name).unwrap();
Python::with_gil(|py| {
let py_args = PyTuple::new_bound(py, args.iter().map(|v| PyValue(v.clone())));
let result = match callable.call_bound(py, py_args, None) {
let py_args = PyTuple::new(py, args.iter().map(|v| PyValue(v.clone()))).unwrap();
let result = match callable.call(py, py_args, None) {
Ok(result) => result,
Err(err) => {
eprintln!(

View file

@ -158,9 +158,9 @@ impl PyModelShared {
pub fn rust_into_js_model<'py>(
model: &ModelRc<slint_interpreter::Value>,
py: Python<'py>,
) -> Option<PyObject> {
) -> Option<Bound<'py, PyAny>> {
model.as_any().downcast_ref::<PyModelShared>().and_then(|rust_model| {
rust_model.self_ref.borrow().as_ref().map(|obj| obj.clone_ref(py))
rust_model.self_ref.borrow().as_ref().map(|obj| obj.clone_ref(py).into_bound(py))
})
}
}

View file

@ -11,7 +11,8 @@ use pyo3_stub_gen::{
/// Used by the `Timer.start()` function.
#[derive(Copy, Clone)]
#[gen_stub_pyclass_enum]
#[pyclass(name = "TimerMode")]
#[pyclass(name = "TimerMode", eq, eq_int)]
#[derive(PartialEq)]
pub enum PyTimerMode {
/// A SingleShot timer is fired only once.
SingleShot,

View file

@ -3,6 +3,7 @@
use pyo3::prelude::*;
use pyo3::types::PyDict;
use pyo3::IntoPyObjectExt;
use pyo3_stub_gen::{derive::gen_stub_pyclass, derive::gen_stub_pymethods};
use std::collections::HashMap;
@ -11,49 +12,46 @@ use std::collections::HashMap;
pub struct PyValue(pub slint_interpreter::Value);
struct PyValueRef<'a>(&'a slint_interpreter::Value);
impl IntoPy<PyObject> for PyValue {
fn into_py(self, py: Python<'_>) -> PyObject {
impl<'py> IntoPyObject<'py> for PyValue {
type Target = PyAny;
type Output = Bound<'py, Self::Target>;
type Error = PyErr;
fn into_pyobject(self, py: Python<'py>) -> Result<Self::Output, Self::Error> {
// Share the conversion code below that operates on the reference
self.to_object(py).into_py(py)
PyValueRef(&self.0).into_pyobject(py)
}
}
impl ToPyObject for PyValue {
fn to_object(&self, py: Python<'_>) -> PyObject {
PyValueRef(&self.0).to_object(py)
}
}
impl<'a, 'py> IntoPyObject<'py> for PyValueRef<'a> {
type Target = PyAny;
type Output = Bound<'py, Self::Target>;
type Error = PyErr;
impl IntoPy<PyObject> for PyValueRef<'_> {
fn into_py(self, py: Python<'_>) -> PyObject {
// Share the conversion code below that operates on the reference
self.to_object(py).into_py(py)
}
}
impl ToPyObject for PyValueRef<'_> {
fn to_object(&self, py: Python<'_>) -> PyObject {
fn into_pyobject(self, py: Python<'py>) -> Result<Self::Output, Self::Error> {
match &self.0 {
slint_interpreter::Value::Void => ().into_py(py),
slint_interpreter::Value::Number(num) => num.into_py(py),
slint_interpreter::Value::String(str) => str.into_py(py),
slint_interpreter::Value::Bool(b) => b.into_py(py),
slint_interpreter::Value::Void => ().into_bound_py_any(py),
slint_interpreter::Value::Number(num) => num.into_bound_py_any(py),
slint_interpreter::Value::String(str) => str.into_bound_py_any(py),
slint_interpreter::Value::Bool(b) => b.into_bound_py_any(py),
slint_interpreter::Value::Image(image) => {
crate::image::PyImage::from(image).into_py(py)
crate::image::PyImage::from(image).into_bound_py_any(py)
}
slint_interpreter::Value::Model(model) => {
crate::models::PyModelShared::rust_into_js_model(model, py)
.unwrap_or_else(|| crate::models::ReadOnlyRustModel::from(model).into_py(py))
crate::models::PyModelShared::rust_into_js_model(model, py).map_or_else(
|| crate::models::ReadOnlyRustModel::from(model).into_bound_py_any(py),
|m| Ok(m),
)
}
slint_interpreter::Value::Struct(structval) => {
PyStruct { data: structval.clone() }.into_py(py)
PyStruct { data: structval.clone() }.into_bound_py_any(py)
}
slint_interpreter::Value::Brush(brush) => {
crate::brush::PyBrush::from(brush.clone()).into_py(py)
crate::brush::PyBrush::from(brush.clone()).into_bound_py_any(py)
}
v @ _ => {
eprintln!("Python: conversion from slint to python needed for {v:#?} and not implemented yet");
().into_py(py)
().into_bound_py_any(py)
}
}
}