I don't think I would add the marker to the DependantProtocol itself. Instead, it can be a contract between the Dependant implementation and the Executor implementation.
What would need changing, as far as interfaces go, is giving access to the dependent from within the Executor. I can see two ways to do this, one which is backwards compatible and one which is not:
Option 1: add the attribute to the executor's task
from __future__ import annotations
from di.types.dependencies import DependantBase
import sys
from typing import Awaitable, Iterable, Union
if sys.version_info < (3, 8):
from typing_extensions import Protocol
else:
from typing import Protocol
class Task(Protocol):
dependent: DependantBase[Any]
def __call__(
self,
) -> Union[Awaitable[Union[None, Iterable[Task]]], Union[None, Iterable[Task]]]:
...
This would require creating a small wrapper within di/_tasks.py.
Option 2: return a tuple from Task
from __future__ import annotations
from di.types.dependencies import DependantBase
import sys
from typing import Awaitable, Iterable, Union
if sys.version_info < (3, 8):
from typing_extensions import Protocol
else:
from typing import Protocol
class Task(Protocol):
dependent: DependantBase[Any]
def __call__(
self,
) -> Union[Awaitable[Union[None, Iterable[Tuple[Task, Dependant]]], Union[None, Iterable[Tuple[Task, Dependant]]]:
...
I like this less. It's not backwards compatible and is more complicated of an interface (requires implementers to do unpacking).
The main impetus for this feature is to be able to add a marker to say "this sync dependency {should,should not} be executed in a threadpool". Often sync dependencies are small sans-io things, it's super wasteful to put them in a threadpool. Here is an example of such a marker: https://github.com/index-py/index.py/blob/5d7cb5c2de20ef633473bdca58d06306e62a7fed/indexpy/parameters/field_functions.py#L223
I don't think I would add the marker to the DependantProtocol itself. Instead, it can be a contract between the Dependant implementation and the Executor implementation.
What would need changing, as far as interfaces go, is giving access to the dependent from within the Executor. I can see two ways to do this, one which is backwards compatible and one which is not:
Option 1: add the attribute to the executor's task
This would require creating a small wrapper within
di/_tasks.py
.Option 2: return a tuple from Task
I like this less. It's not backwards compatible and is more complicated of an interface (requires implementers to do unpacking).