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
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ def __init__(self):
@abstractmethod
def to_json(self) -> dict[str, str]:
"""Convert this token source into a JSON-serializable dictionary."""
...
pass


class ManagedIdentityTokenSource(TokenSource):
Expand Down
12 changes: 6 additions & 6 deletions durabletask/payload/store.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ class PayloadStore(abc.ABC):
@abc.abstractmethod
def options(self) -> LargePayloadStorageOptions:
"""Return the storage options for this payload store."""
...
pass

@abc.abstractmethod
def upload(self, data: bytes, *, instance_id: str | None = None) -> str:
Expand All @@ -59,12 +59,12 @@ def upload(self, data: bytes, *, instance_id: str | None = None) -> str:
Returns:
A token string that can be used to retrieve the payload.
"""
...
pass

@abc.abstractmethod
async def upload_async(self, data: bytes, *, instance_id: str | None = None) -> str:
"""Async version of :meth:`upload`."""
...
pass

@abc.abstractmethod
def download(self, token: str) -> bytes:
Expand All @@ -77,14 +77,14 @@ def download(self, token: str) -> bytes:
Returns:
The original payload bytes.
"""
...
pass

@abc.abstractmethod
async def download_async(self, token: str) -> bytes:
"""Async version of :meth:`download`."""
...
pass

@abc.abstractmethod
def is_known_token(self, value: str) -> bool:
"""Return ``True`` if *value* looks like a token produced by this store."""
...
pass
6 changes: 3 additions & 3 deletions durabletask/serialization.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ class DataConverter(ABC):
@abstractmethod
def serialize(self, value: Any) -> str | None:
"""Serialize ``value`` to a string, or ``None`` when ``value`` is ``None``."""
...
pass

@abstractmethod
def deserialize(self, data: str | None, target_type: type | None = None) -> Any:
Expand All @@ -85,7 +85,7 @@ def deserialize(self, data: str | None, target_type: type | None = None) -> Any:
:class:`JsonDataConverter` is best-effort and falls back; a validating
converter may instead raise.
"""
...
pass

@abstractmethod
def coerce(self, value: Any, target_type: type | None = None) -> Any:
Expand All @@ -99,7 +99,7 @@ def coerce(self, value: Any, target_type: type | None = None) -> Any:
(strict vs. best-effort) that an implementation applies in
:meth:`deserialize` should apply here.
"""
...
pass

def can_reconstruct(self, target_type: Any) -> bool:
"""Return True if this converter can rebuild ``target_type`` from a payload.
Expand Down
4 changes: 2 additions & 2 deletions tests/durabletask/test_orchestration_executor.py
Original file line number Diff line number Diff line change
Expand Up @@ -586,7 +586,7 @@ class Result:
message: str

def annotated_activity(ctx, _) -> Result:
...
pass

captured: dict = {}

Expand Down Expand Up @@ -626,7 +626,7 @@ class Override:
value: str

def annotated_activity(ctx, _) -> Annotated:
...
pass

captured: dict = {}

Expand Down
48 changes: 24 additions & 24 deletions tests/durabletask/test_type_discovery.py
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ def can_reconstruct(self, target_type: Any) -> bool:
return super().can_reconstruct(target_type)

def act(ctx, w: Widget):
...
pass

# The default converter does not recognize Widget...
assert type_discovery.activity_input_type(act) is None
Expand All @@ -118,48 +118,48 @@ def act(ctx, w: Widget):
class TestInputTypeDiscovery:
def test_orchestrator_input_type_dataclass(self):
def orch(ctx, order: Order):
...
pass
assert type_discovery.orchestrator_input_type(orch) is Order

def test_activity_input_type_dataclass(self):
def act(ctx, order: Order):
...
pass
assert type_discovery.activity_input_type(act) is Order

def test_input_type_builtin_returns_none(self):
def act(ctx, value: int):
...
pass
assert type_discovery.activity_input_type(act) is None

def test_input_type_unannotated_returns_none(self):
def act(ctx, value):
...
pass
assert type_discovery.activity_input_type(act) is None

def test_input_type_no_input_param_returns_none(self):
def orch(ctx):
...
pass
assert type_discovery.orchestrator_input_type(orch) is None

def test_postponed_annotation_resolves(self):
# Annotation provided as a string (PEP 563 style) still resolves because
# Order is importable in this module's globals.
def act(ctx, order: "Order"):
...
pass
assert type_discovery.activity_input_type(act) is Order

def test_function_entity_input_type(self):
def counter(ctx, order: Order):
...
pass
assert type_discovery.entity_input_type(counter, "any_op") is Order

def test_class_entity_input_type_per_operation(self):
class Store(entities.DurableEntity):
def add(self, order: Order):
...
pass

def clear(self):
...
pass

assert type_discovery.entity_input_type(Store, "add") is Order
# Operation with no input parameter.
Expand All @@ -171,32 +171,32 @@ def clear(self):
class TestActivityOutputTypeDiscovery:
def test_dataclass_return_annotation(self):
def act(ctx, _) -> Order:
...
pass
assert type_discovery.activity_output_type(act) is Order

def test_from_json_return_annotation(self):
def act(ctx, _) -> Money:
...
pass
assert type_discovery.activity_output_type(act) is Money

def test_builtin_return_annotation_returns_none(self):
def act(ctx, _) -> int:
...
pass
assert type_discovery.activity_output_type(act) is None

def test_unannotated_return_returns_none(self):
def act(ctx, _):
...
pass
assert type_discovery.activity_output_type(act) is None

def test_optional_dataclass_return(self):
def act(ctx, _) -> Optional[Order]:
...
pass
assert type_discovery.activity_output_type(act) is Optional[Order]

def test_postponed_return_annotation_resolves(self):
def act(ctx, _) -> "Order":
...
pass
assert type_discovery.activity_output_type(act) is Order

def test_string_name_returns_none(self):
Expand All @@ -223,7 +223,7 @@ class TestSignatureCaching:

def test_signature_inspected_once_per_function(self):
def act(ctx, order: Order) -> Money:
...
pass

real_signature = inspect.signature
calls: list[Any] = []
Expand All @@ -248,7 +248,7 @@ def counting_signature(obj, *args, **kwargs):
def test_entity_operation_signature_inspected_once(self):
class Store(entities.DurableEntity):
def add(self, order: Order):
...
pass

real_signature = inspect.signature
calls: list[Any] = []
Expand Down Expand Up @@ -277,7 +277,7 @@ def can_reconstruct(self, target_type: Any) -> bool:
return super().can_reconstruct(target_type)

def act(ctx, w: Widget) -> Widget:
...
pass

# Prime the cache with the converter that *does* recognize Widget, then
# switch back: the cached structure must not bake in the first answer.
Expand All @@ -303,7 +303,7 @@ def can_reconstruct(self, target_type: Any) -> bool:
return super().can_reconstruct(target_type)

def act(ctx, w: Widget):
...
pass

converter = ToggleConverter()
assert type_discovery.activity_input_type(act, converter) is None
Expand All @@ -314,7 +314,7 @@ def act(ctx, w: Widget):

def test_converter_is_consulted_on_every_call(self):
def act(ctx, order: Order) -> Order:
...
pass

converter = _CountingConverter()
for _ in range(3):
Expand All @@ -328,7 +328,7 @@ def act(ctx, order: Order) -> Order:

def test_unannotated_parameters_are_not_offered_to_the_converter(self):
def act(ctx, value, *args, keyword_only: Order = None, **kwargs):
...
pass

converter = _CountingConverter()
assert type_discovery.activity_input_type(act, converter) is None
Expand All @@ -344,7 +344,7 @@ def __eq__(self, other):
return self is other

def __call__(self, ctx, order: Order) -> Order:
...
pass

act = Callable_()
assert type_discovery.activity_input_type(act) is Order
Expand All @@ -361,7 +361,7 @@ class ConfiguredActivity:
retries: int = 3

def __call__(self, ctx, order: Order) -> Order:
...
pass

handler = ConfiguredActivity()
with pytest.raises(TypeError):
Expand Down
Loading