Fix file writing for python

This commit is contained in:
2026-04-26 18:04:43 +01:00
parent bb76afac4f
commit aae997fc41
3 changed files with 20 additions and 5 deletions

View File

@@ -4,7 +4,7 @@ build-backend = "maturin"
[project] [project]
name = "slingshot-microservice" name = "slingshot-microservice"
version = "0.1.3" version = "0.1.4"
description = "Opinionated Rust framework for queue-driven microservices" description = "Opinionated Rust framework for queue-driven microservices"
license = { text = "MIT" } license = { text = "MIT" }
requires-python = ">=3.8" requires-python = ">=3.8"

View File

@@ -15,7 +15,12 @@ class ReadFileFn(Protocol):
class WriteFileFn(Protocol): class WriteFileFn(Protocol):
def __call__(self, key: str, id: int) -> BinaryIO: ... def __call__(self, key: str, id: int) -> "WriteHandle": ...
class WriteHandle(Protocol):
def write(self, data: bytes | str) -> int: ...
def flush(self) -> None: ...
class ProcessFn(Protocol): class ProcessFn(Protocol):
@@ -31,6 +36,7 @@ class ProcessFn(Protocol):
__all__ = [ __all__ = [
"CaseVariable", "CaseVariable",
"ReadFileFn", "ReadFileFn",
"WriteHandle",
"WriteFileFn", "WriteFileFn",
"ProcessFn", "ProcessFn",
] ]

View File

@@ -802,14 +802,23 @@ struct PyWriteHandle {
#[cfg(feature = "python")] #[cfg(feature = "python")]
#[pymethods] #[pymethods]
impl PyWriteHandle { impl PyWriteHandle {
fn write(&self, data: &[u8]) -> PyResult<usize> { fn write(&self, data: &Bound<'_, PyAny>) -> PyResult<usize> {
let (buffer, chars_written) = if let Ok(bytes) = data.extract::<Vec<u8>>() {
(bytes, None)
} else if let Ok(text) = data.extract::<String>() {
let char_count = text.chars().count();
(text.into_bytes(), Some(char_count))
} else {
return Err(PyTypeError::new_err("write() argument must be bytes or str"));
};
let mut file = self let mut file = self
.file .file
.lock() .lock()
.map_err(|e| PyRuntimeError::new_err(format!("write lock poisoned: {}", e)))?; .map_err(|e| PyRuntimeError::new_err(format!("write lock poisoned: {}", e)))?;
file.write_all(data) file.write_all(&buffer)
.map_err(|e| PyRuntimeError::new_err(e.to_string()))?; .map_err(|e| PyRuntimeError::new_err(e.to_string()))?;
Ok(data.len()) Ok(chars_written.unwrap_or(buffer.len()))
} }
fn flush(&self) -> PyResult<()> { fn flush(&self) -> PyResult<()> {