Making injections into class attributes can't work with `Resource` in nested container.
Opened this issue · 2 comments
YogiLiu commented
Reproducible project: https://github.com/YogiLiu/pdi_issue
When I run python -m pdi_issue.main, an error was raised:
Traceback (most recent call last):
File "<frozen runpy>", line 198, in _run_module_as_main
File "<frozen runpy>", line 88, in _run_code
File "/home/yogiliu/Workspace/YogiLiu/pdi_issue/src/pdi_issue/main.py", line 4, in <module>
container = SrvContainer()
^^^^^^^^^^^^^^
File "src/dependency_injector/containers.pyx", line 727, in dependency_injector.containers.DeclarativeContainer.__new__
File "src/dependency_injector/providers.pyx", line 4916, in dependency_injector.providers.deepcopy
File "src/dependency_injector/providers.pyx", line 4923, in dependency_injector.providers.deepcopy
File "/home/yogiliu/.local/share/uv/python/cpython-3.11.10-linux-x86_64-gnu/lib/python3.11/copy.py", line 146, in deepcopy
y = copier(x, memo)
^^^^^^^^^^^^^^^
File "/home/yogiliu/.local/share/uv/python/cpython-3.11.10-linux-x86_64-gnu/lib/python3.11/copy.py", line 231, in _deepcopy_dict
y[deepcopy(key, memo)] = deepcopy(value, memo)
^^^^^^^^^^^^^^^^^^^^^
File "/home/yogiliu/.local/share/uv/python/cpython-3.11.10-linux-x86_64-gnu/lib/python3.11/copy.py", line 153, in deepcopy
y = copier(memo)
^^^^^^^^^^^^
File "src/dependency_injector/providers.pyx", line 4024, in dependency_injector.providers.Container.__deepcopy__
File "src/dependency_injector/providers.pyx", line 4923, in dependency_injector.providers.deepcopy
File "/home/yogiliu/.local/share/uv/python/cpython-3.11.10-linux-x86_64-gnu/lib/python3.11/copy.py", line 153, in deepcopy
y = copier(memo)
^^^^^^^^^^^^
File "src/dependency_injector/containers.pyx", line 125, in dependency_injector.containers.DynamicContainer.__deepcopy__
File "src/dependency_injector/providers.pyx", line 4916, in dependency_injector.providers.deepcopy
File "src/dependency_injector/providers.pyx", line 4923, in dependency_injector.providers.deepcopy
File "/home/yogiliu/.local/share/uv/python/cpython-3.11.10-linux-x86_64-gnu/lib/python3.11/copy.py", line 146, in deepcopy
y = copier(x, memo)
^^^^^^^^^^^^^^^
File "/home/yogiliu/.local/share/uv/python/cpython-3.11.10-linux-x86_64-gnu/lib/python3.11/copy.py", line 231, in _deepcopy_dict
y[deepcopy(key, memo)] = deepcopy(value, memo)
^^^^^^^^^^^^^^^^^^^^^
File "/home/yogiliu/.local/share/uv/python/cpython-3.11.10-linux-x86_64-gnu/lib/python3.11/copy.py", line 153, in deepcopy
y = copier(memo)
^^^^^^^^^^^^
File "src/dependency_injector/providers.pyx", line 3669, in dependency_injector.providers.Resource.__deepcopy__
dependency_injector.errors.Error: Can not copy initialized resource
ZipFile commented
Thanks for the report. Nested containers and wiring is an area we can improve. No ETA when we'll work on it, but in the mean time, try doing so:
diff
diff --git a/src/pdi_issue/container.py b/src/pdi_issue/container.py
index e4485ec..47f75ef 100644
--- a/src/pdi_issue/container.py
+++ b/src/pdi_issue/container.py
@@ -6,8 +6,6 @@ def create_engine():
class RepoContainer(containers.DeclarativeContainer):
- wiring_config = containers.WiringConfiguration(modules=['.repo'])
-
engine = providers.Resource(create_engine)
# engine = providers.Factory(lambda: 'database engine')
@@ -15,4 +13,6 @@ class RepoContainer(containers.DeclarativeContainer):
class SrvContainer(containers.DeclarativeContainer):
+ wiring_config = containers.WiringConfiguration(modules=['.repo'])
+
repo = providers.Container(RepoContainer)
diff --git a/src/pdi_issue/repo.py b/src/pdi_issue/repo.py
index e34a497..e78df19 100644
--- a/src/pdi_issue/repo.py
+++ b/src/pdi_issue/repo.py
@@ -2,7 +2,7 @@ from dependency_injector.wiring import Provide
class UserRepo:
- engine = Provide['engine']
+ engine = Provide['repo.engine']
def do_something(self):
print(self.engine)YogiLiu commented
Thanks for reply.
To be honest, there are many solutions for this case, like injecting as params of __init__ method. So, I think this is a quite special case. It must be great if it's supported.
Thanks for your contributions.