Repository: reagento/dishka
Pull request #232 (2024-08-29 23:33:11)

add explicit factory override #16


Patch:
diff --git a/docs/provider/provide.rst b/docs/provider/provide.rst
index fd1459f..743bd80 100644
--- a/docs/provider/provide.rst
+++ b/docs/provider/provide.rst
@@ -155,6 +155,19 @@ WithParents generates only one factory and many aliases and is equivalent to ``A
         c = provide(C, scope=Scope.APP, recursive=True)
 
 
+* Do you want to override the factory? To do this, specify the parameter ``override=True``. If this is not done, error ``FactoryIsNotOverriddenError`` will be thrown
+
+.. code-block:: python
+    from dishka import WithParents, provide, Provider, Scope
+    class MyProvider(Provider):
+        scope=Scope.APP
+        a = provide(lambda: 1, provides=int)
+        a_override = provide(lambda: 2, provides=int, override=True)
+    container = make_async_container(MyProvider())
+    a = await container.get(int)
+    # 2
+
+
 * You can use factory with Generic classes
 
 .. code-block:: python
@@ -163,3 +176,4 @@ WithParents generates only one factory and many aliases and is equivalent to ``A
         @provide
         def make_a(self, type_: type[T]) -> A[T]:
             ...
+
diff --git a/src/dishka/async_container.py b/src/dishka/async_container.py
index c4fbf69..484cc25 100644
--- a/src/dishka/async_container.py
+++ b/src/dishka/async_container.py
@@ -196,12 +196,16 @@ def make_async_container(
         lock_factory: Callable[[], Lock] | None = Lock,
         skip_validation: bool = False,
         start_scope: BaseScope | None = None,
+        skip_override: bool = False,
+        skip_cant_override: bool = False,
 ) -> AsyncContainer:
     registries = RegistryBuilder(
         scopes=scopes,
         container_type=AsyncContainer,
         providers=providers,
         skip_validation=skip_validation,
+        skip_override=skip_override,
+        skip_cant_override=skip_cant_override,
     ).build()
     container = AsyncContainer(
         *registries,
diff --git a/src/dishka/container.py b/src/dishka/container.py
index eef9034..8fdc4f7 100644
--- a/src/dishka/container.py
+++ b/src/dishka/container.py
@@ -194,12 +194,16 @@ def make_container(
         lock_factory: Callable[[], Lock] | None = None,
         skip_validation: bool = False,
         start_scope: BaseScope | None = None,
+        skip_override: bool = False,
+        skip_cant_override: bool = False,
 ) -> Container:
     registries = RegistryBuilder(
         scopes=scopes,
         container_type=Container,
         providers=providers,
         skip_validation=skip_validation,
+        skip_override=skip_override,
+        skip_cant_override=skip_cant_override,
     ).build()
     container = Container(
         *registries,
diff --git a/src/dishka/dependency_source/alias.py b/src/dishka/dependency_source/alias.py
index cf38611..db0e7d5 100644
--- a/src/dishka/dependency_source/alias.py
+++ b/src/dishka/dependency_source/alias.py
@@ -38,6 +38,7 @@ class Alias:
             kw_dependencies={},
             type_=FactoryType.ALIAS,
             cache=self.cache,
+            override=False,
         )
 
     def __get__(self, instance: Any, owner: Any) -> Alias:
diff --git a/src/dishka/dependency_source/context_var.py b/src/dishka/dependency_source/context_var.py
index 313bce4..8700e44 100644
--- a/src/dishka/dependency_source/context_var.py
+++ b/src/dishka/dependency_source/context_var.py
@@ -38,6 +38,7 @@ class ContextVariable:
                 kw_dependencies={},
                 type_=FactoryType.CONTEXT,
                 cache=False,
+                override=False,
             )
         else:
             aliased = Alias(
diff --git a/src/dishka/dependency_source/decorator.py b/src/dishka/dependency_source/decorator.py
index d1127e1..72419c0 100644
--- a/src/dishka/dependency_source/decorator.py
+++ b/src/dishka/dependency_source/decorator.py
@@ -52,6 +52,7 @@ class Decorator:
             },
             type_=self.factory.type,
             cache=cache,
+            override=False,
         )
 
     def __get__(self, instance: Any, owner: Any) -> Decorator:
