[BUG] wire() fails when module imports a mutable Pydantic dataclass with pydantic @classmethod @field_validator
Closed this issue · 5 comments
MCVE
- models.py (Defines the pydantic dataclass)
from pydantic import field_validator
from pydantic.dataclasses import dataclass
@dataclass(slots=True)
class Data:
a: str
@classmethod
@field_validator("a")
def check_module_id(cls, v):
...- services.py (Defines the wired service module, importing the Pydantic model)
from dependency_injector.wiring import inject, Provide
from .container import Container
from .models import ProblematicModel # <--- Key: Pydantic model is directly imported
@inject
def my_example_service(
dummy_config_value=Provide[Container.config.some_setting]
):
...- main.py
from .container import Container
from . import services # Import the services module
if __name__ == "__main__":
container = Container()
container.wire(modules=["services"] # <-- raiseExpected Behavior
Traceback (most recent call last):
File "/Users/colas/Work/infra/case/case/main.py", line 5, in <module>
containers.wire(
~~~~~~~~~~~~~~~^
modules=["service"]
^^^^^^^^^^^^^^^^^^^
)
^
File "src/dependency_injector/containers.pyx", line 315, in dependency_injector.containers.DynamicContainer.wire
File "/Users/colas/Work/infra/case/.venv/lib/python3.13/site-packages/dependency_injector/wiring.py", line 454, in wire
_patch_method(
~~~~~~~~~~~~~^
cls, cls_member_name, cls_member, providers_map
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
)
^
File "/Users/colas/Work/infra/case/.venv/lib/python3.13/site-packages/dependency_injector/wiring.py", line 532, in _patch_method
if not _is_patched(fn):
~~~~~~~~~~~^^^^
File "/Users/colas/Work/infra/case/.venv/lib/python3.13/site-packages/dependency_injector/wiring.py", line 742, in _is_patched
return _patched_registry.has_callable(fn)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^
File "/Users/colas/Work/infra/case/.venv/lib/python3.13/site-packages/dependency_injector/wiring.py", line 130, in has_callable
return fn in self._callables
^^^^^^^^^^^^^^^^^^^^^
TypeError: unhashable type: 'PydanticDescriptorProxyEnvironment
- python: 3.13
- pydantic 2.11.4
- pydantic-core 2.33.2
- dependency-injector 4.46.0
I'm not sure if this is a bug, because the way you define field validator is not how Pydantic expects field validators to be defined.
So fix for your issue is either:
- Swap
@classmethodand@field_validator. - Remove
@classmethodaltogether. - Use new
Annotated-based way of defining field validators.
I'm not sure if this is a bug, because the way you define field validator is not how Pydantic expects field validators to be defined.
So fix for your issue is either:
- Swap
@classmethodand@field_validator.- Remove
@classmethodaltogether.- Use new
Annotated-based way of defining field validators.
Alright, that was my mistake. Before using DI, the code worked fine. Now, with @field_validator and @classmethod in the right order, everything is running smoothly.
Thanks for your help. This framework has been incredibly helpful for me.
Before using DI, the code worked fine.
I strongly suggest to verify if it did. If you put @classmethod at the top, Pydantic will ignore your field validator. Here's the code to verify:
Code
@dataclass(slots=True)
class Foo:
a: str
@classmethod
@field_validator("a")
def check_module_id(cls, v):
raise ValueError("nope")
Foo(a="test") # nothing happensvs
@dataclass(slots=True)
class Foo:
a: str
@field_validator("a")
@classmethod
def check_module_id(cls, v):
raise ValueError("nope")
Foo(a="test") # raises ValidationError, as expected在使用 DI 之前,代码运行良好。
我强烈建议您验证一下是否有效。如果您将其放在
@classmethod顶部,Pydantic 将忽略您的字段验证器。以下是验证代码:代码
@DataClass(slots=True)
class Foo:
a: str@classmethod @field_validator("a") def check_module_id(cls, v): raise ValueError("nope")Foo(a="test") # nothing happens
对比@DataClass(slots=True)
class Foo:
a: str@field_validator("a") @classmethod def check_module_id(cls, v): raise ValueError("nope")Foo(a="test") # raises ValidationError, as expected
The bad news is it seems I've been using invalid validators all along🫠. Thanks for pointing that out.
it's great help!!!