This is an automated email from the ASF dual-hosted git repository.

xuanwo pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/incubator-opendal.git


The following commit(s) were added to refs/heads/main by this push:
     new d27dc3e67 fix(bindings/python): fix type annotations and improve docs 
(#3483)
d27dc3e67 is described below

commit d27dc3e67c9937dca2accd5669eadb5a0d9d5dfa
Author: messense <[email protected]>
AuthorDate: Sat Nov 4 12:02:53 2023 +0800

    fix(bindings/python): fix type annotations and improve docs (#3483)
---
 bindings/python/python/opendal/__init__.pyi | 22 ++++++-----
 bindings/python/python/opendal/layers.pyi   | 15 +++++---
 bindings/python/src/capability.rs           | 60 +++++++++++++++++++++++++++++
 bindings/python/tests/test_async_delete.py  |  2 +-
 bindings/python/tests/test_read.py          |  5 +++
 5 files changed, 88 insertions(+), 16 deletions(-)

diff --git a/bindings/python/python/opendal/__init__.pyi 
b/bindings/python/python/opendal/__init__.pyi
index 65ae74a21..7713e2a3c 100644
--- a/bindings/python/python/opendal/__init__.pyi
+++ b/bindings/python/python/opendal/__init__.pyi
@@ -17,6 +17,8 @@
 
 from typing import AsyncIterable, Iterable, Optional
 
+from opendal.layers import Layer
+
 class Error(Exception): ...
 
 class Operator:
@@ -28,11 +30,11 @@ class Operator:
         self,
         path: str,
         bs: bytes,
-        append: bool = None,
-        buffer: int = None,
-        content_type: str = None,
-        content_disposition: str = None,
-        cache_control: str = None,
+        append: Optional[bool] = None,
+        buffer: Optional[int] = None,
+        content_type: Optional[str] = None,
+        content_disposition: Optional[str] = None,
+        cache_control: Optional[str] = None,
     ): ...
     def stat(self, path: str) -> Metadata: ...
     def create_dir(self, path: str): ...
@@ -53,11 +55,11 @@ class AsyncOperator:
         self,
         path: str,
         bs: bytes,
-        append: bool = None,
-        buffer: int = None,
-        content_type: str = None,
-        content_disposition: str = None,
-        cache_control: str = None,
+        append: Optional[bool] = None,
+        buffer: Optional[int] = None,
+        content_type: Optional[str] = None,
+        content_disposition: Optional[str] = None,
+        cache_control: Optional[str] = None,
     ): ...
     async def stat(self, path: str) -> Metadata: ...
     async def create_dir(self, path: str): ...
diff --git a/bindings/python/python/opendal/layers.pyi 
b/bindings/python/python/opendal/layers.pyi
index bd2bc2e02..19a38d586 100644
--- a/bindings/python/python/opendal/layers.pyi
+++ b/bindings/python/python/opendal/layers.pyi
@@ -15,12 +15,17 @@
 # specific language governing permissions and limitations
 # under the License.
 
-class RetryLayer:
+from typing import Optional
+
+class Layer:
+    pass
+
+class RetryLayer(Layer):
     def __init__(
         self,
-        max_times: int | None = None,
-        factor: float | None = None,
+        max_times: Optional[int] = None,
+        factor: Optional[float] = None,
         jitter: bool = False,
-        max_delay: float | None = None,
-        min_delay: float | None = None,
+        max_delay: Optional[float] = None,
+        min_delay: Optional[float] = None,
     ) -> None: ...
diff --git a/bindings/python/src/capability.rs 
b/bindings/python/src/capability.rs
index f027199aa..373ea9599 100644
--- a/bindings/python/src/capability.rs
+++ b/bindings/python/src/capability.rs
@@ -17,47 +17,107 @@
 
 use pyo3::prelude::*;
 
