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 6f22e6d7a feat(bindings/python)!: Stubs fix for operator and
__version__ (#6728)
6f22e6d7a is described below
commit 6f22e6d7a66b905257ee931ced7f7315768c0943
Author: Chitral Verma <[email protected]>
AuthorDate: Wed Oct 22 15:40:50 2025 +0530
feat(bindings/python)!: Stubs fix for operator and __version__ (#6728)
---
bindings/python/python/opendal/__init__.py | 9 ++++-
.../python/opendal/{__init__.pyi => operator.pyi} | 34 +++++++++--------
bindings/python/src/lib.rs | 14 +++----
bindings/python/src/operator.rs | 44 +++++++++++-----------
bindings/python/tests/conftest.py | 4 +-
bindings/python/tests/test_capability.py | 4 +-
6 files changed, 59 insertions(+), 50 deletions(-)
diff --git a/bindings/python/python/opendal/__init__.py
b/bindings/python/python/opendal/__init__.py
index 91547a39b..c2b8430bd 100644
--- a/bindings/python/python/opendal/__init__.py
+++ b/bindings/python/python/opendal/__init__.py
@@ -16,7 +16,12 @@
# under the License.
# ruff: noqa: D104
+import builtins
-from opendal._opendal import * # noqa: F403
+from opendal._opendal import * # noqa: F403 # pyright:ignore
+from opendal.operator import AsyncOperator, Operator # pyright:ignore
-__all__ = [_opendal.__all__] # noqa: F405
+__version__: builtins.str
+
+__all__ = _opendal.__all__ # noqa: F405 # pyright:ignore
+__all__ += ["AsyncOperator", "Operator"] # pyright:ignore
diff --git a/bindings/python/python/opendal/__init__.pyi
b/bindings/python/python/opendal/operator.pyi
similarity index 97%
rename from bindings/python/python/opendal/__init__.pyi
rename to bindings/python/python/opendal/operator.pyi
index 7e3ca6759..564f8c9f8 100644
--- a/bindings/python/python/opendal/__init__.pyi
+++ b/bindings/python/python/opendal/operator.pyi
@@ -25,10 +25,12 @@ import os
import pathlib
import typing
-from opendal import capability, exceptions, file, layers, types
+import opendal.file
+import opendal.types
+from opendal.capability import Capability
+from opendal.file import File
from opendal.layers import Layer
-
-__version__: builtins.str = "0.46.1"
+from opendal.types import Metadata
@typing.final
class AsyncOperator:
@@ -77,7 +79,7 @@ class AsyncOperator:
path: builtins.str | os.PathLike | pathlib.Path,
mode: builtins.str,
**kwargs: typing.Any,
- ) -> collections.abc.Awaitable[file.AsyncFile]:
+ ) -> collections.abc.Awaitable[opendal.file.AsyncFile]:
r"""
Open an async file-like object for the given path.
@@ -226,7 +228,7 @@ class AsyncOperator:
content_type: builtins.str | None = None,
cache_control: builtins.str | None = None,
content_disposition: builtins.str | None = None,
- ) -> collections.abc.Awaitable[types.Metadata]:
+ ) -> collections.abc.Awaitable[Metadata]:
r"""
Get the metadata of a file at the given path.
@@ -392,7 +394,7 @@ class AsyncOperator:
recursive: builtins.bool | None = None,
versions: builtins.bool | None = None,
deleted: builtins.bool | None = None,
- ) -> collections.abc.AsyncIterable[types.Entry]:
+ ) -> collections.abc.AsyncIterable[opendal.types.Entry]:
r"""
List entries in the given directory.
@@ -420,7 +422,7 @@ class AsyncOperator:
self,
path: builtins.str | os.PathLike | pathlib.Path,
expire_second: builtins.int,
- ) -> types.PresignedRequest:
+ ) -> opendal.types.PresignedRequest:
r"""
Create a presigned request for a stat operation.
@@ -440,7 +442,7 @@ class AsyncOperator:
self,
path: builtins.str | os.PathLike | pathlib.Path,
expire_second: builtins.int,
- ) -> types.PresignedRequest:
+ ) -> opendal.types.PresignedRequest:
r"""
Create a presigned request for a read operation.
@@ -460,7 +462,7 @@ class AsyncOperator:
self,
path: builtins.str | os.PathLike | pathlib.Path,
expire_second: builtins.int,
- ) -> types.PresignedRequest:
+ ) -> opendal.types.PresignedRequest:
r"""
Create a presigned request for a write operation.
@@ -480,7 +482,7 @@ class AsyncOperator:
self,
path: builtins.str | os.PathLike | pathlib.Path,
expire_second: builtins.int,
- ) -> types.PresignedRequest:
+ ) -> opendal.types.PresignedRequest:
r"""
Create a presigned request for a delete operation.
@@ -496,7 +498,7 @@ class AsyncOperator:
coroutine
An awaitable that returns a presigned request object.
"""
- def full_capability(self) -> capability.Capability:
+ def capability(self) -> Capability:
r"""
Get all capabilities of this operator.
@@ -562,7 +564,7 @@ class Operator:
path: builtins.str | os.PathLike | pathlib.Path,
mode: builtins.str,
**kwargs: typing.Any,
- ) -> file.File:
+ ) -> File:
r"""
Open a file-like object for the given path.
@@ -706,7 +708,7 @@ class Operator:
content_type: builtins.str | None = None,
cache_control: builtins.str | None = None,
content_disposition: builtins.str | None = None,
- ) -> types.Metadata:
+ ) -> Metadata:
r"""
Get the metadata of a file at the given path.
@@ -825,7 +827,7 @@ class Operator:
recursive: builtins.bool | None = None,
versions: builtins.bool | None = None,
deleted: builtins.bool | None = None,
- ) -> collections.abc.Iterable[types.Entry]:
+ ) -> collections.abc.Iterable[opendal.types.Entry]:
r"""
List entries in the given directory.
@@ -857,7 +859,7 @@ class Operator:
start_after: builtins.str | None = None,
versions: builtins.bool | None = None,
deleted: builtins.bool | None = None,
- ) -> collections.abc.Iterable[types.Entry]:
+ ) -> collections.abc.Iterable[opendal.types.Entry]:
r"""
Recursively list entries in the given directory.
@@ -883,7 +885,7 @@ class Operator:
BlockingLister
An iterator over the entries in the directory.
"""
- def full_capability(self) -> capability.Capability:
+ def capability(self) -> Capability:
r"""
Get all capabilities of this operator.
diff --git a/bindings/python/src/lib.rs b/bindings/python/src/lib.rs
index c4133ecc9..46c41f430 100644
--- a/bindings/python/src/lib.rs
+++ b/bindings/python/src/lib.rs
@@ -38,13 +38,16 @@ mod errors;
pub use errors::*;
mod options;
pub use options::*;
-use pyo3_stub_gen::{define_stub_info_gatherer, derive::*, module_variable};
-
-// Add version
-module_variable!("opendal", "__version__", &str, env!("CARGO_PKG_VERSION"));
+use pyo3_stub_gen::{define_stub_info_gatherer, derive::*};
#[pymodule(gil_used = false)]
fn _opendal(py: Python, m: &Bound<'_, PyModule>) -> PyResult<()> {
+ // Add version
+ m.add("__version__", env!("CARGO_PKG_VERSION"))?;
+
+ // Operator module
+ add_pymodule!(py, m, "operator", [Operator, AsyncOperator])?;
+
// File module
add_pymodule!(py, m, "file", [File, AsyncFile])?;
@@ -67,9 +70,6 @@ fn _opendal(py: Python, m: &Bound<'_, PyModule>) ->
PyResult<()> {
[Entry, EntryMode, Metadata, PresignedRequest]
)?;
- m.add_class::<Operator>()?;
- m.add_class::<AsyncOperator>()?;
-
m.add_class::<WriteOptions>()?;
m.add_class::<ReadOptions>()?;
m.add_class::<ListOptions>()?;
diff --git a/bindings/python/src/operator.rs b/bindings/python/src/operator.rs
index 993cda599..1225c854f 100644
--- a/bindings/python/src/operator.rs
+++ b/bindings/python/src/operator.rs
@@ -57,7 +57,7 @@ fn build_blocking_operator(
/// --------
/// AsyncOperator
#[gen_stub_pyclass]
-#[pyclass(module = "opendal")]
+#[pyclass(module = "opendal.operator")]
pub struct Operator {
core: ocore::blocking::Operator,
__scheme: ocore::Scheme,
@@ -144,7 +144,6 @@ impl Operator {
/// -------
/// File
/// A file-like object.
- #[gen_stub(override_return_type(type_repr = "file.File"))]
#[pyo3(signature = (path, mode, *, **kwargs))]
pub fn open(
&self,
@@ -400,7 +399,6 @@ impl Operator {
/// -------
/// Metadata
/// The metadata of the file.
- #[gen_stub(override_return_type(type_repr = "types.Metadata"))]
#[allow(clippy::too_many_arguments)]
#[pyo3(signature = (path, *,
version=None,
@@ -550,8 +548,8 @@ impl Operator {
/// BlockingLister
/// An iterator over the entries in the directory.
#[gen_stub(override_return_type(
- type_repr="collections.abc.Iterable[types.Entry]",
- imports=("collections.abc")
+ type_repr="collections.abc.Iterable[opendal.types.Entry]",
+ imports=("collections.abc", "opendal.types")
))]
#[pyo3(signature = (path, *,
limit=None,
@@ -609,8 +607,8 @@ impl Operator {
/// BlockingLister
/// An iterator over the entries in the directory.
#[gen_stub(override_return_type(
- type_repr="collections.abc.Iterable[types.Entry]",
- imports=("collections.abc")
+ type_repr="collections.abc.Iterable[opendal.types.Entry]",
+ imports=("collections.abc", "opendal.types")
))]
#[pyo3(signature = (path, *,
limit=None,
@@ -634,8 +632,7 @@ impl Operator {
/// -------
/// Capability
/// The capability of the operator.
- #[gen_stub(override_return_type(type_repr = "capability.Capability"))]
- pub fn full_capability(&self) -> PyResult<capability::Capability> {
+ pub fn capability(&self) -> PyResult<capability::Capability> {
Ok(capability::Capability::new(
self.core.info().full_capability(),
))
@@ -696,7 +693,7 @@ impl Operator {
/// --------
/// Operator
#[gen_stub_pyclass]
-#[pyclass(module = "opendal")]
+#[pyclass(module = "opendal.operator")]
pub struct AsyncOperator {
core: ocore::Operator,
__scheme: ocore::Scheme,
@@ -780,8 +777,8 @@ impl AsyncOperator {
/// coroutine
/// An awaitable that returns a file-like object.
#[gen_stub(override_return_type(
- type_repr="collections.abc.Awaitable[file.AsyncFile]",
- imports=("collections.abc")
+ type_repr="collections.abc.Awaitable[opendal.file.AsyncFile]",
+ imports=("collections.abc", "opendal.file")
))]
#[pyo3(signature = (path, mode, *, **kwargs))]
pub fn open<'p>(
@@ -1071,7 +1068,7 @@ impl AsyncOperator {
/// An awaitable that returns the metadata of the file.
#[allow(clippy::too_many_arguments)]
#[gen_stub(override_return_type(
- type_repr="collections.abc.Awaitable[types.Metadata]",
+ type_repr="collections.abc.Awaitable[Metadata]",
imports=("collections.abc")
))]
#[pyo3(signature = (path, *,
@@ -1329,7 +1326,10 @@ impl AsyncOperator {
/// coroutine
/// An awaitable that returns an async iterator over the entries.
#[allow(clippy::too_many_arguments)]
- #[gen_stub(override_return_type(type_repr =
"collections.abc.AsyncIterable[types.Entry]"))]
+ #[gen_stub(override_return_type(
+ type_repr="collections.abc.AsyncIterable[opendal.types.Entry]",
+ imports=("collections.abc", "opendal.types")
+ ))]
#[pyo3(signature = (path, *,
limit=None,
start_after=None,
@@ -1390,7 +1390,10 @@ impl AsyncOperator {
/// -------
/// coroutine
/// An awaitable that returns an async iterator over the entries.
- #[gen_stub(override_return_type(type_repr =
"collections.abc.AsyncIterable[types.Entry]",))]
+ #[gen_stub(override_return_type(
+ type_repr="collections.abc.AsyncIterable[opendal.types.Entry]",
+ imports=("collections.abc", "opendal.types")
+ ))]
#[gen_stub(skip)]
#[pyo3(signature = (path, *,
limit=None,
@@ -1422,7 +1425,7 @@ impl AsyncOperator {
/// -------
/// coroutine
/// An awaitable that returns a presigned request object.
- #[gen_stub(override_return_type(type_repr = "types.PresignedRequest"))]
+ #[gen_stub(override_return_type(type_repr =
"opendal.types.PresignedRequest", imports=("opendal.types")))]
pub fn presign_stat<'p>(
&'p self,
py: Python<'p>,
@@ -1455,7 +1458,7 @@ impl AsyncOperator {
/// -------
/// coroutine
/// An awaitable that returns a presigned request object.
- #[gen_stub(override_return_type(type_repr = "types.PresignedRequest"))]
+ #[gen_stub(override_return_type(type_repr =
"opendal.types.PresignedRequest", imports=("opendal.types")))]
pub fn presign_read<'p>(
&'p self,
py: Python<'p>,
@@ -1488,7 +1491,7 @@ impl AsyncOperator {
/// -------
/// coroutine
/// An awaitable that returns a presigned request object.
- #[gen_stub(override_return_type(type_repr = "types.PresignedRequest"))]
+ #[gen_stub(override_return_type(type_repr =
"opendal.types.PresignedRequest", imports=("opendal.types")))]
pub fn presign_write<'p>(
&'p self,
py: Python<'p>,
@@ -1521,7 +1524,7 @@ impl AsyncOperator {
/// -------
/// coroutine
/// An awaitable that returns a presigned request object.
- #[gen_stub(override_return_type(type_repr = "types.PresignedRequest"))]
+ #[gen_stub(override_return_type(type_repr =
"opendal.types.PresignedRequest", imports=("opendal.types")))]
pub fn presign_delete<'p>(
&'p self,
py: Python<'p>,
@@ -1547,8 +1550,7 @@ impl AsyncOperator {
/// -------
/// Capability
/// The capability of the operator.
- #[gen_stub(override_return_type(type_repr = "capability.Capability"))]
- pub fn full_capability(&self) -> PyResult<Capability> {
+ pub fn capability(&self) -> PyResult<Capability> {
Ok(capability::Capability::new(
self.core.info().full_capability(),
))
diff --git a/bindings/python/tests/conftest.py
b/bindings/python/tests/conftest.py
index 38a689628..5bf32d545 100644
--- a/bindings/python/tests/conftest.py
+++ b/bindings/python/tests/conftest.py
@@ -79,8 +79,8 @@ def check_capability(request, operator, async_operator) ->
None:
marker
and marker.args
and not all(
- [getattr(operator.full_capability(), x) for x in marker.args]
- + [getattr(async_operator.full_capability(), x) for x in
marker.args]
+ [getattr(operator.capability(), x) for x in marker.args]
+ + [getattr(async_operator.capability(), x) for x in marker.args]
)
):
pytest.skip(f"skip because {marker.args} not supported")
diff --git a/bindings/python/tests/test_capability.py
b/bindings/python/tests/test_capability.py
index b22decdb4..240816418 100644
--- a/bindings/python/tests/test_capability.py
+++ b/bindings/python/tests/test_capability.py
@@ -19,13 +19,13 @@ import pytest
def test_capability(service_name, operator):
- cap = operator.full_capability()
+ cap = operator.capability()
assert cap is not None
assert cap.read is not None
def test_capability_exception(service_name, operator):
- cap = operator.full_capability()
+ cap = operator.capability()
assert cap is not None
with pytest.raises(AttributeError):
_ = cap.read_demo