Skip to content

Self provider not being copied by @copy #619

Open
@Qjammer

Description

@Qjammer

It seems the Self provider is not being copied properly. Consider the following:

class A(containers.DeclarativeContainer):
    __self__ = providers.Self()
    dep = providers.Singleton(dict, container=__self__)

@containers.copy(A)
class CopyA(A):
    # __self__ = providers.Self()
    # A.__self__.override(__self__)
    # Neither of these two lines fix the problem
    pass

container = CopyA()
dep = container.dep()
print(container)
print(dep["container"])

Expected output: Both containers are the same instance

<dependency_injector.containers.DynamicContainer object at 0x7f7ad44a94b0>
<dependency_injector.containers.DynamicContainer object at 0x7f7ad44a94b0>

Actual output: First one is container, second is the class name of the original non-copied container

<dependency_injector.containers.DynamicContainer object at 0x7f7ad44a94b0>
<class '__main__.A'>

The commented lines don't fix the issue. It only changes the second output to be:

<class '__main__.CopyA'>

The following two fragments work as expected:

Composition of containers:

class A(containers.DeclarativeContainer):
    __self__ = providers.Self()
    dep = providers.Singleton(dict, container=__self__)


class ComposedA(containers.DeclarativeContainer):
    __self__ = providers.Self()
    a = providers.Container(A, __self__=__self__)

container = ComposedA()
dep = container.a.dep()
print(container)        # <dependency_injector.containers.DynamicContainer object at 0x7f7ad44a94b0>
print(dep["container"]) # <dependency_injector.containers.DynamicContainer object at 0x7f7ad44a94b0>

Copy of provider that is not Self:

class A(containers.DeclarativeContainer):
    __self__ = providers.Self()
    dep = providers.Singleton(dict, container=__self__)


@containers.copy(A)
class CopyDepA(A):
    str = providers.Singleton(str, "overridden_value")
    A.dep = providers.Singleton(dict, container=str)
    # The following method also works
    # A.dep.override(providers.Singleton(dict, container=str))

container = CopyDepA()
value = container.str()
dep = container.dep()
print(value)            # overridden_value
print(dep["container"]) # overridden_value

Could it be that the Self provider is not being copied? I read this in the docs:

Provider Self is not listed in container .providers attributes.

The implementation of @copy uses the .providers attribute to get the providers to copy. Could this be the issue?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions