[libcamera-devel,v4,14/15] py: Improve stub type generation for PyCameraEvent
diff mbox series

Message ID 20230309142601.70556-15-tomi.valkeinen@ideasonboard.com
State Superseded
Headers show
Series
  • py: New python bindings event handling
Related show

Commit Message

Tomi Valkeinen March 9, 2023, 2:26 p.m. UTC
We store the camera, request and fb fields in PyCameraEvent as
py::objects, so that we keep the refs and keep-alives. When we
return py::objects to the Python side, they, obviously, show up
as "objects" when the stub generation is looking at the fields.

Fix this by manually casting the py::objects to the correct C++
counterparts, which causes pybind11 to assign the correct types for the
properties, helpind stubgen to generate correct types.

Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>
---
 src/py/libcamera/py_main.cpp | 14 +++++++++++---
 1 file changed, 11 insertions(+), 3 deletions(-)

Comments

Laurent Pinchart March 12, 2023, 3:13 p.m. UTC | #1
Hi Tomi,

Thank you for the patch.

On Thu, Mar 09, 2023 at 04:26:00PM +0200, Tomi Valkeinen via libcamera-devel wrote:
> We store the camera, request and fb fields in PyCameraEvent as
> py::objects, so that we keep the refs and keep-alives. When we
> return py::objects to the Python side, they, obviously, show up
> as "objects" when the stub generation is looking at the fields.
> 
> Fix this by manually casting the py::objects to the correct C++
> counterparts, which causes pybind11 to assign the correct types for the
> properties, helpind stubgen to generate correct types.

s/helpind/helping/

> Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>

Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>

> ---
>  src/py/libcamera/py_main.cpp | 14 +++++++++++---
>  1 file changed, 11 insertions(+), 3 deletions(-)
> 
> diff --git a/src/py/libcamera/py_main.cpp b/src/py/libcamera/py_main.cpp
> index 1585b14a..cb7088b1 100644
> --- a/src/py/libcamera/py_main.cpp
> +++ b/src/py/libcamera/py_main.cpp
> @@ -100,11 +100,19 @@ PYBIND11_MODULE(_libcamera, m)
>  		.value("RequestCompleted", CameraEventType::RequestCompleted)
>  		.value("BufferCompleted", CameraEventType::BufferCompleted);
>  
> +	/*
> +	 * For camera, request and fb fields, manually typecast to the C++ type,
> +	 * so that pybind11 assigns the actual type for the return value. This
> +	 * makes the stubs generated by pybind11-stubgen contain the correct type,
> +	 * instead of "object".
> +	 *
> +	 * Maybe there's a better way to do this...
> +	 */
>  	pyEvent
>  		.def_readonly("type", &PyCameraEvent::type_)
> -		.def_readonly("camera", &PyCameraEvent::camera_)
> -		.def_readonly("request", &PyCameraEvent::request_)
> -		.def_readonly("fb", &PyCameraEvent::fb_);
> +		.def_property_readonly("camera", [](PyCameraEvent &self) { return self.camera_.cast<Camera *>(); })
> +		.def_property_readonly("request", [](PyCameraEvent &self) { return self.request_.cast<Request *>(); })
> +		.def_property_readonly("fb", [](PyCameraEvent &self) { return self.fb_.cast<FrameBuffer *>(); });
>  
>  	pyCameraManager
>  		.def_static("singleton", []() {

Patch
diff mbox series

diff --git a/src/py/libcamera/py_main.cpp b/src/py/libcamera/py_main.cpp
index 1585b14a..cb7088b1 100644
--- a/src/py/libcamera/py_main.cpp
+++ b/src/py/libcamera/py_main.cpp
@@ -100,11 +100,19 @@  PYBIND11_MODULE(_libcamera, m)
 		.value("RequestCompleted", CameraEventType::RequestCompleted)
 		.value("BufferCompleted", CameraEventType::BufferCompleted);
 
+	/*
+	 * For camera, request and fb fields, manually typecast to the C++ type,
+	 * so that pybind11 assigns the actual type for the return value. This
+	 * makes the stubs generated by pybind11-stubgen contain the correct type,
+	 * instead of "object".
+	 *
+	 * Maybe there's a better way to do this...
+	 */
 	pyEvent
 		.def_readonly("type", &PyCameraEvent::type_)
-		.def_readonly("camera", &PyCameraEvent::camera_)
-		.def_readonly("request", &PyCameraEvent::request_)
-		.def_readonly("fb", &PyCameraEvent::fb_);
+		.def_property_readonly("camera", [](PyCameraEvent &self) { return self.camera_.cast<Camera *>(); })
+		.def_property_readonly("request", [](PyCameraEvent &self) { return self.request_.cast<Request *>(); })
+		.def_property_readonly("fb", [](PyCameraEvent &self) { return self.fb_.cast<FrameBuffer *>(); });
 
 	pyCameraManager
 		.def_static("singleton", []() {