diff --git a/src/dishka/dependency_source/factory.py b/src/dishka/dependency_source/factory.py
index 6dfa19d..4012f73 100644
--- a/src/dishka/dependency_source/factory.py
+++ b/src/dishka/dependency_source/factory.py
@@ -18,6 +18,7 @@ class Factory(FactoryData):
         "kw_dependencies",
         "is_to_bind",
         "cache",
+        "override",
     )
 
     def __init__(
@@ -31,6 +32,7 @@ class Factory(FactoryData):
             type_: FactoryType,
             is_to_bind: bool,
             cache: bool,
+            override: bool,
     ) -> None:
         super().__init__(
             source=source,
@@ -42,6 +44,7 @@ class Factory(FactoryData):
         self.kw_dependencies = kw_dependencies
         self.is_to_bind = is_to_bind
         self.cache = cache
+        self.override = override
 
     def __get__(self, instance: Any, owner: Any) -> Factory:
         scope = self.scope or instance.scope
@@ -62,6 +65,7 @@ class Factory(FactoryData):
             type_=self.type,
             is_to_bind=False,
             cache=self.cache,
+            override=self.override,
         )
 
     def with_component(self, component: Component) -> Factory:
@@ -79,4 +83,5 @@ class Factory(FactoryData):
             is_to_bind=self.is_to_bind,
             cache=self.cache,
             type_=self.type,
+            override=self.override,
         )
