dependencies icon indicating copy to clipboard operation
dependencies copied to clipboard

Iterate over draft object returned by produce function.

Open proofit404 opened this issue 3 years ago • 0 comments

Without defining delegated class for each separated case.

Log + instance for every method call.

Or cache & instance for every method call.

from attrs import define
from attrs import field
from dependencies import Injector
from dependencies import produce
from generics import delegated
from generics import private


@private
@define
class Login:
    backend = field()

    def verify(self, name, password):
        user = self.backend.select(name)
        return user.is_correct(password)


@private
@define
class Database:
    result_class = field()

    def select(self, name):
        return self.result_class(name)


@private
@define
class User:
    name = field()

    def is_correct(self, password):
        return len(password) == len(self.name) * 2 - 1


class App(Injector):
    login = Login
    backend = Database
    result_class = User


with produce(App(console=print)) as (draft, LoggedApp):
    for name, cls in draft:

        @delegated(cls)
        @define
        class LoggedClass:
            console = field()
            instance = field()

            def __method__(self, fn, args, kwargs):
                self.console(f"=> {self.instance!r}.{fn}({args!r}, {kwargs!r})")
                result = fn(self.instance, *args, **kwargs)
                self.console(f"<= {self.instance!r}.{fn}: {result!r}")
                return result

        setattr(draft, name, pluck(LoggedClass, instance=cls))


if __name__ == "__main__":
    LoggedApp.login.verify("John", "test")
    LoggedApp.login.verify("Kate", "foobar!")

proofit404 avatar Jul 18 '22 17:07 proofit404