Add Python typings for Rust declared types (#7575)

This comes with a bump of the Python version to 3.11
due to the need for typing.Self.
This commit is contained in:
Simon Hausmann 2025-02-09 16:06:34 +01:00 committed by GitHub
parent 30aefd4957
commit 94c655731f
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
11 changed files with 207 additions and 8 deletions

View file

@ -15,7 +15,11 @@ rust-version.workspace = true
[lib]
path = "lib.rs"
crate-type = ["cdylib"]
crate-type = ["cdylib", "rlib"]
[[bin]]
name = "stub-gen"
path = "stub-gen/main.rs"
[features]
default = ["backend-winit", "renderer-femtovg", "renderer-software", "backend-qt", "accessibility"]
@ -46,6 +50,7 @@ indexmap = { version = "2.1.0" }
chrono = "0.4"
spin_on = { workspace = true }
css-color-parser2 = { workspace = true }
pyo3-stub-gen = { version = "0.7.0", default-features = false }
[package.metadata.maturin]
python-source = "slint"

View file

@ -2,9 +2,36 @@
// SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-Slint-Royalty-free-2.0 OR LicenseRef-Slint-Software-3.0
use pyo3::prelude::*;
use pyo3_stub_gen::{derive::gen_stub_pyclass, derive::gen_stub_pymethods, impl_stub_type};
use crate::errors::PyColorParseError;
#[gen_stub_pyclass]
#[pyclass]
#[derive(FromPyObject)]
struct RgbaColor {
#[pyo3(get, set)]
red: u8,
#[pyo3(get, set)]
green: u8,
#[pyo3(get, set)]
blue: u8,
#[pyo3(get, set)]
alpha: u8,
}
#[gen_stub_pyclass]
#[pyclass]
#[derive(FromPyObject)]
struct RgbColor {
#[pyo3(get, set)]
red: u8,
#[pyo3(get, set)]
green: u8,
#[pyo3(get, set)]
blue: u8,
}
#[derive(FromPyObject)]
enum PyColorInput {
ColorStr(String),
@ -29,12 +56,16 @@ enum PyColorInput {
},
}
impl_stub_type!(PyColorInput = String | RgbaColor | RgbColor);
#[gen_stub_pyclass]
#[pyclass(name = "Color")]
#[derive(Clone)]
pub struct PyColor {
pub color: slint_interpreter::Color,
}
#[gen_stub_pymethods]
#[pymethods]
impl PyColor {
#[new]
@ -124,11 +155,15 @@ enum PyBrushInput {
SolidColor(PyColor),
}
impl_stub_type!(PyBrushInput = PyColor);
#[gen_stub_pyclass]
#[pyclass(name = "Brush")]
pub struct PyBrush {
pub brush: slint_interpreter::Brush,
}
#[gen_stub_pymethods]
#[pymethods]
impl PyBrush {
#[new]

View file

@ -2,14 +2,17 @@
// SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-Slint-Royalty-free-2.0 OR LicenseRef-Slint-Software-3.0
use pyo3::prelude::*;
use pyo3_stub_gen::{derive::gen_stub_pyclass, derive::gen_stub_pymethods};
/// Image objects can be set on Slint Image elements for display. Construct Image objects from a path to an
/// image file on disk, using `Image.load_from_path`.
#[gen_stub_pyclass]
#[pyclass(unsendable, name = "Image")]
pub struct PyImage {
pub image: slint_interpreter::Image,
}
#[gen_stub_pymethods]
#[pymethods]
impl PyImage {
#[new]
@ -37,8 +40,8 @@ impl PyImage {
/// The path of the image if it was loaded from disk, or None.
#[getter]
fn path(&self) -> PyResult<Option<&std::path::Path>> {
Ok(self.image.path())
fn path(&self) -> PyResult<Option<std::path::PathBuf>> {
Ok(self.image.path().map(|p| p.to_path_buf()))
}
/// Loads the image from the specified path. Returns None if the image can't be loaded.
@ -50,8 +53,8 @@ impl PyImage {
/// Creates a new image from a string that describes the image in SVG format.
#[staticmethod]
fn load_from_svg_data(data: &[u8]) -> Result<Self, crate::errors::PyLoadImageError> {
let image = slint_interpreter::Image::load_from_svg_data(data)?;
fn load_from_svg_data(data: Vec<u8>) -> Result<Self, crate::errors::PyLoadImageError> {
let image = slint_interpreter::Image::load_from_svg_data(&data)?;
Ok(Self { image })
}
}

View file

@ -1,6 +1,8 @@
// Copyright © SixtyFPS GmbH <info@slint.dev>
// SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-Slint-Royalty-free-2.0 OR LicenseRef-Slint-Software-3.0
use pyo3_stub_gen::define_stub_info_gatherer;
mod image;
mod interpreter;
use interpreter::{CompilationResult, Compiler, PyDiagnostic, PyDiagnosticLevel, PyValueType};
@ -53,3 +55,5 @@ fn slint(_py: Python<'_>, m: &Bound<'_, PyModule>) -> PyResult<()> {
Ok(())
}
define_stub_info_gatherer!(stub_info);

View file

@ -3,7 +3,7 @@
import nox
@nox.session(python="3.10")
@nox.session(python="3.11")
def python(session: nox.Session):
session.env["MATURIN_PEP517_ARGS"] = "--profile=dev"
session.install(".[dev]")

View file

@ -8,7 +8,7 @@ build-backend = "maturin"
[project]
name = "slint"
version = "1.10.0a1"
requires-python = ">= 3.10"
requires-python = ">= 3.11"
authors = [
{name = "Slint Team", email = "info@slint.dev"},
]

View file

@ -0,0 +1,134 @@
# Copyright © SixtyFPS GmbH <info@slint.dev>
# SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-Slint-Royalty-free-2.0 OR LicenseRef-Slint-Software-3.0
# This file is automatically generated by pyo3_stub_gen
# ruff: noqa: E501, F401
import builtins
import datetime
import os
import pathlib
import typing
from typing import Self
from enum import Enum, auto
class RgbColor:
red: builtins.int
green: builtins.int
blue: builtins.int
class RgbaColor:
red: builtins.int
green: builtins.int
blue: builtins.int
alpha: builtins.int
class Color:
red: builtins.int
green: builtins.int
blue: builtins.int
alpha: builtins.int
def __new__(cls,maybe_value:typing.Optional[builtins.str | RgbaColor | RgbColor]): ...
def brighter(self, factor:builtins.float) -> Self:
...
def darker(self, factor:builtins.float) -> Self:
...
def transparentize(self, factor:builtins.float) -> Self:
...
def mix(self, other:Self, factor:builtins.float) -> Self:
...
def with_alpha(self, alpha:builtins.float) -> Self:
...
def __str__(self) -> builtins.str:
...
def __eq__(self, other:Self) -> builtins.bool:
...
class Brush:
color: Color
def __new__(cls,maybe_value:typing.Optional[Color]): ...
def is_transparent(self) -> builtins.bool:
...
def is_opaque(self) -> builtins.bool:
...
def brighter(self, factor:builtins.float) -> Self:
...
def darker(self, factor:builtins.float) -> Self:
...
def transparentize(self, amount:builtins.float) -> Self:
...
def with_alpha(self, alpha:builtins.float) -> Self:
...
def __eq__(self, other:Self) -> builtins.bool:
...
class Image:
r"""
Image objects can be set on Slint Image elements for display. Construct Image objects from a path to an
image file on disk, using `Image.load_from_path`.
"""
size: tuple[builtins.int, builtins.int]
width: builtins.int
height: builtins.int
path: typing.Optional[builtins.str]
def __new__(cls,): ...
@staticmethod
def load_from_path(path:builtins.str | os.PathLike | pathlib.Path) -> Self:
r"""
Loads the image from the specified path. Returns None if the image can't be loaded.
"""
...
@staticmethod
def load_from_svg_data(data:typing.Sequence[builtins.int]) -> Self:
r"""
Creates a new image from a string that describes the image in SVG format.
"""
...
class TimerMode(Enum):
SingleShot = auto()
Repeated = auto()
class Timer:
def __new__(cls,): ...
def start(self, mode:TimerMode, interval:datetime.timedelta, callback:typing.Any) -> None:
...
@staticmethod
def single_shot(duration:datetime.timedelta, callback:typing.Any) -> None:
...
def stop(self) -> None:
...
def restart(self) -> None:
...
def running(self) -> builtins.bool:
...
def set_interval(self, interval:datetime.timedelta) -> None:
...

View file

@ -0,0 +1,11 @@
// Copyright © SixtyFPS GmbH <info@slint.dev>
// SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-Slint-Royalty-free-2.0 OR LicenseRef-Slint-Software-3.0
use pyo3_stub_gen::Result;
fn main() -> Result<()> {
// `stub_info` is a function defined by `define_stub_info_gatherer!` macro.
let stub = slint_python::stub_info()?;
stub.generate()?;
Ok(())
}

View file

@ -2,8 +2,12 @@
// SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-Slint-Royalty-free-2.0 OR LicenseRef-Slint-Software-3.0
use pyo3::prelude::*;
use pyo3_stub_gen::{
derive::gen_stub_pyclass, derive::gen_stub_pyclass_enum, derive::gen_stub_pymethods,
};
#[derive(Copy, Clone)]
#[gen_stub_pyclass_enum]
#[pyclass(name = "TimerMode")]
pub enum PyTimerMode {
/// A SingleShot timer is fired only once.
@ -21,11 +25,13 @@ impl From<PyTimerMode> for i_slint_core::timers::TimerMode {
}
}
#[gen_stub_pyclass]
#[pyclass(name = "Timer", unsendable)]
pub struct PyTimer {
timer: i_slint_core::timers::Timer,
}
#[gen_stub_pymethods]
#[pymethods]
impl PyTimer {
#[new]