61
61
# is installed.
62
62
from pydantic import PyObject
63
63
64
- # prevent unbound variable warnings
64
+ # Prevent unbound variable warnings
65
65
BaseModelV2 = BaseModelV1
66
66
UndefinedV2 = Undefined
67
+
68
+ if TYPE_CHECKING :
69
+ from pydantic .dataclasses import Dataclass as PydanticDataclassV1 # pyright: ignore[reportPrivateImportUsage]
70
+
71
+ # Prevent unbound variable warnings
72
+ PydanticDataclassV2 = PydanticDataclassV1
67
73
except ImportError :
68
74
# pydantic v2
69
75
92
98
from pydantic .v1 .color import Color # type: ignore[assignment]
93
99
from pydantic .v1 .fields import DeferredType , ModelField , Undefined
94
100
101
+ if TYPE_CHECKING :
102
+ from pydantic .dataclasses import PydanticDataclass as PydanticDataclassV2 # pyright: ignore[reportPrivateImportUsage]
95
103
96
104
if TYPE_CHECKING :
97
105
from collections import abc
100
108
101
109
from typing_extensions import NotRequired , TypeGuard
102
110
103
- from pydantic .dataclasses import PydanticDataclass # pyright: ignore[reportPrivateImportUsage]
104
111
105
112
ModelT = TypeVar ("ModelT" , bound = "BaseModelV1 | BaseModelV2" ) # pyright: ignore[reportInvalidTypeForm]
106
113
T = TypeVar ("T" )
@@ -627,8 +634,11 @@ def _is_pydantic_v2_model(model: Any) -> TypeGuard[BaseModelV2]: # pyright: ign
627
634
return not _IS_PYDANTIC_V1 and is_safe_subclass (model , BaseModelV2 )
628
635
629
636
630
- def is_pydantic_dataclass (cls : type [Any ]) -> TypeGuard [PydanticDataclass ]:
631
- # This method is available in the `pydantic.dataclasses` module for python >= 3.9
637
+ def _is_pydantic_v1_dataclass (cls : type [Any ]) -> TypeGuard [PydanticDataclassV1 ]:
638
+ return is_dataclass (cls ) and "__pydantic_model__" in cls .__dict__
639
+
640
+
641
+ def _is_pydantic_v2_dataclass (cls : type [Any ]) -> TypeGuard [PydanticDataclassV2 ]:
632
642
return is_dataclass (cls ) and "__pydantic_validator__" in cls .__dict__
633
643
634
644
@@ -639,27 +649,37 @@ class PydanticDataclassFactory(ModelFactory[T]): # type: ignore[type-var]
639
649
640
650
@classmethod
641
651
def is_supported_type (cls , value : Any ) -> TypeGuard [type [T ]]:
642
- return is_pydantic_dataclass (value )
652
+ return _is_pydantic_v1_dataclass ( value ) or _is_pydantic_v2_dataclass (value )
643
653
644
654
@classmethod
645
655
def get_model_fields (cls ) -> list [FieldMeta ]:
646
- if not is_pydantic_dataclass (cls .__model__ ):
656
+ if _is_pydantic_v1_dataclass (cls .__model__ ):
657
+ pydantic_model = cls .__model__ .__pydantic_model__
658
+ cls ._fields_metadata = [
659
+ PydanticFieldMeta .from_model_field (
660
+ field ,
661
+ use_alias = not pydantic_model .__config__ .allow_population_by_field_name , # type: ignore[attr-defined]
662
+ random = cls .__random__ ,
663
+ )
664
+ for field in pydantic_model .__fields__ .values ()
665
+ ]
666
+ elif _is_pydantic_v2_dataclass (cls .__model__ ):
667
+ pydantic_fields = cls .__model__ .__pydantic_fields__
668
+ pydantic_config = cls .__model__ .__pydantic_config__
669
+ cls ._fields_metadata = [
670
+ PydanticFieldMeta .from_field_info (
671
+ field_info = field_info ,
672
+ field_name = field_name ,
673
+ random = cls .__random__ ,
674
+ use_alias = not pydantic_config .get (
675
+ "populate_by_name" ,
676
+ False ,
677
+ ),
678
+ )
679
+ for field_name , field_info in pydantic_fields .items ()
680
+ ]
681
+ else :
647
682
# This should be unreachable
648
683
return []
649
684
650
- pydantic_fields = cls .__model__ .__pydantic_fields__
651
- pydantic_config = cls .__model__ .__pydantic_config__
652
- cls ._fields_metadata = [
653
- PydanticFieldMeta .from_field_info (
654
- field_info = field_info ,
655
- field_name = field_name ,
656
- random = cls .__random__ ,
657
- use_alias = not pydantic_config .get (
658
- "populate_by_name" ,
659
- False ,
660
- ),
661
- )
662
- for field_name , field_info in pydantic_fields .items ()
663
- ]
664
-
665
685
return cls ._fields_metadata
0 commit comments