diff --git a/src/dishka/dependency_source/make_decorator.py b/src/dishka/dependency_source/make_decorator.py
index 3ab44a5..33736d4 100644
--- a/src/dishka/dependency_source/make_decorator.py
+++ b/src/dishka/dependency_source/make_decorator.py
@@ -22,6 +22,7 @@ def _decorate(
             source=source,
             cache=False,
             is_in_class=is_in_class,
+            override=False,
         ),
     )
     if (
diff --git a/src/dishka/dependency_source/make_factory.py b/src/dishka/dependency_source/make_factory.py
index 7b83b59..e3fa0aa 100644
--- a/src/dishka/dependency_source/make_factory.py
+++ b/src/dishka/dependency_source/make_factory.py
@@ -199,6 +199,7 @@ def _make_factory_by_class(
         scope: BaseScope | None,
         source: type,
         cache: bool,
+        override: bool,
 ) -> Factory:
     if not provides:
         provides = source
@@ -247,6 +248,7 @@ def _make_factory_by_class(
         provides=hint_to_dependency_key(provides),
         is_to_bind=False,
         cache=cache,
+        override=override,
     )
 
 
@@ -257,6 +259,7 @@ def _make_factory_by_function(
         source: Callable[..., Any] | classmethod, # type: ignore[type-arg]
         cache: bool,
         is_in_class: bool,
+        override: bool,
 ) -> Factory:
     # typing.cast is applied as unwrap takes a Callable object
     raw_source = unwrap(cast(Callable[..., Any], source))
@@ -318,6 +321,7 @@ def _make_factory_by_function(
         provides=hint_to_dependency_key(provides),
         is_to_bind=is_in_class,
         cache=cache,
+        override=override,
     )
 
 
@@ -327,6 +331,7 @@ def _make_factory_by_static_method(
         scope: BaseScope | None,
         source: staticmethod,  # type: ignore[type-arg]
         cache: bool,
+        override: bool,
 ) -> Factory:
     if missing_hints := _params_without_hints(source, skip_self=False):
         name = get_name(source, include_module=True)
@@ -378,6 +383,7 @@ def _make_factory_by_static_method(
         provides=hint_to_dependency_key(provides),
         is_to_bind=False,
         cache=cache,
+        override=override,
     )
 
 
@@ -387,6 +393,7 @@ def _make_factory_by_other_callable(
         scope: BaseScope | None,
         source: Callable[..., Any],
         cache: bool,
+        override: bool,
 ) -> Factory:
     if _is_bound_method(source):
         to_check = source.__func__  # type: ignore[attr-defined]
@@ -398,6 +405,7 @@ def _make_factory_by_other_callable(
         cache=cache,
         scope=scope,
         is_in_class=True,
+        override=override,
     )
     if factory.is_to_bind:
         dependencies = factory.dependencies[1:]  # remove `self`
@@ -412,6 +420,7 @@ def _make_factory_by_other_callable(
         provides=factory.provides,
         is_to_bind=False,
         cache=cache,
+        override=override,
     )
 
 
@@ -422,6 +431,7 @@ def make_factory(
         source: ProvideSource,
         cache: bool,
         is_in_class: bool,
+        override: bool,
 ) -> Factory:
     if is_bare_generic(source):
         source = source[get_type_vars(source)]  # type: ignore[index]
@@ -432,6 +442,7 @@ def make_factory(
             scope=scope,
             source=cast(type, source),
             cache=cache,
+            override=override,
         )
     elif isfunction(source) or isinstance(source, classmethod):
         return _make_factory_by_function(
@@ -440,6 +451,7 @@ def make_factory(
             source=source,
             cache=cache,
             is_in_class=is_in_class,
+            override=override,
         )
     elif isbuiltin(source):
         return _make_factory_by_function(
@@ -448,6 +460,7 @@ def make_factory(
             source=source,
             cache=cache,
             is_in_class=False,
+            override=override,
         )
     elif isinstance(source, staticmethod):
         return _make_factory_by_static_method(
@@ -455,6 +468,7 @@ def make_factory(
             scope=scope,
             source=source,
             cache=cache,
+            override=override,
         )
     elif callable(source):
         return _make_factory_by_other_callable(
@@ -462,6 +476,7 @@ def make_factory(
             scope=scope,
             source=source,
             cache=cache,
+            override=override,
         )
     else:
         raise TypeError(f"Cannot use {type(source)} as a factory")
@@ -475,12 +490,14 @@ def _provide(
         cache: bool = True,
         is_in_class: bool = True,
         recursive: bool = False,
+        override: bool = False,
 ) -> CompositeDependencySource:
     composite = ensure_composite(source)
     factory = make_factory(
         provides=provides, scope=scope,
         source=composite.origin, cache=cache,
         is_in_class=is_in_class,
+        override=override,
     )
     composite.dependency_sources.extend(unpack_factory(factory))
     if not recursive:
@@ -497,6 +514,7 @@ def _provide(
                 source=dependency.type_hint,
                 cache=cache,
                 is_in_class=is_in_class,
+                override=override,
             )
             composite.dependency_sources.extend(additional.dependency_sources)
     return composite
@@ -509,11 +527,12 @@ def provide_on_instance(
         provides: Any = None,
         cache: bool = True,
         recursive: bool = False,
+        override: bool = False,
 ) -> CompositeDependencySource:
     return _provide(
         provides=provides, scope=scope, source=source, cache=cache,
         is_in_class=False,
-        recursive=recursive,
+        recursive=recursive, override=override,
     )
 
 
@@ -524,6 +543,7 @@ def provide(
         provides: Any = None,
         cache: bool = True,
         recursive: bool = False,
+        override: bool = False,
 ) -> Callable[[Callable[..., Any]], CompositeDependencySource]:
     ...
 
@@ -536,6 +556,7 @@ def provide(
         provides: Any = None,
         cache: bool = True,
         recursive: bool = False,
+        override: bool = False,
 ) -> CompositeDependencySource:
     ...
 
@@ -547,6 +568,7 @@ def provide(
         provides: Any = None,
         cache: bool = True,
         recursive: bool = False,
+        override: bool = False,
 ) -> CompositeDependencySource | Callable[
     [Callable[..., Any]], CompositeDependencySource,
 ]:
@@ -567,20 +589,21 @@ def provide(
     :param source: Method to decorate or class.
     :param scope: Scope of the dependency to limit its lifetime
     :param provides: Dependency type which is provided by this factory
-    :return: instance of Factory or a decorator returning it
     :param cache: save created object to scope cache or not
     :param recursive: register dependencies as factories as well
+    :param override: dependency override
+    :return: instance of Factory or a decorator returning it
     """
     if source is not None:
         return _provide(
             provides=provides, scope=scope, source=source, cache=cache,
-            is_in_class=True, recursive=recursive,
+            is_in_class=True, recursive=recursive, override=override,
         )
 
     def scoped(func: Callable[..., Any]) -> CompositeDependencySource:
         return _provide(
             provides=provides, scope=scope, source=func, cache=cache,
-            is_in_class=True, recursive=recursive,
+            is_in_class=True, recursive=recursive, override=override,
         )
 
     return scoped
@@ -593,6 +616,7 @@ def _provide_all(
         cache: bool,
         is_in_class: bool,
         recursive: bool,
+        override: bool = False,
 ) -> CompositeDependencySource:
     composite = CompositeDependencySource(None)
     for single_provides in provides:
@@ -603,6 +627,7 @@ def _provide_all(
             cache=cache,
             is_in_class=is_in_class,
             recursive=recursive,
+            override=override,
         )
         composite.dependency_sources.extend(source.dependency_sources)
     return composite
@@ -613,11 +638,12 @@ def provide_all(
         scope: BaseScope | None = None,
         cache: bool = True,
         recursive: bool = False,
+        override: bool = False,
 ) -> CompositeDependencySource:
     return _provide_all(
         provides=provides, scope=scope,
         cache=cache, is_in_class=True,
-        recursive=recursive,
+        recursive=recursive, override=override,
     )
 
 
@@ -626,9 +652,10 @@ def provide_all_on_instance(
         scope: BaseScope | None = None,
         cache: bool = True,
         recursive: bool = False,
+        override: bool = False,
 ) -> CompositeDependencySource:
     return _provide_all(
         provides=provides, scope=scope,
         cache=cache, is_in_class=False,
-        recursive=recursive,
+        recursive=recursive, override=override,
     )
diff --git a/src/dishka/dependency_source/unpack_provides.py b/src/dishka/dependency_source/unpack_provides.py
index bb8cfc5..c11df77 100644
--- a/src/dishka/dependency_source/unpack_provides.py
+++ b/src/dishka/dependency_source/unpack_provides.py
@@ -31,6 +31,7 @@ def unpack_factory(factory: Factory) -> Sequence[DependencySource]:
             scope=factory.scope,
             is_to_bind=factory.is_to_bind,
             cache=factory.cache,
+            override=factory.override,
             provides=DependencyKey(
                 provides_first,
                 factory.provides.component,
diff --git a/src/dishka/exceptions.py b/src/dishka/exceptions.py
index 5e74f13..f8092d4 100644
--- a/src/dishka/exceptions.py
+++ b/src/dishka/exceptions.py
@@ -99,3 +99,35 @@ class NoFactoryError(DishkaError):
 
 class GraphMissingFactoryError(NoFactoryError, InvalidGraphError):
     pass
+
+
+class FactoryNotOverrideError(InvalidGraphError):
+    def __init__(self, factory: Factory) -> None:
+        self.factory = factory
+
+    def __str__(self) -> str:
+        name = get_name(self.factory.source, include_module=False)
+        return (
+            f"Factory {self.factory.provides} was found that "
+            "implicitly override factory.\n"
+            "Hint:\n"
+            f" * Specify the parameter override=True for {name}.\n"
+            " * Add skip_override=True to make_container"
+            " or make_async_container."
+        )
+
+
+class CantOverrideFactoryError(InvalidGraphError):
+    def __init__(self, factory: Factory) -> None:
+        self.factory = factory
+
+    def __str__(self) -> str:
+        name = get_name(self.factory.source, include_module=False)
+        return (
+            f"Can't override factory for {self.factory.provides}.\n"
+            "Hint:\n"
+            f" * Remove override=True from {name}.\n"
+            " * Add skip_cant_override=True to make_container"
+            " or make_async_container."
+        )
+
diff --git a/src/dishka/provider.py b/src/dishka/provider.py
index 5f2b173..0805179 100644
--- a/src/dishka/provider.py
+++ b/src/dishka/provider.py
@@ -137,6 +137,7 @@ class Provider(BaseProvider):
             provides: Any = None,
             cache: bool = True,
             recursive: bool = False,
+            override: bool = False,
     ) -> CompositeDependencySource:
         if scope is None:
             scope = self.scope
@@ -146,6 +147,7 @@ class Provider(BaseProvider):
             provides=provides,
             cache=cache,
             recursive=recursive,
+            override=override,
         )
         self._add_dependency_sources(str(source), composite.dependency_sources)
         return composite
@@ -156,11 +158,13 @@ class Provider(BaseProvider):
             scope: BaseScope | None = None,
             cache: bool = True,
             recursive: bool = False,
+            override: bool = False,
     ) -> CompositeDependencySource:
         if scope is None:
             scope = self.scope
         composite = provide_all_on_instance(
             *provides, scope=scope, cache=cache, recursive=recursive,
+            override=override,
         )
         self._add_dependency_sources("?", composite.dependency_sources)
         return composite
diff --git a/src/dishka/registry.py b/src/dishka/registry.py
index 8469b27..16a9b1b 100644
--- a/src/dishka/registry.py
+++ b/src/dishka/registry.py
@@ -16,7 +16,9 @@ from .entities.factory_type import FactoryType
 from .entities.key import DependencyKey
 from .entities.scope import BaseScope, InvalidScopes, Scope
 from .exceptions import (
+    CantOverrideFactoryError,
     CycleDependenciesError,
+    FactoryNotOverrideError,
     GraphMissingFactoryError,
     InvalidGraphError,
     NoFactoryError,
@@ -113,6 +115,7 @@ class Registry:
             type_=FactoryType.FACTORY,
             is_to_bind=False,
             cache=False,
+            override=False,
             source=lambda: typevar,
         )
 
@@ -160,6 +163,7 @@ class Registry:
             type_=factory.type,
             scope=factory.scope,
             cache=factory.cache,
+            override=factory.override,
         )
 
 
@@ -256,6 +260,8 @@ class RegistryBuilder:
             providers: Sequence[BaseProvider],
             container_type: type,
             skip_validation: bool,
+            skip_override: bool,
+            skip_cant_override: bool,
     ) -> None:
         self.scopes = scopes
         self.providers = providers
@@ -267,6 +273,9 @@ class RegistryBuilder:
         self.container_type = container_type
         self.decorator_depth: dict[DependencyKey, int] = defaultdict(int)
         self.skip_validation = skip_validation
+        self.skip_override = skip_override
+        self.skip_cant_override = skip_cant_override
+        self.override_factories: dict[DependencyKey, Factory] = {}
 
     def _collect_components(self) -> None:
         for provider in self.providers:
@@ -314,8 +323,22 @@ class RegistryBuilder:
     def _process_factory(
             self, provider: BaseProvider, factory: Factory,
     ) -> None:
+        factory = factory.with_component(provider.component)
+        provides = factory.provides
+        if (
+            not self.skip_cant_override
+            and factory.override
+            and provides not in self.override_factories
+        ):
+            raise CantOverrideFactoryError(factory)
+        if not self.skip_override and provides in self.override_factories:
+            if not factory.override:
+                raise FactoryNotOverrideError(factory)
+        else:
+            self.override_factories[provides] = factory
+
         registry = self.registries[cast(Scope, factory.scope)]
-        registry.add_factory(factory.with_component(provider.component))
+        registry.add_factory(factory)
 
     def _process_alias(
             self, provider: BaseProvider, alias: Alias,
diff --git a/src/dishka/text_rendering/path.py b/src/dishka/text_rendering/path.py
index f22e9ca..4ed5828 100644
--- a/src/dishka/text_rendering/path.py
+++ b/src/dishka/text_rendering/path.py
@@ -8,7 +8,6 @@ from dishka.text_rendering import get_name
 
 
 class PathRenderer:
-
     def _arrow_cycle(self, index: int, length: int) -> str:
         if length == 1:
             return "⥁"


Test patch:
diff --git a/tests/unit/container/test_decorator.py b/tests/unit/container/test_decorator.py
index 6a1f319..80742f6 100644
--- a/tests/unit/container/test_decorator.py
+++ b/tests/unit/container/test_decorator.py
@@ -176,7 +176,7 @@ def test_expected_decorator():
         def bar(self) -> A:
             return A()
 
-        @provide
+        @provide(override=True)
         def foo(self, a: A) -> A:
             return a
 
diff --git a/tests/unit/container/test_override.py b/tests/unit/container/test_override.py
new file mode 100644
index 0000000..65df8a3
--- /dev/null
+++ b/tests/unit/container/test_override.py
@@ -0,0 +1,85 @@
+import pytest
+
+from dishka import Provider, Scope, make_container, provide, provide_all
+from dishka.exceptions import CantOverrideFactoryError, FactoryNotOverrideError
+
+
+def test_not_override_provide() -> None:
+    class TestProvider(Provider):
+        scope = Scope.APP
+        provides = (
+            provide(int, provides=int)
+            + provide(int, provides=int)
+        )
+
+    with pytest.raises(FactoryNotOverrideError):
+        make_container(TestProvider())
+
+
+def test_skip_override_provide() -> None:
+    class TestProvider(Provider):
+        scope = Scope.APP
+        provides = (
+            provide(int, provides=int)
+            + provide(int, provides=int)
+        )
+
+    make_container(
+        TestProvider(),
+        skip_override=True,
+    )
+
+
+def test_override_provide() -> None:
+    class TestProvider(Provider):
+        scope = Scope.APP
+        provides = (
+            provide(int, provides=int)
+            + provide(int, provides=int, override=True)
+        )
+
+    make_container(TestProvider())
+
+
+def test_not_override_provide_all() -> None:
+    class TestProvider(Provider):
+        scope = Scope.APP
+        provides = (
+            provide_all(int, str)
+            + provide_all(int, str)
+        )
+
+    with pytest.raises(FactoryNotOverrideError):
+        make_container(TestProvider())
+
+
+def test_override_provide_all() -> None:
+    class TestProvider(Provider):
+        scope = Scope.APP
+        provides = (
+            provide_all(int, str)
+            + provide_all(int, str, override=True)
+        )
+
+    make_container(TestProvider())
+
+
+def test_cant_override() -> None:
+    class TestProvider(Provider):
+        scope = Scope.APP
+        provides = provide(int, provides=int, override=True)
+
+    with pytest.raises(CantOverrideFactoryError):
+        make_container(TestProvider())
+
+
+def test_skip_cant_override() -> None:
+    class TestProvider(Provider):
+        scope = Scope.APP
+        provides = provide(int, provides=int, override=True)
+
+    make_container(
+        TestProvider(),
+        skip_cant_override=True,
+    )
+
diff --git a/tests/unit/container/test_recursive.py b/tests/unit/container/test_recursive.py
index a45f951..aa2d918 100644
--- a/tests/unit/container/test_recursive.py
+++ b/tests/unit/container/test_recursive.py
@@ -61,7 +61,7 @@ def test_provide_all_class():
     class MyProvider(Provider):
         x = provide_all(B, C, scope=Scope.APP, recursive=True)
 
-    container = make_container(MyProvider())
+    container = make_container(MyProvider(), skip_override=True)
     b = container.get(B)
     assert isinstance(b, B)
     assert isinstance(b.a1, A1)
@@ -75,7 +75,7 @@ def test_provide_all_class():
 def test_provide_all_instance():
     provider = Provider(scope=Scope.APP)
     provider.provide_all(B, C, recursive=True)
-    container = make_container(provider)
+    container = make_container(provider, skip_override=True)
     b = container.get(B)
     assert isinstance(b, B)
     assert isinstance(b.a1, A1)
diff --git a/tests/unit/sample_providers.py b/tests/unit/sample_providers.py
index 26a0a52..25c2357 100644
--- a/tests/unit/sample_providers.py
+++ b/tests/unit/sample_providers.py
@@ -74,5 +74,6 @@ value_factory = Factory(
     scope=Scope.APP,
     is_to_bind=False,
     cache=False,
+    override=False,
 )
 value_source = CompositeDependencySource(lambda: None, [value_factory])
diff --git a/tests/unit/test_provider.py b/tests/unit/test_provider.py
index 3044e50..d49d351 100644
--- a/tests/unit/test_provider.py
+++ b/tests/unit/test_provider.py
@@ -91,6 +91,7 @@ def test_parse_factory_cls(source, provider_type, is_to_bound):
         cache=False,
         scope=Scope.REQUEST,
         is_in_class=False,
+        override=False,
     )
     assert factory.provides == hint_to_dependency_key(ClassA)
     assert factory.dependencies == hints_to_dependency_keys([int])
diff --git a/tests/unit/text_rendering/test_path.py b/tests/unit/text_rendering/test_path.py
index 91cd4f7..353544d 100644
--- a/tests/unit/text_rendering/test_path.py
+++ b/tests/unit/text_rendering/test_path.py
@@ -24,6 +24,7 @@ def test_cycle(renderer):
         cache=False,
         scope=None,
         is_in_class=True,
+        override=False,
     )
 
     res = renderer.render([factory, factory, factory])
@@ -44,6 +45,7 @@ def test_cycle_1(renderer):
         cache=False,
         scope=None,
         is_in_class=True,
+        override=False,
     )
 
     res = renderer.render([factory])
@@ -62,6 +64,7 @@ def test_linear(renderer):
         cache=False,
         scope=None,
         is_in_class=True,
+        override=False,
     )
 
     res = renderer.render([factory, factory], last=factory.provides)