From 93f3aa14bf4c7247af242ee36d8c644e57275c57 Mon Sep 17 00:00:00 2001
From: Trim21 <trim21.me@gmail.com>
Date: Thu, 26 Dec 2024 08:27:47 +0800
Subject: [PATCH] fix: python binding kwargs parsing (#5458)

* fix: python binding kwargs parsing

* add for test
---
 bindings/python/Cargo.toml          | 1 +
 bindings/python/src/operator.rs     | 9 +++++++--
 bindings/python/src/options.rs      | 5 +++--
 bindings/python/tests/test_write.py | 2 +-
 4 files changed, 12 insertions(+), 5 deletions(-)

diff --git a/bindings/python/Cargo.toml b/bindings/python/Cargo.toml
index a2db6361c85d..6cda36ddfb29 100644
--- a/bindings/python/Cargo.toml
+++ b/bindings/python/Cargo.toml
@@ -158,6 +158,7 @@ doc = false
 
 [dependencies]
 bytes = "1.5.0"
+dict_derive = "0.6.0"
 futures = "0.3.28"
 # this crate won't be published, we always use the local version
 opendal = { version = ">=0", path = "../../core", features = [
diff --git a/bindings/python/src/operator.rs b/bindings/python/src/operator.rs
index 4cd53924407d..b3c14b7c5d0a 100644
--- a/bindings/python/src/operator.rs
+++ b/bindings/python/src/operator.rs
@@ -118,7 +118,10 @@ impl Operator {
     #[pyo3(signature = (path, bs, **kwargs))]
     pub fn write(&self, path: &str, bs: Vec<u8>, kwargs: Option<WriteOptions>) -> PyResult<()> {
         let kwargs = kwargs.unwrap_or_default();
-        let mut write = self.core.write_with(path, bs).append(kwargs.append);
+        let mut write = self
+            .core
+            .write_with(path, bs)
+            .append(kwargs.append.unwrap_or(false));
         if let Some(chunk) = kwargs.chunk {
             write = write.chunk(chunk);
         }
@@ -333,7 +336,9 @@ impl AsyncOperator {
         let this = self.core.clone();
         let bs = bs.as_bytes().to_vec();
         future_into_py(py, async move {
-            let mut write = this.write_with(&path, bs).append(kwargs.append);
+            let mut write = this
+                .write_with(&path, bs)
+                .append(kwargs.append.unwrap_or(false));
             if let Some(buffer) = kwargs.chunk {
                 write = write.chunk(buffer);
             }
diff --git a/bindings/python/src/options.rs b/bindings/python/src/options.rs
index 0992b913d038..16e6a4640a2d 100644
--- a/bindings/python/src/options.rs
+++ b/bindings/python/src/options.rs
@@ -15,12 +15,13 @@
 // specific language governing permissions and limitations
 // under the License.
 
-use pyo3::{pyclass, FromPyObject};
+use dict_derive::FromPyObject;
+use pyo3::pyclass;
 
 #[pyclass(module = "opendal")]
 #[derive(FromPyObject, Default)]
 pub struct WriteOptions {
-    pub append: bool,
+    pub append: Option<bool>,
     pub chunk: Option<usize>,
     pub content_type: Option<String>,
     pub content_disposition: Option<String>,
diff --git a/bindings/python/tests/test_write.py b/bindings/python/tests/test_write.py
index e15bdd26e49f..69d448ba01c4 100644
--- a/bindings/python/tests/test_write.py
+++ b/bindings/python/tests/test_write.py
@@ -29,7 +29,7 @@ def test_sync_write(service_name, operator, async_operator):
     filename = f"test_file_{str(uuid4())}.txt"
     content = os.urandom(size)
     size = len(content)
-    operator.write(filename, content)
+    operator.write(filename, content, content_type="text/plain")
     metadata = operator.stat(filename)
     assert metadata is not None
     assert metadata.mode.is_file()