Qualifiers and by_default
Closed this issue · 5 comments
by_default
lets you register an implementation to be used when no other implementation is found. But it doesn't work as expected with qualified_by
.
@interface
class View(Protocol):
name: str
@implements(View).by_default
@dataclass
class DefaultView:
name: str = "Default View"
@implements(View).when(qualified_by=V1)
@dataclass
class CustomView:
name: str = "Custom View"
if __name__ == "__main__":
print(world.get[View].single(qualified_by=V1))
print(world.get[View].single())
If I leave off .by_default
it fails at lookup when discovering multiple implementations.
When I include by_default
, the second print
just finds CustomView
again.
I have a worry that you've explained this to me in email and I forgot. 😇
Ok, I have to admit, it wasn't obvious to me either at first. :)
When doing the second part, world.get[View].single()
, no constraints are used at all. So any implementation is valid, CustomView
included.
What you were expecting though was an implementation without qualifiers. This can be done with a predicate constraint:
class NotQualified:
def evaluate(self, predicate: Optional[QualifiedBy]) -> bool:
return predicate is None
print(world.get[View].single(NotQualified()))
Also, In the V2, I intend to replace evaluate
with __call__
. I think it was a mistake to use a custom name. It makes using function as constraints just easier.
For the stuff I'm writing on holiday, predicates was next. So you give me a good "segue" to introduce it!
While I won't change the current behavior with qualifiers, I've added a QualifiedBy.nothing
constraint:
from dataclasses import dataclass
from typing import Protocol
from antidote import implements, instanceOf, interface, QualifiedBy, world
@interface
class View(Protocol):
name: str
@implements.protocol[View]().as_default
@dataclass
class DefaultView:
name: str = "Default View"
@implements.protocol[View]().when(qualified_by='v1')
@dataclass
class CustomView:
name: str = "Custom View"
if __name__ == "__main__":
print(world[instanceOf[View]().single(qualified_by='v1')])
print(world[instanceOf[View]().single(QualifiedBy.nothing)])
Ah, thanks, I think that covers the case (from our coding session) that my cursor is currently sitting on.
I'll close this.