Skip to content

Commit

Permalink
feat(binding/python): Support remove_all API for Python binding (#3469)
Browse files Browse the repository at this point in the history
Signed-off-by: Manjusaka <[email protected]>
  • Loading branch information
Zheaoli authored Nov 3, 2023
1 parent 27b2a16 commit e90575b
Show file tree
Hide file tree
Showing 5 changed files with 111 additions and 0 deletions.
2 changes: 2 additions & 0 deletions bindings/python/python/opendal/__init__.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ class Operator:
def capability(self) -> Capability: ...
def copy(self, source: str, target: str): ...
def rename(self, source: str, target: str): ...
def remove_all(self, path: str): ...

class AsyncOperator:
def __init__(self, scheme: str, **kwargs): ...
Expand Down Expand Up @@ -71,6 +72,7 @@ class AsyncOperator:
def capability(self) -> Capability: ...
async def copy(self, source: str, target: str): ...
async def rename(self, source: str, target: str): ...
async def remove_all(self, path: str): ...

class Reader:
def read(self, size: Optional[int] = None) -> memoryview: ...
Expand Down
8 changes: 8 additions & 0 deletions bindings/python/src/asyncio.rs
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,14 @@ impl AsyncOperator {
})
}

/// Remove all file
pub fn remove_all<'p>(&'p self, py: Python<'p>, path: String) -> PyResult<&'p PyAny> {
let this = self.0.clone();
future_into_py(py, async move {
this.remove_all(&path).await.map_err(format_pyerr)
})
}

/// Create a dir at given path.
///
/// # Notes
Expand Down
6 changes: 6 additions & 0 deletions bindings/python/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,12 @@ impl Operator {
pub fn rename(&self, source: &str, target: &str) -> PyResult<()> {
self.0.rename(source, target).map_err(format_pyerr)
}

/// Remove all file
pub fn remove_all(&self, path: &str) -> PyResult<()> {
self.0.remove_all(path).map_err(format_pyerr)
}

/// Create a dir at given path.
///
/// # Notes
Expand Down
48 changes: 48 additions & 0 deletions bindings/python/tests/test_async_delete.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.

import os
from random import randint
from uuid import uuid4

import pytest


@pytest.mark.asyncio
@pytest.mark.need_capability("read", "write", "delete", "list")
async def test_async_remove_all(service_name, operator, async_operator):
parent = f"random_dir_{str(uuid4())}"
excepted = [
"x/",
"x/y",
"x/x/",
"x/x/y",
"x/x/x/",
"x/x/x/y",
"x/x/x/x/",
]
for path in excepted:
if path.endswith("/"):
await async_operator.create_dir(f"{parent}/{path}")
else:
await async_operator.write(f"{parent}/{path}", os.urandom(1024))
await async_operator.remove_all(f"{parent}/x/")
for path in excepted:
if not path.endswith("/"):
with pytest.raises(FileNotFoundError) as e_info:
await async_operator.read(f"{parent}/{path}")
await async_operator.remove_all(f"{parent}/")
47 changes: 47 additions & 0 deletions bindings/python/tests/test_sync_delete.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.

import os
from random import randint
from uuid import uuid4

import pytest


@pytest.mark.need_capability("read", "write", "delete", "list", "blocking")
def test_sync_remove_all(service_name, operator, async_operator):
parent = f"random_dir_{str(uuid4())}"
excepted = [
"x/",
"x/y",
"x/x/",
"x/x/y",
"x/x/x/",
"x/x/x/y",
"x/x/x/x/",
]
for path in excepted:
if path.endswith("/"):
operator.create_dir(f"{parent}/{path}")
else:
operator.write(f"{parent}/{path}", os.urandom(1024))
operator.remove_all(f"{parent}/x/")
for path in excepted:
if not path.endswith("/"):
with pytest.raises(FileNotFoundError) as e_info:
operator.read(f"{parent}/{path}")
operator.remove_all(f"{parent}/")

0 comments on commit e90575b

Please sign in to comment.