Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion docs/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ module zenoh
:undoc-members:

module zenoh.handlers
============
=====================

.. automodule:: zenoh.handlers
:members:
Expand Down
20 changes: 18 additions & 2 deletions docs/stubs_to_sources.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,23 @@
referencing a type not declared yet (i.e. forward reference)."""

import ast
import inspect
from collections import defaultdict
from pathlib import Path

PACKAGE = (Path(__file__) / "../../zenoh").resolve()
__INIT__ = PACKAGE / "__init__.py"


def _unstable(item):
warning = ".. warning:: This API has been marked as unstable: it works as advertised, but it may be changed in a future release."
if item.__doc__:
item.__doc__ += "\n" + warning
else:
item.__doc__ = warning
return item


class RemoveOverload(ast.NodeTransformer):
def __init__(self):
self.current_cls = None
Expand Down Expand Up @@ -95,10 +105,16 @@ def main():
entry.rename(PACKAGE / f"{entry.stem}.py")
# read stub code
with open(__INIT__) as f:
stub = ast.parse(f.read())
stub: ast.Module = ast.parse(f.read())
# replace _unstable
for i, stmt in enumerate(stub.body):
if isinstance(stmt, ast.FunctionDef) and stmt.name == "_unstable":
stub.body[i] = ast.parse(inspect.getsource(_unstable))
# remove overload
stub = RemoveOverload().visit(stub)
# write modified code
with open(__INIT__, "w") as f:
f.write(ast.unparse(RemoveOverload().visit(stub)))
f.write(ast.unparse(stub))


if __name__ == "__main__":
Expand Down
2 changes: 2 additions & 0 deletions tests/stubs_check.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ def visit_ClassDef(self, node: ast.ClassDef):
self.current_cls = None

def visit_FunctionDef(self, node: ast.FunctionDef):
if node.name == "_unstable":
return
func = getattr(self.current_cls or self.module, node.name)
if node.name.startswith("__") or node.name.endswith("serializer"):
pass
Expand Down
15 changes: 14 additions & 1 deletion zenoh/__init__.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,9 @@ _RustHandler = (
_PythonCallback = Callable[[_T], Any]
_PythonHandler = tuple[_PythonCallback[_T], _H]

def _unstable(item: _T) -> _T:
"""marker for unstable functionality"""

@final
class ZError(Exception): ...

Expand Down Expand Up @@ -330,6 +333,7 @@ class KeyExpr:
def includes(self, other: _IntoKeyExpr) -> bool:
"""Returns true if self includes other, i.e. the set defined by self contains every key belonging to the set defined by other."""

@_unstable
def relation_to(self, other: _IntoKeyExpr) -> SetIntersectionLevel:
"""Returns the relation between self and other from self's point of view (SetIntersectionLevel::Includes signifies that self includes other).
Note that this is slower than keyexpr::intersects and keyexpr::includes, so you should favor these methods for most applications.
Expand All @@ -348,6 +352,7 @@ class KeyExpr:

_IntoKeyExpr = KeyExpr | str

@_unstable
Comment thread
DenisBiryukov91 marked this conversation as resolved.
@final
class Liveliness:
def declare_token(self, key_expr: _IntoKeyExpr) -> LivelinessToken:
Expand Down Expand Up @@ -413,6 +418,7 @@ class Liveliness:
) -> Subscriber[None]:
"""Create a Subscriber for liveliness changes matching the given key expression."""

@_unstable
@final
class LivelinessToken:
def __enter__(self) -> Self: ...
Expand Down Expand Up @@ -484,6 +490,7 @@ class Publisher:
@property
def priority(self) -> Priority: ...
@property
@_unstable
def reliability(self) -> Reliability: ...
def put(
self,
Expand Down Expand Up @@ -573,9 +580,10 @@ class Queryable(Generic[_H]):
@overload
def __iter__(self) -> Never: ...

@_unstable
@final
class Querier:
"""A querier that allows to send queries to a queryable..
"""A querier that allows to send queries to a queryable.
Queriers are automatically undeclared when dropped."""

def __enter__(self) -> Self: ...
Expand Down Expand Up @@ -642,6 +650,7 @@ class QueryTarget(Enum):
DEFAULT = BEST_MATCHING

@final
@_unstable
class Reliability(Enum):
BEST_EFFORT = auto()
RELIABLE = auto()
Expand All @@ -657,6 +666,7 @@ class Reply:
@property
def err(self) -> ReplyError | None: ...
@property
@_unstable
def replier_id(self) -> ZenohId | None: ...

@final
Expand Down Expand Up @@ -944,6 +954,7 @@ class Session:
) -> Publisher:
"""Create a Publisher for the given key expression."""

@_unstable
def declare_querier(
self,
key_expr: _IntoKeyExpr,
Expand All @@ -957,6 +968,7 @@ class Session:
) -> Querier:
"""Create a Querier for the given key expression."""

@_unstable
def liveliness(self) -> Liveliness:
"""Obtain a Liveliness instance tied to this Zenoh session."""

Expand All @@ -971,6 +983,7 @@ class SessionInfo:
def peers_zid(self) -> list[ZenohId]:
"""Return the ZenohId of the zenoh peers this process is currently connected to."""

@_unstable
@final
class SetIntersectionLevel(Enum):
DISJOINT = auto()
Expand Down