ets-labs/python-dependency-injector

Copying a container fails if a `pydantic-settings`-based configuration is overridden

Opened this issue · 1 comments

Package versions:

dependencies = [
    "dependency-injector>=4.45.0",
    "pydantic>=2.10.6",
    "pydantic-settings>=2.7.1",
]

Example code:

from dependency_injector import containers, providers
from pydantic_settings import BaseSettings


class Container(containers.DeclarativeContainer):
    config = providers.Configuration()


# This one will work:
class OverriddeContainer(Container):
    config = providers.Configuration(
        default={"foo": "bar"}
    )


class Config(BaseSettings):
    bla: str = "nja"


class Container2(containers.DeclarativeContainer):
    config = providers.Configuration(pydantic_settings=[Config()])


# this one will work:
@containers.copy(Container2)
class OverriddeContainer2(Container2):
    config2 = providers.Configuration(
        pydantic_settings=[Config(bla="foo")]
    )


# this one will fail:
@containers.copy(Container2)
class OverriddeContainer3(Container2):
    config = providers.Configuration(
        pydantic_settings=[Config(bla="foo")]
    )

Error thrown:

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/milos/projects/di-test/src/ditest/__main__.py", line 32, in <module>
    @containers.copy(Container2)
     ^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "src/dependency_injector/containers.pyx", line 871, in dependency_injector.containers.copy._decorator
  File "src/dependency_injector/containers.pyx", line 865, in dependency_injector.containers.copy._get_memo_for_matching_names
  File "src/dependency_injector/containers.pyx", line 858, in dependency_injector.containers.copy._get_memo_for_matching_names
TypeError: 'NoneType' object is not iterable

Thought you might want to know.

Love the library btw.

EDIT:

Tried to mess with Cython magic a bit, but this is a bit too much for me at the moment. The best I was able to do is:

Image

...which makes it work:

Image

...but I'm not really confident this would be a right solution, looks like the error could be something deeper.

+1 bump