diff --git a/src/py/libcamera/py_camera_manager.cpp b/src/py/libcamera/py_camera_manager.cpp
index 599a9f7e..dfd43a09 100644
--- a/src/py/libcamera/py_camera_manager.cpp
+++ b/src/py/libcamera/py_camera_manager.cpp
@@ -218,6 +218,36 @@ void PyCameraManager::discardEvents()
 	}
 }
 
+void PyCameraManager::discardRequests(std::shared_ptr<Camera> camera)
+{
+	MutexLocker guard(cameraEventsMutex_);
+
+	size_t oldSize = cameraEvents_.size();
+
+	for (const auto &ev : cameraEvents_) {
+		if (ev.type_ != CameraEvent::Type::RequestCompleted)
+			continue;
+
+		if (ev.camera_ != camera)
+			continue;
+
+		/* Decrease the ref increased in Camera.queue_request() */
+		py::object o = py::cast(ev.request_);
+		o.dec_ref();
+	}
+
+	cameraEvents_.erase(std::remove_if(cameraEvents_.begin(), cameraEvents_.end(),
+		[&camera](const CameraEvent &ev) {
+			return ev.camera_ == camera &&
+				(ev.type_ == CameraEvent::Type::RequestCompleted ||
+				 ev.type_ == CameraEvent::Type::BufferCompleted);
+		}),
+		cameraEvents_.end());
+
+	LOG(Python, Debug) << "Discarded " << oldSize - cameraEvents_.size()
+			   << " request events";
+}
+
 std::function<void(std::shared_ptr<Camera>)> PyCameraManager::getCameraAdded() const
 {
 	return cameraAddedHandler_;
diff --git a/src/py/libcamera/py_camera_manager.h b/src/py/libcamera/py_camera_manager.h
index aa51a6bc..9c8d6ca8 100644
--- a/src/py/libcamera/py_camera_manager.h
+++ b/src/py/libcamera/py_camera_manager.h
@@ -38,6 +38,7 @@ public:
 
 	void dispatchEvents();
 	void discardEvents();
+	void discardRequests(std::shared_ptr<Camera> camera);
 
 	std::function<void(std::shared_ptr<Camera>)> getCameraAdded() const;
 	void setCameraAdded(std::function<void(std::shared_ptr<Camera>)> func);
diff --git a/src/py/libcamera/py_main.cpp b/src/py/libcamera/py_main.cpp
index a07f06c4..c4755bea 100644
--- a/src/py/libcamera/py_main.cpp
+++ b/src/py/libcamera/py_main.cpp
@@ -168,16 +168,24 @@ PYBIND11_MODULE(_libcamera, m)
 			}
 		}, py::arg("controls") = std::unordered_map<const ControlId *, py::object>())
 
-		.def("stop", [](Camera &self) {
+		.def("stop", [](Camera &self, bool dispatchEvents) {
 			int ret = self.stop();
 
 			self.requestCompleted.disconnect();
 
+			auto cm = gCameraManager.lock();
+			ASSERT(cm);
+
+			if (dispatchEvents)
+				cm->dispatchEvents();
+			else
+				cm->discardRequests(self.shared_from_this());
+
 			/* \todo Should we just ignore the error? */
 			if (ret)
 				throw std::system_error(-ret, std::generic_category(),
 				                        "Failed to start camera");
-		})
+		}, py::arg("dispatch_events") = false)
 
 		.def_property("request_completed",
 		[](Camera &self) {
