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/opendal.git


The following commit(s) were added to refs/heads/main by this push:
     new 501a87f142 chore(binding/python): Upgrade pyo3 to 0.21 (#4734)
501a87f142 is described below

commit 501a87f142b0e4e09d9349150381cfe0992a1c46
Author: Weijie Guo <[email protected]>
AuthorDate: Fri Jun 14 13:39:24 2024 +0800

    chore(binding/python): Upgrade pyo3 to 0.21 (#4734)
---
 bindings/python/Cargo.toml      |  4 ++--
 bindings/python/src/file.rs     | 44 ++++++++++++++++++--------------------
 bindings/python/src/lib.rs      | 42 ++++++++++++++++++++----------------
 bindings/python/src/operator.rs | 47 +++++++++++++++++++++++------------------
 bindings/python/src/utils.rs    |  5 +++--
 5 files changed, 76 insertions(+), 66 deletions(-)

diff --git a/bindings/python/Cargo.toml b/bindings/python/Cargo.toml
index df47ac4c6b..94ff95d6b9 100644
--- a/bindings/python/Cargo.toml
+++ b/bindings/python/Cargo.toml
@@ -157,8 +157,8 @@ futures = "0.3.28"
 opendal = { version = "0.47.0", path = "../../core", features = [
   "layers-blocking",
 ] }
-pyo3 = { version = "0.20.1", features = ["abi3", "abi3-py311"] }
-pyo3-asyncio = { version = "0.20", features = ["tokio-runtime"] }
+pyo3 = { version = "0.21.2", features = ["abi3", "abi3-py311"] }
+pyo3-asyncio = { package = "pyo3-asyncio-0-21", version = "0.21", features = 
["tokio-runtime"]}
 tokio = "1"
 
 [target.'cfg(unix)'.dependencies.opendal]
diff --git a/bindings/python/src/file.rs b/bindings/python/src/file.rs
index 0134bf8edc..2a7907f1c8 100644
--- a/bindings/python/src/file.rs
+++ b/bindings/python/src/file.rs
@@ -61,7 +61,7 @@ impl File {
 impl File {
     /// Read and return at most size bytes, or if size is not given, until EOF.
     #[pyo3(signature = (size=None,))]
-    pub fn read<'p>(&'p mut self, py: Python<'p>, size: Option<usize>) -> 
PyResult<&'p PyAny> {
+    pub fn read<'p>(&'p mut self, py: Python<'p>, size: Option<usize>) -> 
PyResult<Bound<PyAny>> {
         let reader = match &mut self.0 {
             FileState::Reader(r) => r,
             FileState::Writer(_) => {
@@ -243,15 +243,13 @@ impl File {
     pub fn flush(&mut self) -> PyResult<()> {
         if matches!(self.0, FileState::Reader(_)) {
             Ok(())
-        } else {
-            if let FileState::Writer(w) = &mut self.0 {
-                match w.flush() {
-                    Ok(_) => Ok(()),
-                    Err(e) => Err(e.into()),
-                }
-            } else {
-                Ok(())
+        } else if let FileState::Writer(w) = &mut self.0 {
+            match w.flush() {
+                Ok(_) => Ok(()),
+                Err(e) => Err(e.into()),
             }
+        } else {
+            Ok(())
         }
     }
 
@@ -312,7 +310,7 @@ impl AsyncFile {
 #[pymethods]
 impl AsyncFile {
     /// Read and return at most size bytes, or if size is not given, until EOF.
-    pub fn read<'p>(&'p self, py: Python<'p>, size: Option<usize>) -> 
PyResult<&'p PyAny> {
+    pub fn read<'p>(&'p self, py: Python<'p>, size: Option<usize>) -> 
PyResult<Bound<PyAny>> {
         let state = self.0.clone();
 
         future_into_py(py, async move {
@@ -357,7 +355,7 @@ impl AsyncFile {
     }
 
     /// Write bytes into the file.
-    pub fn write<'p>(&'p mut self, py: Python<'p>, bs: &'p [u8]) -> 
PyResult<&'p PyAny> {
+    pub fn write<'p>(&'p mut self, py: Python<'p>, bs: &'p [u8]) -> 
PyResult<Bound<PyAny>> {
         let state = self.0.clone();
 
         // FIXME: can we avoid this clone?
@@ -398,7 +396,7 @@ impl AsyncFile {
     ///
     /// Return the new absolute position.
     #[pyo3(signature = (pos, whence = 0))]
-    pub fn seek<'p>(&'p mut self, py: Python<'p>, pos: i64, whence: u8) -> 
PyResult<&'p PyAny> {
+    pub fn seek<'p>(&'p mut self, py: Python<'p>, pos: i64, whence: u8) -> 
PyResult<Bound<PyAny>> {
         let state = self.0.clone();
 
         let whence = match whence {
@@ -433,7 +431,7 @@ impl AsyncFile {
     }
 
     /// Return the current stream position.
-    pub fn tell<'p>(&'p mut self, py: Python<'p>) -> PyResult<&'p PyAny> {
+    pub fn tell<'p>(&'p mut self, py: Python<'p>) -> PyResult<Bound<PyAny>> {
         let state = self.0.clone();
 
         future_into_py(py, async move {
@@ -460,7 +458,7 @@ impl AsyncFile {
         })
     }
 
-    fn close<'p>(&'p mut self, py: Python<'p>) -> PyResult<&'p PyAny> {
+    fn close<'p>(&'p mut self, py: Python<'p>) -> PyResult<Bound<PyAny>> {
         let state = self.0.clone();
         future_into_py(py, async move {
             let mut state = state.lock().await;
@@ -474,7 +472,7 @@ impl AsyncFile {
         })
     }
 
-    fn __aenter__<'a>(slf: PyRef<'a, Self>, py: Python<'a>) -> PyResult<&'a 
PyAny> {
+    fn __aenter__<'a>(slf: PyRef<'a, Self>, py: Python<'a>) -> 
PyResult<Bound<'a, PyAny>> {
         let slf = slf.into_py(py);
         future_into_py(py, async move { Ok(slf) })
     }
@@ -482,15 +480,15 @@ impl AsyncFile {
     fn __aexit__<'a>(
         &'a mut self,
         py: Python<'a>,
-        _exc_type: &'a PyAny,
-        _exc_value: &'a PyAny,
-        _traceback: &'a PyAny,
-    ) -> PyResult<&'a PyAny> {
+        _exc_type: &Bound<'a, PyAny>,
+        _exc_value: &Bound<'a, PyAny>,
+        _traceback: &Bound<'a, PyAny>,
+    ) -> PyResult<Bound<'a, PyAny>> {
         self.close(py)
     }
 
     /// Check if the stream may be read from.
-    pub fn readable<'p>(&'p self, py: Python<'p>) -> PyResult<&'p PyAny> {
+    pub fn readable<'p>(&'p self, py: Python<'p>) -> PyResult<Bound<PyAny>> {
         let state = self.0.clone();
         future_into_py(py, async move {
             let state = state.lock().await;
@@ -499,7 +497,7 @@ impl AsyncFile {
     }
 
     /// Check if the stream may be written to.
-    pub fn writable<'p>(&'p self, py: Python<'p>) -> PyResult<&'p PyAny> {
+    pub fn writable<'p>(&'p self, py: Python<'p>) -> PyResult<Bound<PyAny>> {
         let state = self.0.clone();
         future_into_py(py, async move {
             let state = state.lock().await;
@@ -508,7 +506,7 @@ impl AsyncFile {
     }
 
     /// Check if the stream reader may be re-located.
-    pub fn seekable<'p>(&'p self, py: Python<'p>) -> PyResult<&'p PyAny> {
+    pub fn seekable<'p>(&'p self, py: Python<'p>) -> PyResult<Bound<PyAny>> {
         if true {
             self.readable(py)
         } else {
@@ -518,7 +516,7 @@ impl AsyncFile {
 
     /// Check if the stream is closed.
     #[getter]
-    pub fn closed<'p>(&'p self, py: Python<'p>) -> PyResult<&'p PyAny> {
+    pub fn closed<'p>(&'p self, py: Python<'p>) -> PyResult<Bound<PyAny>> {
         let state = self.0.clone();
         future_into_py(py, async move {
             let state = state.lock().await;
diff --git a/bindings/python/src/lib.rs b/bindings/python/src/lib.rs
index e45c9b83eb..3985095398 100644
--- a/bindings/python/src/lib.rs
+++ b/bindings/python/src/lib.rs
@@ -69,7 +69,7 @@ pub use errors::*;
 /// asyncio.run(main())
 /// ```
 #[pymodule]
-fn _opendal(py: Python, m: &PyModule) -> PyResult<()> {
+fn _opendal(py: Python, m: &Bound<'_, PyModule>) -> PyResult<()> {
     m.add_class::<Operator>()?;
     m.add_class::<AsyncOperator>()?;
 
@@ -83,28 +83,34 @@ fn _opendal(py: Python, m: &PyModule) -> PyResult<()> {
     m.add_class::<Capability>()?;
 
     // Layer module
-    let layers_module = PyModule::new(py, "layers")?;
+    let layers_module = PyModule::new_bound(py, "layers")?;
     layers_module.add_class::<Layer>()?;
     layers_module.add_class::<RetryLayer>()?;
-    m.add_submodule(layers_module)?;
-    py.import("sys")?
+    m.add_submodule(&layers_module)?;
+    py.import_bound("sys")?
         .getattr("modules")?
         .set_item("opendal.layers", layers_module)?;
 
-    let exception_module = PyModule::new(py, "exceptions")?;
-    exception_module.add("Error", py.get_type::<Error>())?;
-    exception_module.add("Unexpected", py.get_type::<UnexpectedError>())?;
-    exception_module.add("Unsupported", py.get_type::<UnsupportedError>())?;
-    exception_module.add("ConfigInvalid", 
py.get_type::<ConfigInvalidError>())?;
-    exception_module.add("NotFound", py.get_type::<NotFoundError>())?;
-    exception_module.add("PermissionDenied", 
py.get_type::<PermissionDeniedError>())?;
-    exception_module.add("IsADirectory", py.get_type::<IsADirectoryError>())?;
-    exception_module.add("NotADirectory", 
py.get_type::<NotADirectoryError>())?;
-    exception_module.add("AlreadyExists", 
py.get_type::<AlreadyExistsError>())?;
-    exception_module.add("IsSameFile", py.get_type::<IsSameFileError>())?;
-    exception_module.add("ConditionNotMatch", 
py.get_type::<ConditionNotMatchError>())?;
-    m.add_submodule(exception_module)?;
-    py.import("sys")?
+    let exception_module = PyModule::new_bound(py, "exceptions")?;
+    exception_module.add("Error", py.get_type_bound::<Error>())?;
+    exception_module.add("Unexpected", 
py.get_type_bound::<UnexpectedError>())?;
+    exception_module.add("Unsupported", 
py.get_type_bound::<UnsupportedError>())?;
+    exception_module.add("ConfigInvalid", 
py.get_type_bound::<ConfigInvalidError>())?;
+    exception_module.add("NotFound", py.get_type_bound::<NotFoundError>())?;
+    exception_module.add(
+        "PermissionDenied",
+        py.get_type_bound::<PermissionDeniedError>(),
+    )?;
+    exception_module.add("IsADirectory", 
py.get_type_bound::<IsADirectoryError>())?;
+    exception_module.add("NotADirectory", 
py.get_type_bound::<NotADirectoryError>())?;
+    exception_module.add("AlreadyExists", 
py.get_type_bound::<AlreadyExistsError>())?;
+    exception_module.add("IsSameFile", 
py.get_type_bound::<IsSameFileError>())?;
+    exception_module.add(
+        "ConditionNotMatch",
+        py.get_type_bound::<ConditionNotMatchError>(),
+    )?;
+    m.add_submodule(&exception_module)?;
+    py.import_bound("sys")?
         .getattr("modules")?
         .set_item("opendal.exceptions", exception_module)?;
     Ok(())
diff --git a/bindings/python/src/operator.rs b/bindings/python/src/operator.rs
index 8a6d592312..e013145a71 100644
--- a/bindings/python/src/operator.rs
+++ b/bindings/python/src/operator.rs
@@ -52,7 +52,7 @@ pub struct Operator(ocore::BlockingOperator);
 impl Operator {
     #[new]
     #[pyo3(signature = (scheme, *, **map))]
-    pub fn new(scheme: &str, map: Option<&PyDict>) -> PyResult<Self> {
+    pub fn new(scheme: &str, map: Option<&Bound<PyDict>>) -> PyResult<Self> {
         let scheme = ocore::Scheme::from_str(scheme)
             .map_err(|err| {
                 ocore::Error::new(ocore::ErrorKind::Unexpected, "unsupported 
scheme")
@@ -97,14 +97,14 @@ impl Operator {
     }
 
     /// Read the whole path into bytes.
-    pub fn read<'p>(&'p self, py: Python<'p>, path: &str) -> PyResult<&'p 
PyAny> {
+    pub fn read<'p>(&'p self, py: Python<'p>, path: &str) -> 
PyResult<Bound<PyAny>> {
         let buffer = self.0.read(path).map_err(format_pyerr)?.to_vec();
         Buffer::new(buffer).into_bytes_ref(py)
     }
 
     /// Write bytes into given path.
     #[pyo3(signature = (path, bs, **kwargs))]
-    pub fn write(&self, path: &str, bs: Vec<u8>, kwargs: Option<&PyDict>) -> 
PyResult<()> {
+    pub fn write(&self, path: &str, bs: Vec<u8>, kwargs: 
Option<&Bound<PyDict>>) -> PyResult<()> {
         let opwrite = build_opwrite(kwargs)?;
         let mut write = self.0.write_with(path, bs).append(opwrite.append());
         if let Some(chunk) = opwrite.chunk() {
@@ -218,7 +218,7 @@ pub struct AsyncOperator(ocore::Operator);
 impl AsyncOperator {
     #[new]
     #[pyo3(signature = (scheme, *,  **map))]
-    pub fn new(scheme: &str, map: Option<&PyDict>) -> PyResult<Self> {
+    pub fn new(scheme: &str, map: Option<&Bound<PyDict>>) -> PyResult<Self> {
         let scheme = ocore::Scheme::from_str(scheme)
             .map_err(|err| {
                 ocore::Error::new(ocore::ErrorKind::Unexpected, "unsupported 
scheme")
@@ -242,7 +242,12 @@ impl AsyncOperator {
     }
 
     /// Open a file-like reader for the given path.
-    pub fn open<'p>(&'p self, py: Python<'p>, path: String, mode: String) -> 
PyResult<&'p PyAny> {
+    pub fn open<'p>(
+        &'p self,
+        py: Python<'p>,
+        path: String,
+        mode: String,
+    ) -> PyResult<Bound<PyAny>> {
         let this = self.0.clone();
         let capability = self.capability()?;
 
@@ -268,7 +273,7 @@ impl AsyncOperator {
     }
 
     /// Read the whole path into bytes.
-    pub fn read<'p>(&'p self, py: Python<'p>, path: String) -> PyResult<&'p 
PyAny> {
+    pub fn read<'p>(&'p self, py: Python<'p>, path: String) -> 
PyResult<Bound<PyAny>> {
         let this = self.0.clone();
         future_into_py(py, async move {
             let res: Vec<u8> = 
this.read(&path).await.map_err(format_pyerr)?.to_vec();
@@ -282,9 +287,9 @@ impl AsyncOperator {
         &'p self,
         py: Python<'p>,
         path: String,
-        bs: &PyBytes,
-        kwargs: Option<&PyDict>,
-    ) -> PyResult<&'p PyAny> {
+        bs: &Bound<PyBytes>,
+        kwargs: Option<&Bound<PyDict>>,
+    ) -> PyResult<Bound<PyAny>> {
         let opwrite = build_opwrite(kwargs)?;
         let this = self.0.clone();
         let bs = bs.as_bytes().to_vec();
@@ -307,7 +312,7 @@ impl AsyncOperator {
     }
 
     /// Get current path's metadata **without cache** directly.
-    pub fn stat<'p>(&'p self, py: Python<'p>, path: String) -> PyResult<&'p 
PyAny> {
+    pub fn stat<'p>(&'p self, py: Python<'p>, path: String) -> 
PyResult<Bound<PyAny>> {
         let this = self.0.clone();
         future_into_py(py, async move {
             let res: Metadata = this
@@ -326,7 +331,7 @@ impl AsyncOperator {
         py: Python<'p>,
         source: String,
         target: String,
-    ) -> PyResult<&'p PyAny> {
+    ) -> PyResult<Bound<PyAny>> {
         let this = self.0.clone();
         future_into_py(py, async move {
             this.copy(&source, &target).await.map_err(format_pyerr)
@@ -339,7 +344,7 @@ impl AsyncOperator {
         py: Python<'p>,
         source: String,
         target: String,
-    ) -> PyResult<&'p PyAny> {
+    ) -> PyResult<Bound<PyAny>> {
         let this = self.0.clone();
         future_into_py(py, async move {
             this.rename(&source, &target).await.map_err(format_pyerr)
@@ -347,7 +352,7 @@ impl AsyncOperator {
     }
 
     /// Remove all file
-    pub fn remove_all<'p>(&'p self, py: Python<'p>, path: String) -> 
PyResult<&'p PyAny> {
+    pub fn remove_all<'p>(&'p self, py: Python<'p>, path: String) -> 
PyResult<Bound<PyAny>> {
         let this = self.0.clone();
         future_into_py(py, async move {
             this.remove_all(&path).await.map_err(format_pyerr)
@@ -366,7 +371,7 @@ impl AsyncOperator {
     ///
     /// - Create on existing dir will succeed.
     /// - Create dir is always recursive, works like `mkdir -p`
-    pub fn create_dir<'p>(&'p self, py: Python<'p>, path: String) -> 
PyResult<&'p PyAny> {
+    pub fn create_dir<'p>(&'p self, py: Python<'p>, path: String) -> 
PyResult<Bound<PyAny>> {
         let this = self.0.clone();
         future_into_py(py, async move {
             this.create_dir(&path).await.map_err(format_pyerr)
@@ -378,7 +383,7 @@ impl AsyncOperator {
     /// # Notes
     ///
     /// - Delete not existing error won't return errors.
-    pub fn delete<'p>(&'p self, py: Python<'p>, path: String) -> PyResult<&'p 
PyAny> {
+    pub fn delete<'p>(&'p self, py: Python<'p>, path: String) -> 
PyResult<Bound<PyAny>> {
         let this = self.0.clone();
         future_into_py(
             py,
@@ -387,7 +392,7 @@ impl AsyncOperator {
     }
 
     /// List current dir path.
-    pub fn list<'p>(&'p self, py: Python<'p>, path: String) -> PyResult<&'p 
PyAny> {
+    pub fn list<'p>(&'p self, py: Python<'p>, path: String) -> 
PyResult<Bound<PyAny>> {
         let this = self.0.clone();
         future_into_py(py, async move {
             let lister = this.lister(&path).await.map_err(format_pyerr)?;
@@ -397,7 +402,7 @@ impl AsyncOperator {
     }
 
     /// List dir in flat way.
-    pub fn scan<'p>(&'p self, py: Python<'p>, path: String) -> PyResult<&'p 
PyAny> {
+    pub fn scan<'p>(&'p self, py: Python<'p>, path: String) -> 
PyResult<Bound<PyAny>> {
         let this = self.0.clone();
         future_into_py(py, async move {
             let lister = this
@@ -416,7 +421,7 @@ impl AsyncOperator {
         py: Python<'p>,
         path: String,
         expire_second: u64,
-    ) -> PyResult<&'p PyAny> {
+    ) -> PyResult<Bound<PyAny>> {
         let this = self.0.clone();
         future_into_py(py, async move {
             let res = this
@@ -435,7 +440,7 @@ impl AsyncOperator {
         py: Python<'p>,
         path: String,
         expire_second: u64,
-    ) -> PyResult<&'p PyAny> {
+    ) -> PyResult<Bound<PyAny>> {
         let this = self.0.clone();
         future_into_py(py, async move {
             let res = this
@@ -454,7 +459,7 @@ impl AsyncOperator {
         py: Python<'p>,
         path: String,
         expire_second: u64,
-    ) -> PyResult<&'p PyAny> {
+    ) -> PyResult<Bound<PyAny>> {
         let this = self.0.clone();
         future_into_py(py, async move {
             let res = this
@@ -495,7 +500,7 @@ impl AsyncOperator {
 }
 
 /// recognize OpWrite-equivalent options passed as python dict
-pub(crate) fn build_opwrite(kwargs: Option<&PyDict>) -> 
PyResult<ocore::raw::OpWrite> {
+pub(crate) fn build_opwrite(kwargs: Option<&Bound<PyDict>>) -> 
PyResult<ocore::raw::OpWrite> {
     use ocore::raw::OpWrite;
     let mut op = OpWrite::new();
 
diff --git a/bindings/python/src/utils.rs b/bindings/python/src/utils.rs
index f51306a645..eb58e85ef8 100644
--- a/bindings/python/src/utils.rs
+++ b/bindings/python/src/utils.rs
@@ -39,9 +39,10 @@ impl Buffer {
     }
 
     /// Consume self to build a bytes
-    pub fn into_bytes_ref(self, py: Python) -> PyResult<&PyAny> {
+    pub fn into_bytes_ref(self, py: Python) -> PyResult<Bound<PyAny>> {
         let buffer = self.into_py(py);
-        let view = unsafe { 
py.from_owned_ptr_or_err(ffi::PyBytes_FromObject(buffer.as_ptr()))? };
+        let view =
+            unsafe { Bound::from_owned_ptr_or_err(py, 
ffi::PyBytes_FromObject(buffer.as_ptr()))? };
 
         Ok(view)
     }

Reply via email to