Expose versioned delete in Python bindings
diff --git a/bindings/python/python/opendal/operator.pyi b/bindings/python/python/opendal/operator.pyi index 7136720..7483c72 100644 --- a/bindings/python/python/opendal/operator.pyi +++ b/bindings/python/python/opendal/operator.pyi
@@ -337,7 +337,10 @@ An awaitable that completes when the directory is created. """ def delete( - self, path: builtins.str | os.PathLike | pathlib.Path + self, + path: builtins.str | os.PathLike | pathlib.Path, + *, + version: builtins.str | None = None, ) -> collections.abc.Awaitable[None]: r""" Delete a file at the given path. @@ -350,6 +353,8 @@ ---------- path : str The path to the file. + version : str, optional + The version of the file to delete. Returns ------- @@ -2710,7 +2715,12 @@ path : str The path to the directory. """ - def delete(self, path: builtins.str | os.PathLike | pathlib.Path) -> None: + def delete( + self, + path: builtins.str | os.PathLike | pathlib.Path, + *, + version: builtins.str | None = None, + ) -> None: r""" Delete a file at the given path. @@ -2722,6 +2732,8 @@ ---------- path : str The path to the file. + version : str, optional + The version of the file to delete. """ def exists(self, path: builtins.str | os.PathLike | pathlib.Path) -> builtins.bool: r"""
diff --git a/bindings/python/src/operator.rs b/bindings/python/src/operator.rs index abf1bd7..c9f4412 100644 --- a/bindings/python/src/operator.rs +++ b/bindings/python/src/operator.rs
@@ -523,9 +523,15 @@ /// ---------- /// path : str /// The path to the file. - pub fn delete(&self, path: PathBuf) -> PyResult<()> { + /// version : str, optional + /// The version of the file to delete. + #[pyo3(signature = (path, *, version=None))] + pub fn delete(&self, path: PathBuf, version: Option<String>) -> PyResult<()> { let path = path.to_string_lossy().to_string(); - self.core.delete(&path).map_err(format_pyerr) + let opts = DeleteOptions { version }; + self.core + .delete_options(&path, opts.into()) + .map_err(format_pyerr) } /// Check if a path exists. @@ -1293,6 +1299,8 @@ /// ---------- /// path : str /// The path to the file. + /// version : str, optional + /// The version of the file to delete. /// /// Returns /// ------- @@ -1302,13 +1310,21 @@ type_repr="collections.abc.Awaitable[None]", imports=("collections.abc") ))] - pub fn delete<'p>(&'p self, py: Python<'p>, path: PathBuf) -> PyResult<Bound<'p, PyAny>> { + #[pyo3(signature = (path, *, version=None))] + pub fn delete<'p>( + &'p self, + py: Python<'p>, + path: PathBuf, + version: Option<String>, + ) -> PyResult<Bound<'p, PyAny>> { let this = self.core.clone(); let path = path.to_string_lossy().to_string(); - future_into_py( - py, - async move { this.delete(&path).await.map_err(format_pyerr) }, - ) + let opts = DeleteOptions { version }; + future_into_py(py, async move { + this.delete_options(&path, opts.into()) + .await + .map_err(format_pyerr) + }) } /// Check if a path exists.
diff --git a/bindings/python/tests/test_async_delete.py b/bindings/python/tests/test_async_delete.py index ff3988f..b7596a7 100644 --- a/bindings/python/tests/test_async_delete.py +++ b/bindings/python/tests/test_async_delete.py
@@ -24,6 +24,16 @@ @pytest.mark.asyncio +@pytest.mark.need_capability("read", "write", "delete") +async def test_async_delete_with_version_option(service_name, operator, async_operator): + path = f"random_file_{str(uuid4())}" + await async_operator.write(path, os.urandom(1024)) + await async_operator.delete(path, version=None) + with pytest.raises(NotFound): + await async_operator.read(path) + + +@pytest.mark.asyncio @pytest.mark.need_capability("read", "write", "delete", "list", "create_dir") async def test_async_remove_all(service_name, operator, async_operator): parent = f"random_dir_{str(uuid4())}"
diff --git a/bindings/python/tests/test_sync_delete.py b/bindings/python/tests/test_sync_delete.py index 0260bf8..68fa296 100644 --- a/bindings/python/tests/test_sync_delete.py +++ b/bindings/python/tests/test_sync_delete.py
@@ -23,6 +23,15 @@ from opendal.exceptions import NotFound +@pytest.mark.need_capability("read", "write", "delete") +def test_sync_delete_with_version_option(service_name, operator, async_operator): + path = f"random_file_{str(uuid4())}" + operator.write(path, os.urandom(1024)) + operator.delete(path, version=None) + with pytest.raises(NotFound): + operator.read(path) + + @pytest.mark.need_capability("read", "write", "delete", "list", "create_dir") def test_sync_remove_all(service_name, operator, async_operator): parent = f"random_dir_{str(uuid4())}"