+/// Capability is used to describe what operations are supported
+/// by current Operator.
 #[pyclass(get_all, module = "opendal")]
 pub struct Capability {
+    /// If operator supports stat.
     pub stat: bool,
+    /// If operator supports stat with if match.
     pub stat_with_if_match: bool,
+    /// If operator supports stat with if none match.
     pub stat_with_if_none_match: bool,
+
+    /// If operator supports read.
     pub read: bool,
+    /// If operator supports seek on returning reader.
     pub read_can_seek: bool,
+    /// If operator supports next on returning reader.
     pub read_can_next: bool,
+    /// If operator supports read with range.
     pub read_with_range: bool,
+    /// If operator supports read with if match.
     pub read_with_if_match: bool,
+    /// If operator supports read with if none match.
     pub read_with_if_none_match: bool,
+    /// if operator supports read with override cache control.
     pub read_with_override_cache_control: bool,
+    /// if operator supports read with override content disposition.
     pub read_with_override_content_disposition: bool,
+    /// if operator supports read with override content type.
     pub read_with_override_content_type: bool,
+
+    /// If operator supports write.
     pub write: bool,
+    /// If operator supports write can be called in multi times.
     pub write_can_multi: bool,
+    /// If operator supports write with empty content.
     pub write_can_empty: bool,
+    /// If operator supports write by append.
     pub write_can_append: bool,
+    /// If operator supports write with content type.
     pub write_with_content_type: bool,
+    /// If operator supports write with content disposition.
     pub write_with_content_disposition: bool,
+    /// If operator supports write with cache control.
     pub write_with_cache_control: bool,
+    /// write_multi_max_size is the max size that services support in 
write_multi.
+    ///
+    /// For example, AWS S3 supports 5GiB as max in write_multi.
     pub write_multi_max_size: Option<usize>,
+    /// write_multi_min_size is the min size that services support in 
write_multi.
+    ///
+    /// For example, AWS S3 requires at least 5MiB in write_multi expect the 
last one.
     pub write_multi_min_size: Option<usize>,
+    /// write_multi_align_size is the align size that services required in 
write_multi.
+    ///
+    /// For example, Google GCS requires align size to 256KiB in write_multi.
     pub write_multi_align_size: Option<usize>,
+    /// write_total_max_size is the max size that services support in 
write_total.
+    ///
+    /// For example, Cloudflare D1 supports 1MB as max in write_total.
     pub write_total_max_size: Option<usize>,
+
+    /// If operator supports create dir.
     pub create_dir: bool,
+
+    /// If operator supports delete.
     pub delete: bool,
+
+    /// If operator supports copy.
     pub copy: bool,
+
+    /// If operator supports rename.
     pub rename: bool,
+
+    /// If operator supports list.
     pub list: bool,
+    /// If backend supports list with limit.
     pub list_with_limit: bool,
+    /// If backend supports list with start after.
     pub list_with_start_after: bool,
+    /// If backend support list with using slash as delimiter.
     pub list_with_delimiter_slash: bool,
+    /// If backend supports list without delimiter.
     pub list_without_delimiter: bool,
+
+    /// If operator supports presign.
     pub presign: bool,
+    /// If operator supports presign read.
     pub presign_read: bool,
+    /// If operator supports presign stat.
     pub presign_stat: bool,
+    /// If operator supports presign write.
     pub presign_write: bool,
+
+    /// If operator supports batch.
     pub batch: bool,
+    /// If operator supports batch delete.
     pub batch_delete: bool,
+    /// The max operations that operator supports in batch.
     pub batch_max_operations: Option<usize>,
+
+    /// If operator supports blocking.
     pub blocking: bool,
 }
 
diff --git a/bindings/python/tests/test_async_delete.py 
b/bindings/python/tests/test_async_delete.py
index 9b230f0f8..07e94f85e 100644
--- a/bindings/python/tests/test_async_delete.py
+++ b/bindings/python/tests/test_async_delete.py
@@ -45,4 +45,4 @@ async def test_async_remove_all(service_name, operator, 
async_operator):
         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}/")
\ No newline at end of file
+    await async_operator.remove_all(f"{parent}/")
diff --git a/bindings/python/tests/test_read.py 
b/bindings/python/tests/test_read.py
index 95cde619e..62a424104 100644
--- a/bindings/python/tests/test_read.py
+++ b/bindings/python/tests/test_read.py
@@ -35,6 +35,7 @@ def test_sync_read(service_name, operator, async_operator):
 
     operator.delete(filename)
 
+
 @pytest.mark.need_capability("read", "write", "delete")
 def test_sync_reader(service_name, operator, async_operator):
     size = randint(1, 1024)
@@ -49,6 +50,7 @@ def test_sync_reader(service_name, operator, async_operator):
 
     operator.delete(filename)
 
+
 @pytest.mark.asyncio
 @pytest.mark.need_capability("read", "write", "delete")
 async def test_async_read(service_name, operator, async_operator):
@@ -63,6 +65,7 @@ async def test_async_read(service_name, operator, 
async_operator):
 
     await async_operator.delete(filename)
 
+
 @pytest.mark.asyncio
 @pytest.mark.need_capability("read", "write", "delete")
 async def test_async_reader(service_name, operator, async_operator):
@@ -78,6 +81,7 @@ async def test_async_reader(service_name, operator, 
async_operator):
 
     await async_operator.delete(filename)
 
+
 @pytest.mark.asyncio
 @pytest.mark.need_capability("read", "write", "delete")
 async def test_async_reader_without_context(service_name, operator, 
async_operator):
@@ -94,6 +98,7 @@ async def test_async_reader_without_context(service_name, 
operator, async_operat
 
     await async_operator.delete(filename)
 
+
 @pytest.mark.need_capability("read", "write", "delete", "stat")
 def test_sync_read_stat(service_name, operator, async_operator):
     size = randint(1, 1024)

Reply via email to