Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Making injections into class attributes can't work with Resource in nested container. #873

Open
YogiLiu opened this issue Mar 23, 2025 · 2 comments

Comments

@YogiLiu
Copy link

YogiLiu commented Mar 23, 2025

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
Copy link
Contributor

ZipFile commented Mar 23, 2025

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
Copy link
Author

YogiLiu commented Mar 23, 2025

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants