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)
}