Skip to content

Commit 51f313b

Browse files
authored
Fix returning None from async functions (#245)
1 parent c8ac3a3 commit 51f313b

File tree

6 files changed

+33
-3
lines changed

6 files changed

+33
-3
lines changed

Diff for: obstore/src/copy.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@ use object_store::ObjectStore;
22
use pyo3::prelude::*;
33
use pyo3_object_store::{get_runtime, PyObjectStore, PyObjectStoreError, PyObjectStoreResult};
44

5+
use crate::utils::PyNone;
6+
57
#[pyfunction]
68
#[pyo3(signature = (store, from_, to, *, overwrite=true))]
79
pub(crate) fn copy(
@@ -43,6 +45,6 @@ pub(crate) fn copy_async(
4345
store.as_ref().copy_if_not_exists(&from_, &to)
4446
};
4547
fut.await.map_err(PyObjectStoreError::ObjectStoreError)?;
46-
Ok(())
48+
Ok(PyNone)
4749
})
4850
}

Diff for: obstore/src/delete.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ use pyo3::prelude::*;
33
use pyo3_object_store::{get_runtime, PyObjectStore, PyObjectStoreError, PyObjectStoreResult};
44

55
use crate::path::PyPaths;
6+
use crate::utils::PyNone;
67

78
#[pyfunction]
89
pub(crate) fn delete(py: Python, store: PyObjectStore, paths: PyPaths) -> PyObjectStoreResult<()> {
@@ -49,6 +50,6 @@ pub(crate) fn delete_async(
4950
.map_err(PyObjectStoreError::ObjectStoreError)?;
5051
}
5152
}
52-
Ok(())
53+
Ok(PyNone)
5354
})
5455
}

Diff for: obstore/src/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ mod put;
1313
mod rename;
1414
mod signer;
1515
mod tags;
16+
mod utils;
1617

1718
use pyo3::prelude::*;
1819

Diff for: obstore/src/rename.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@ use object_store::ObjectStore;
22
use pyo3::prelude::*;
33
use pyo3_object_store::{get_runtime, PyObjectStore, PyObjectStoreError, PyObjectStoreResult};
44

5+
use crate::utils::PyNone;
6+
57
#[pyfunction]
68
#[pyo3(signature = (store, from_, to, *, overwrite=true))]
79
pub(crate) fn rename(
@@ -43,6 +45,6 @@ pub(crate) fn rename_async(
4345
store.as_ref().rename_if_not_exists(&from_, &to)
4446
};
4547
fut.await.map_err(PyObjectStoreError::ObjectStoreError)?;
46-
Ok(())
48+
Ok(PyNone)
4749
})
4850
}

Diff for: obstore/src/utils.rs

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
use pyo3::prelude::*;
2+
3+
/// Returning `()` from `future_into_py` returns an empty tuple instead of None
4+
/// https://github.com/developmentseed/obstore/issues/240
5+
pub(crate) struct PyNone;
6+
7+
impl<'py> IntoPyObject<'py> for PyNone {
8+
type Target = PyAny;
9+
type Output = Bound<'py, PyAny>;
10+
type Error = PyErr;
11+
12+
fn into_pyobject(self, py: Python<'py>) -> Result<Self::Output, Self::Error> {
13+
Ok(py.None().bind(py).clone())
14+
}
15+
}

Diff for: tests/test_delete.py

+9
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,15 @@ def test_delete_one():
2020
assert len(obs.list(store).collect()) == 0
2121

2222

23+
@pytest.mark.asyncio
24+
async def test_delete_async():
25+
store = MemoryStore()
26+
27+
await obs.put_async(store, "file1.txt", b"foo")
28+
result = await obs.delete_async(store, "file1.txt")
29+
assert result is None
30+
31+
2332
def test_delete_many():
2433
store = MemoryStore()
2534

0 commit comments

Comments
 (0)