Skip to content

Commit

Permalink
feat(wip): fix resolve_factory check return
Browse files Browse the repository at this point in the history
  • Loading branch information
raceychan committed Feb 5, 2025
1 parent 1d69329 commit 6bd20f1
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 58 deletions.
62 changes: 5 additions & 57 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -991,71 +991,19 @@ def test_ignore_dependences():
Function as Dependency
```python
def get_user(session: Session, token: Token) -> Ignore[Any]:
...
```
a function with its return type Annotated by `Ignore` is considered a pure function dependency, instead of a factory.
```python
def validate_admin(user: Annotated[User, get_user]):
@dg.node
def get_user(session: Session, token: Token) -> Ignore[User]:
...
```
<!--
# TODO: are FnDep nodes?
if so, we need to define new type of node
```python
class FnDepNode:
factory: Callable[P, ...]
factory_type: Literal["function", "resource"]
dependencies: Dependencies
config: NodeConfig
```
```
def resolve_params(self, function):
require_scope, unresolved = self.analyze_params(function)
if require_scope:
raise OutOfScopeError
params = {}
for pname, ptype in unresolved:
params[pname] = self.resolve(ptype)
return params
async def resolve_afunction(self, function): ...
```
then we can rewrite entry as such
which means that, `get_user` won't be used to resolve `User`.
```python
@wraps(func)
async def _async_scoped_wrapper(*args: P.args, **kwargs: P.kwargs) -> T:
async with self.scope() as scope:
params = await scope.aresolve_params(function, ignore=kwargs)
await scope.aresolve_function(*args, **(params|kwargs))
```
or
we introduce `FuncReturn` Mark
```python
def get_user(session: Session, token: Token) -> Fndep[User]:
def validate_admin(user: Annotated[User, get_user])->Ignore[Any]:
...
dg.resolve(get_user)
```
FuncReturn can be Any
The biggest difference between Funcdep and factory is that
factory is associated with a type where Fndep is not.
in short,
dg.resolve(User) won't call get_user -->
2 changes: 1 addition & 1 deletion ididi/_type_resolve.py
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,7 @@ def resolve_factory(factory: Callable[..., T]) -> type[T]:
should handle Annotate, Generator function, etc.
"""
sig = get_typed_signature(factory, check_return=True)
sig = get_typed_signature(factory)
dependent: type[T] = resolve_annotation(sig.return_annotation)
return dependent

Expand Down
37 changes: 37 additions & 0 deletions tests/test_feat.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,40 @@
run test with: make feat
"""

from typing import Annotated

from ididi import Graph, Ignore

from .test_data import Config, UserService


class User:
def __init__(self, name: str, role: str):
self.name = name
self.role = role


def get_user(config: Config) -> Ignore[User]:
assert isinstance(config, Config)
return User("user", "admin")


def validate_admin(
user: Annotated[User, get_user], service: UserService
) -> Ignore[str]:
assert user.role == "admin"
assert isinstance(service, UserService)
return "ok"


async def test_resolve_function():
dg = Graph()

user = dg.resolve(get_user)
assert isinstance(user, User)


def test_dg_resolve_params():
dg = Graph()

assert dg.resolve(validate_admin) == "ok"

0 comments on commit 6bd20f1

Please sign in to comment.