An immutable map from tag to service. Context[R] holds the
services of the tags R, so a context with more services stands in
for one with fewer (Context[A | B] is a Context[A]).
Context(mapping) is Effect's makeUnsafe: an untyped context.
Build typed ones with make and add.
Attributes#
| Attribute | Type | Description |
|---|---|---|
unsafe_map | Mapping[type[Tag[Any]], Any] | The services by tag, in insertion order, untyped (Effect's
|
Functions#
__init__#
__init__(services=None) -> None| Parameter | Type | Description |
|---|---|---|
services | Mapping[type[Tag[Any]], Any] | None = None |
def __init__(self, services: Mapping[type[Tag[Any]], Any] | None = None) -> None:
self._services: dict[type[Tag[Any]], Any] = dict(services or {})empty#
empty() -> Context[Never]Returns Context[Never]
@staticmethod
def empty() -> Context[Never]:
return _EMPTYmake#
make(tag, service) -> Context[T]A context holding one service.
| Parameter | Type | Description |
|---|---|---|
tag | TagLike[S, T] | |
service | S |
Returns Context[T]
@staticmethod
def make[S, T](tag: TagLike[S, T], service: S) -> Context[T]:
"""A context holding one service."""
return Context({tag_class(tag): service})merge_all#
merge_all(*contexts) -> Context[Any]Every context's services; later contexts win where several have a tag.
| Parameter | Type | Description |
|---|---|---|
contexts | Context[Any] = () |
Returns Context[Any]
@staticmethod
def merge_all(*contexts: Context[Any]) -> Context[Any]:
"""Every context's services; later contexts win where several have
a tag."""
merged: dict[type[Tag[Any]], Any] = {}
for ctx in contexts:
merged.update(ctx._services)
return Context(merged)pick#
pick(*tags) -> _Pick[T]Keep only tags' services, in this context's order. Use with
.pipe; the context must hold every tag.
| Parameter | Type | Description |
|---|---|---|
tags | TagLike[Any, T] = () |
Returns _Pick[T]
@staticmethod
def pick[T = Never](*tags: TagLike[Any, T]) -> _Pick[T]:
"""Keep only ``tags``' services, in this context's order. Use with
``.pipe``; the context must hold every tag."""
return _Pick(frozenset(map(tag_class, tags)))omit#
omit(*tags) -> _Omit[T]Drop tags' services and remove them from the type. Use with
.pipe.
| Parameter | Type | Description |
|---|---|---|
tags | TagLike[Any, T] = () |
Returns _Omit[T]
@staticmethod
def omit[T = Never](*tags: TagLike[Any, T]) -> _Omit[T]:
"""Drop ``tags``' services and remove them from the type. Use with
``.pipe``."""
return _Omit(frozenset(map(tag_class, tags)))add_or_omit#
add_or_omit(tag, service) -> _Omit[T]add for Some(service), omit for None. Either way the
tag leaves the type. Use with .pipe.
| Parameter | Type | Description |
|---|---|---|
tag | TagLike[S, T] | |
service | Option[S] |
Returns _Omit[T]
@staticmethod
def add_or_omit[S, T](tag: TagLike[S, T], service: Option[S]) -> _Omit[T]:
"""``add`` for ``Some(service)``, ``omit`` for ``None``. Either way the
tag leaves the type. Use with ``.pipe``."""
cls = tag_class(tag)
if service is None:
return _Omit(frozenset((cls,)))
return _Omit(frozenset(), (cls, service.value))pipe#
pipe(f) -> B| Parameter | Type | Description |
|---|---|---|
f | Callable[[Self], B] |
Returns B
def pipe[B](self, f: Callable[[Self], B], /) -> B:
return f(self)lookup#
lookup(tag) -> tuple[bool, Any]| Parameter | Type | Description |
|---|---|---|
tag | type[Tag[Any]] |
Returns tuple[bool, Any]
def lookup(self, tag: type[Tag[Any]]) -> tuple[bool, Any]:
if tag in self._services:
return True, self._services[tag]
if issubclass(tag, Reference):
return True, _default_of(tag)
return False, Noneget#
get(tag) -> SThe service of tag, which the context's type must hold (a
reference falls back to its default).
| Parameter | Type | Description |
|---|---|---|
tag | TagLike[S, T] |
Returns S
def get[S, T](self: Context[T], tag: TagLike[S, T]) -> S:
"""The service of ``tag``, which the context's type must hold (a
reference falls back to its default)."""
return self.unsafe_get(tag)unsafe_get#
unsafe_get(tag) -> Sget without the type check: raises MissingServiceError if
the service is absent.
| Parameter | Type | Description |
|---|---|---|
tag | TagLike[S, T] |
Returns S
def unsafe_get[S, T](self, tag: TagLike[S, T]) -> S:
"""``get`` without the type check: raises ``MissingServiceError`` if
the service is absent."""
found, value = self.lookup(tag_class(tag))
if not found:
raise MissingServiceError(_missing(tag_class(tag), self))
return valueget_option#
get_option(tag) -> Option[S]Some(service), or None if absent. A reference is never
absent: it falls back to its default.
| Parameter | Type | Description |
|---|---|---|
tag | TagLike[S, T] |
Returns Option[S]
def get_option[S, T](self, tag: TagLike[S, T]) -> Option[S]:
"""``Some(service)``, or ``None`` if absent. A reference is never
absent: it falls back to its default."""
found, value = self.lookup(tag_class(tag))
return Some(value) if found else Noneget_or_else#
get_or_else(tag, or_else) -> S | BThe service, or or_else() if absent.
| Parameter | Type | Description |
|---|---|---|
tag | TagLike[S, T] | |
or_else | Callable[[], B] |
Returns S | B
def get_or_else[S, T, B](self, tag: TagLike[S, T], or_else: Callable[[], B]) -> S | B:
"""The service, or ``or_else()`` if absent."""
found, value = self.lookup(tag_class(tag))
return value if found else or_else()add#
add(tag, service) -> Context[R_contra | T]A copy with service added. Replacing a tag keeps its place.
| Parameter | Type | Description |
|---|---|---|
tag | TagLike[S, T] | |
service | S |
Returns Context[R_contra | T]
def add[S, T](self, tag: TagLike[S, T], service: S) -> Context[R_contra | T]:
"""A copy with ``service`` added. Replacing a tag keeps its place."""
return Context({**self._services, tag_class(tag): service})merge#
merge(other) -> Context[R_contra | R2]Both contexts' services; other wins where both have a tag.
Merging with an empty context gives back the other one.
| Parameter | Type | Description |
|---|---|---|
other | Context[R2] |
Returns Context[R_contra | R2]
def merge[R2](self, other: Context[R2]) -> Context[R_contra | R2]:
"""Both contexts' services; ``other`` wins where both have a tag.
Merging with an empty context gives back the other one."""
if not other._services:
return cast("Context[Any]", self)
if not self._services:
return cast("Context[Any]", other)
return Context({**self._services, **other._services})tags#
tags() -> tuple[type[Tag[Any]], ...]Returns tuple[type[Tag[Any]], ...]
def tags(self) -> tuple[type[Tag[Any]], ...]:
return tuple(self._services)