Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/dishka/dependency_source/activator.py
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ def as_factory(
},
type_=factory.type,
cache=factory.cache,
validate_unconditional_when=factory.validate_unconditional_when,
when_override=factory.when_override,
when_active=factory.when_active,
when_component=factory.when_component,
Expand Down
1 change: 1 addition & 0 deletions src/dishka/dependency_source/alias.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ def as_factory(
kw_dependencies={},
type_=FactoryType.ALIAS,
cache=self.cache,
validate_unconditional_when=None,
when_override=self.when_override,
when_active=self.when_active,
when_component=(
Expand Down
3 changes: 2 additions & 1 deletion src/dishka/dependency_source/context_var.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ def __init__(
def as_factory(
self, component: Component,
) -> Factory:
override = (BoolMarker(True) if self.override else None)
override = BoolMarker(True) if self.override else None

if component == DEFAULT_COMPONENT:
return Factory(
Expand All @@ -43,6 +43,7 @@ def as_factory(
kw_dependencies={},
type_=FactoryType.CONTEXT,
cache=False,
validate_unconditional_when=None,
when_override=override,
when_active=HasContext(self.provides.type_hint),
when_component=component,
Expand Down
1 change: 1 addition & 0 deletions src/dishka/dependency_source/decorator.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ def as_factory(
},
type_=self.factory.type,
cache=cache,
validate_unconditional_when=None,
when_override=self.when,
when_active=self.when,
when_component=self.factory.when_component or component,
Expand Down
7 changes: 7 additions & 0 deletions src/dishka/dependency_source/factory.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ class Factory(FactoryData):
"dependencies",
"is_to_bind",
"kw_dependencies",
"validate_unconditional_when",
"when_active",
"when_component",
"when_dependencies",
Expand All @@ -51,6 +52,7 @@ def __init__(
type_: FactoryType,
is_to_bind: bool,
cache: bool,
validate_unconditional_when: bool | None,
when_override: BaseMarker | None,
when_active: BaseMarker | None,
when_component: Component | None,
Expand Down Expand Up @@ -82,6 +84,7 @@ def __init__(
self.kw_dependencies = kw_dependencies
self.is_to_bind = is_to_bind
self.cache = cache
self.validate_unconditional_when = validate_unconditional_when
self.when_active = when_active
self.when_component = when_component
self.when_dependencies = when_dependencies
Expand All @@ -106,6 +109,7 @@ def __get__(self, instance: Any, owner: Any) -> Factory:
type_=self.type,
is_to_bind=False,
cache=self.cache,
validate_unconditional_when=self.validate_unconditional_when,
when_override=when_override,
when_active=when_active,
when_component=self.when_component,
Expand All @@ -127,6 +131,7 @@ def with_component(self, component: Component) -> Factory:
is_to_bind=self.is_to_bind,
cache=self.cache,
type_=self.type,
validate_unconditional_when=self.validate_unconditional_when,
when_override=self.when_override,
when_active=self.when_active,
when_component=(
Expand All @@ -147,6 +152,7 @@ def with_scope(self, scope: BaseScope) -> Factory:
is_to_bind=self.is_to_bind,
cache=self.cache,
type_=self.type,
validate_unconditional_when=self.validate_unconditional_when,
when_override=self.when_override,
when_active=self.when_active,
when_component=self.when_component,
Expand All @@ -171,6 +177,7 @@ def replace(
is_to_bind=self.is_to_bind,
cache=self.cache,
type_=self.type,
validate_unconditional_when=self.validate_unconditional_when,
when_override=coalesce(when_override, self.when_override),
when_active=coalesce(when_active, self.when_active),
when_component=coalesce(when_component, self.when_component),
Expand Down
1 change: 1 addition & 0 deletions src/dishka/dependency_source/factory_union_mode.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ def as_factory(self) -> Factory | None:
when_active=None,
when_override=None,
cache=self.cache,
validate_unconditional_when=None,
when_component=self.provides.component,
is_to_bind=False,
type_=FactoryType.COLLECTION,
Expand Down
3 changes: 3 additions & 0 deletions src/dishka/entities/validation_settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,14 @@ class ValidationSettings:
implicit_override: bool = False
# check if decorator was not applied to any factory
nothing_decorated: bool = True
# validate factories without explicit `when` conditions at build time
validate_unconditional_when: bool = False


DEFAULT_VALIDATION = ValidationSettings()
STRICT_VALIDATION = ValidationSettings(
nothing_overridden=True,
implicit_override=True,
nothing_decorated=True,
validate_unconditional_when = True,
)
2 changes: 2 additions & 0 deletions src/dishka/graph_builder/activation.py
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,8 @@ def __init__(
self.activation_container = activation_container

def _eval_activation(self, factory: Factory) -> None:
if factory.when_active is None and factory.when_override is None:
return
try:
active = self.activation_container.is_active(factory)
except StaticEvaluationUnavailable as e:
Expand Down
2 changes: 1 addition & 1 deletion src/dishka/graph_builder/builder.py
Original file line number Diff line number Diff line change
Expand Up @@ -563,5 +563,5 @@ def build(self) -> Sequence[Registry]:
self.start_scope,
).evaluate_static()
if not self.skip_validation:
GraphValidator(registries).validate()
GraphValidator(registries, self.validation_settings).validate()
return registries
1 change: 1 addition & 0 deletions src/dishka/graph_builder/uniter.py
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ def unite(
type_=FactoryType.SELECTOR,
kw_dependencies={},
source=None,
validate_unconditional_when=None,
when_override=None,
when_active=or_markers(*(
factory.when_active
Expand Down
38 changes: 31 additions & 7 deletions src/dishka/graph_builder/validator.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
from dishka.dependency_source import Factory
from dishka.entities.key import DependencyKey
from dishka.entities.marker import BoolMarker
from dishka.entities.validation_settings import ValidationSettings
from dishka.exceptions import (
CycleDependenciesError,
GraphMissingFactoryError,
Expand All @@ -14,10 +15,33 @@


class GraphValidator:
def __init__(self, registries: Sequence[Registry]) -> None:
def __init__(
self,
registries: Sequence[Registry],
validation_settings: ValidationSettings,
) -> None:
self.registries = registries
self.validation_settings = validation_settings
self.path: dict[DependencyKey, Factory] = {}
self.valid_keys: dict[DependencyKey, bool] = {}
self.current_factory: Factory | None = None

def _can_validate_now(self, factory: Factory) -> bool:
return self._is_resolved(factory.when_active) and self._is_resolved(
factory.when_override,
)

def _is_resolved(self, when: object) -> bool:
if when == BoolMarker(True):
return True
if when is None:
if self.current_factory is None:
return self.validation_settings.validate_unconditional_when
factory_override = self.current_factory.validate_unconditional_when
if factory_override is not None:
return factory_override
return self.validation_settings.validate_unconditional_when
return False

def _validate_key(
self,
Expand Down Expand Up @@ -56,13 +80,13 @@ def _validate_key(
)

def _validate_factory(
self, factory: Factory, registry_index: int,
self,
factory: Factory,
registry_index: int,
) -> None:
if (
factory.when_active == BoolMarker(False) and
factory.when_override == BoolMarker(False)
):
return # do not validate disabled factories
self.current_factory = factory
if not self._can_validate_now(factory):
return

self.path[factory.provides] = factory
if (
Expand Down
Loading
Loading