Coverage for pydantic/dataclasses.py: 98.43%

91 statements  

« prev     ^ index     » next       coverage.py v7.5.4, created at 2024-07-03 19:29 +0000

1"""Provide an enhanced dataclass that performs validation.""" 

2 

3from __future__ import annotations as _annotations 1ABCDbcuvdefgtaEFGHhiwxjklmUVOPQRSTMNIJKLnoyzpqrs

4 

5import dataclasses 1ABCDbcuvdefgtaEFGHhiwxjklmUVOPQRSTMNIJKLnoyzpqrs

6import sys 1ABCDbcuvdefgtaEFGHhiwxjklmUVOPQRSTMNIJKLnoyzpqrs

7import types 1ABCDbcuvdefgtaEFGHhiwxjklmUVOPQRSTMNIJKLnoyzpqrs

8from typing import TYPE_CHECKING, Any, Callable, Generic, NoReturn, TypeVar, overload 1ABCDbcuvdefgtaEFGHhiwxjklmUVOPQRSTMNIJKLnoyzpqrs

9 

10from typing_extensions import Literal, TypeGuard, dataclass_transform 1ABCDbcuvdefgtaEFGHhiwxjklmUVOPQRSTMNIJKLnoyzpqrs

11 

12from ._internal import _config, _decorators, _typing_extra 1ABCDbcuvdefgtaEFGHhiwxjklmUVOPQRSTMNIJKLnoyzpqrs

13from ._internal import _dataclasses as _pydantic_dataclasses 1ABCDbcuvdefgtaEFGHhiwxjklmUVOPQRSTMNIJKLnoyzpqrs

14from ._migration import getattr_migration 1ABCDbcuvdefgtaEFGHhiwxjklmUVOPQRSTMNIJKLnoyzpqrs

15from .config import ConfigDict 1ABCDbcuvdefgtaEFGHhiwxjklmUVOPQRSTMNIJKLnoyzpqrs

16from .errors import PydanticUserError 1ABCDbcuvdefgtaEFGHhiwxjklmUVOPQRSTMNIJKLnoyzpqrs

17from .fields import Field, FieldInfo, PrivateAttr 1ABCDbcuvdefgtaEFGHhiwxjklmUVOPQRSTMNIJKLnoyzpqrs

18 

19if TYPE_CHECKING: 1ABCDbcuvdefgtaEFGHhiwxjklmUVOPQRSTMNIJKLnoyzpqrs

20 from ._internal._dataclasses import PydanticDataclass 

21 

22__all__ = 'dataclass', 'rebuild_dataclass' 1ABCDbcuvdefgtaEFGHhiwxjklmUVOPQRSTMNIJKLnoyzpqrs

23 

24_T = TypeVar('_T') 1ABCDbcuvdefgtaEFGHhiwxjklmUVOPQRSTMNIJKLnoyzpqrs

25 

26if sys.version_info >= (3, 10): 1ABCDbcuvdefgtaEFGHhiwxjklmUVOPQRSTMNIJKLnoyzpqrs

27 

28 @dataclass_transform(field_specifiers=(dataclasses.field, Field, PrivateAttr)) 1bcuvdefgahiwxjklmOPQRSTMNnoyzpqrs

29 @overload 1bcuvdefgahiwxjklmOPQRSTMNnoyzpqrs

30 def dataclass( 1bcuvdefgahiwxjklmOPQRSTMNnoyzpqrs

31 *, 

32 init: Literal[False] = False, 1bcuvdefgahiwxjklmOPQRSTMNnoyzpqrs

33 repr: bool = True, 1bcuvdefgahiwxjklmOPQRSTMNnoyzpqrs

34 eq: bool = True, 1bcuvdefgahiwxjklmOPQRSTMNnoyzpqrs

35 order: bool = False, 1bcuvdefgahiwxjklmOPQRSTMNnoyzpqrs

36 unsafe_hash: bool = False, 1bcuvdefgahiwxjklmOPQRSTMNnoyzpqrs

37 frozen: bool = False, 1bcuvdefgahiwxjklmOPQRSTMNnoyzpqrs

38 config: ConfigDict | type[object] | None = None, 1bcuvdefgahiwxjklmOPQRSTMNnoyzpqrs

39 validate_on_init: bool | None = None, 1bcuvdefgahiwxjklmOPQRSTMNnoyzpqrs

40 kw_only: bool = ..., 1bcuvdefgahiwxjklmOPQRSTMNnoyzpqrs

41 slots: bool = ..., 1bcuvdefgahiwxjklmOPQRSTMNnoyzpqrs

42 ) -> Callable[[type[_T]], type[PydanticDataclass]]: # type: ignore 1defgajklmMNpqrs

43 ... 

44 

45 @dataclass_transform(field_specifiers=(dataclasses.field, Field, PrivateAttr)) 1bcuvdefgahiwxjklmOPQRSTMNnoyzpqrs

46 @overload 1bcuvdefgahiwxjklmOPQRSTMNnoyzpqrs

47 def dataclass( 1bcuvdefgahiwxjklmOPQRSTMNnoyzpqrs

48 _cls: type[_T], # type: ignore 1defgajklmMNpqrs

49 *, 

50 init: Literal[False] = False, 1bcuvdefgahiwxjklmOPQRSTMNnoyzpqrs

51 repr: bool = True, 1bcuvdefgahiwxjklmOPQRSTMNnoyzpqrs

52 eq: bool = True, 1bcuvdefgahiwxjklmOPQRSTMNnoyzpqrs

53 order: bool = False, 1bcuvdefgahiwxjklmOPQRSTMNnoyzpqrs

54 unsafe_hash: bool = False, 1bcuvdefgahiwxjklmOPQRSTMNnoyzpqrs

55 frozen: bool = False, 1bcuvdefgahiwxjklmOPQRSTMNnoyzpqrs

56 config: ConfigDict | type[object] | None = None, 1bcuvdefgahiwxjklmOPQRSTMNnoyzpqrs

57 validate_on_init: bool | None = None, 1bcuvdefgahiwxjklmOPQRSTMNnoyzpqrs

58 kw_only: bool = ..., 1bcuvdefgahiwxjklmOPQRSTMNnoyzpqrs

59 slots: bool = ..., 1bcuvdefgahiwxjklmOPQRSTMNnoyzpqrs

60 ) -> type[PydanticDataclass]: ... 1defgajklmMNpqrs

61 

62else: 

63 

64 @dataclass_transform(field_specifiers=(dataclasses.field, Field, PrivateAttr)) 1ABCDtEFGHUVIJKL

65 @overload 1ABCDtEFGHUVIJKL

66 def dataclass( 1ABCDtEFGHUVIJKL

67 *, 

68 init: Literal[False] = False, 1ABCDtEFGHUVIJKL

69 repr: bool = True, 1ABCDtEFGHUVIJKL

70 eq: bool = True, 1ABCDtEFGHUVIJKL

71 order: bool = False, 1ABCDtEFGHUVIJKL

72 unsafe_hash: bool = False, 1ABCDtEFGHUVIJKL

73 frozen: bool = False, 1ABCDtEFGHUVIJKL

74 config: ConfigDict | type[object] | None = None, 1ABCDtEFGHUVIJKL

75 validate_on_init: bool | None = None, 1ABCDtEFGHUVIJKL

76 ) -> Callable[[type[_T]], type[PydanticDataclass]]: # type: ignore 1t

77 ... 

78 

79 @dataclass_transform(field_specifiers=(dataclasses.field, Field, PrivateAttr)) 1ABCDtEFGHUVIJKL

80 @overload 1ABCDtEFGHUVIJKL

81 def dataclass( 1ABCDtEFGHUVIJKL

82 _cls: type[_T], # type: ignore 1t

83 *, 

84 init: Literal[False] = False, 1ABCDtEFGHUVIJKL

85 repr: bool = True, 1ABCDtEFGHUVIJKL

86 eq: bool = True, 1ABCDtEFGHUVIJKL

87 order: bool = False, 1ABCDtEFGHUVIJKL

88 unsafe_hash: bool = False, 1ABCDtEFGHUVIJKL

89 frozen: bool = False, 1ABCDtEFGHUVIJKL

90 config: ConfigDict | type[object] | None = None, 1ABCDtEFGHUVIJKL

91 validate_on_init: bool | None = None, 1ABCDtEFGHUVIJKL

92 ) -> type[PydanticDataclass]: ... 1t

93 

94 

95@dataclass_transform(field_specifiers=(dataclasses.field, Field, PrivateAttr)) 1ABCDbcuvdefgtaEFGHhiwxjklmUVOPQRSTMNIJKLnoyzpqrs

96def dataclass( # noqa: C901 1ABCDbcuvdefgEFGHhiwxjklmUVOPQRSTMNIJKLnoyzpqrs

97 _cls: type[_T] | None = None, 

98 *, 

99 init: Literal[False] = False, 

100 repr: bool = True, 

101 eq: bool = True, 

102 order: bool = False, 

103 unsafe_hash: bool = False, 

104 frozen: bool = False, 

105 config: ConfigDict | type[object] | None = None, 

106 validate_on_init: bool | None = None, 

107 kw_only: bool = False, 

108 slots: bool = False, 

109) -> Callable[[type[_T]], type[PydanticDataclass]] | type[PydanticDataclass]: 

110 """Usage docs: https://docs.pydantic.dev/2.8/concepts/dataclasses/ 

111 

112 A decorator used to create a Pydantic-enhanced dataclass, similar to the standard Python `dataclass`, 

113 but with added validation. 

114 

115 This function should be used similarly to `dataclasses.dataclass`. 

116 

117 Args: 

118 _cls: The target `dataclass`. 

119 init: Included for signature compatibility with `dataclasses.dataclass`, and is passed through to 

120 `dataclasses.dataclass` when appropriate. If specified, must be set to `False`, as pydantic inserts its 

121 own `__init__` function. 

122 repr: A boolean indicating whether to include the field in the `__repr__` output. 

123 eq: Determines if a `__eq__` method should be generated for the class. 

124 order: Determines if comparison magic methods should be generated, such as `__lt__`, but not `__eq__`. 

125 unsafe_hash: Determines if a `__hash__` method should be included in the class, as in `dataclasses.dataclass`. 

126 frozen: Determines if the generated class should be a 'frozen' `dataclass`, which does not allow its 

127 attributes to be modified after it has been initialized. 

128 config: The Pydantic config to use for the `dataclass`. 

129 validate_on_init: A deprecated parameter included for backwards compatibility; in V2, all Pydantic dataclasses 

130 are validated on init. 

131 kw_only: Determines if `__init__` method parameters must be specified by keyword only. Defaults to `False`. 

132 slots: Determines if the generated class should be a 'slots' `dataclass`, which does not allow the addition of 

133 new attributes after instantiation. 

134 

135 Returns: 

136 A decorator that accepts a class as its argument and returns a Pydantic `dataclass`. 

137 

138 Raises: 

139 AssertionError: Raised if `init` is not `False` or `validate_on_init` is `False`. 

140 """ 

141 assert init is False, 'pydantic.dataclasses.dataclass only supports init=False' 1ABCDbcuvdefgtaEFGHhiwxjklmUVOPQRSTMNIJKLnoyzpqrs

142 assert validate_on_init is not False, 'validate_on_init=False is no longer supported' 1ABCDbcuvdefgtaEFGHhiwxjklmUVOPQRSTMNIJKLnoyzpqrs

143 

144 if sys.version_info >= (3, 10): 1ABCDbcuvdefgtaEFGHhiwxjklmUVOPQRSTMNIJKLnoyzpqrs

145 kwargs = dict(kw_only=kw_only, slots=slots) 1bcuvdefgahiwxjklmOPQRSTMNnoyzpqrs

146 else: 

147 kwargs = {} 1ABCDtEFGHUVIJKL

148 

149 def make_pydantic_fields_compatible(cls: type[Any]) -> None: 1ABCDbcuvdefgtaEFGHhiwxjklmUVOPQRSTMNIJKLnoyzpqrs

150 """Make sure that stdlib `dataclasses` understands `Field` kwargs like `kw_only` 

151 To do that, we simply change 

152 `x: int = pydantic.Field(..., kw_only=True)` 

153 into 

154 `x: int = dataclasses.field(default=pydantic.Field(..., kw_only=True), kw_only=True)` 

155 """ 

156 for annotation_cls in cls.__mro__: 1ABCDbcuvdefgtaEFGHhiwxjklmUVOPQRSTMNIJKLnoyzpqrs

157 # In Python < 3.9, `__annotations__` might not be present if there are no fields. 

158 # we therefore need to use `getattr` to avoid an `AttributeError`. 

159 annotations = getattr(annotation_cls, '__annotations__', []) 1ABCDbcuvdefgtaEFGHhiwxjklmUVOPQRSTMNIJKLnoyzpqrs

160 for field_name in annotations: 1ABCDbcuvdefgtaEFGHhiwxjklmUVOPQRSTMNIJKLnoyzpqrs

161 field_value = getattr(cls, field_name, None) 1ABCDbcuvdefgtaEFGHhiwxjklmUVOPQRSTMNIJKLnoyzpqrs

162 # Process only if this is an instance of `FieldInfo`. 

163 if not isinstance(field_value, FieldInfo): 1ABCDbcuvdefgtaEFGHhiwxjklmUVOPQRSTMNIJKLnoyzpqrs

164 continue 1ABCDbcuvdefgtaEFGHhiwxjklmUVOPQRSTMNIJKLnoyzpqrs

165 

166 # Initialize arguments for the standard `dataclasses.field`. 

167 field_args: dict = {'default': field_value} 1ABCDbcuvdefgtaEFGHhiwxjklmIJKLnoyzpqrs

168 

169 # Handle `kw_only` for Python 3.10+ 

170 if sys.version_info >= (3, 10) and field_value.kw_only: 1ABCDbcuvdefgtaEFGHhiwxjklmIJKLnoyzpqrs

171 field_args['kw_only'] = True 1bcuvdefgahiwxjklmnoyzpqrs

172 

173 # Set `repr` attribute if it's explicitly specified to be not `True`. 

174 if field_value.repr is not True: 1ABCDbcuvdefgtaEFGHhiwxjklmIJKLnoyzpqrs

175 field_args['repr'] = field_value.repr 1ABCDbcuvdefgtaEFGHhiwxjklmIJKLnoyzpqrs

176 

177 setattr(cls, field_name, dataclasses.field(**field_args)) 1ABCDbcuvdefgtaEFGHhiwxjklmIJKLnoyzpqrs

178 # In Python 3.8, dataclasses checks cls.__dict__['__annotations__'] for annotations, 

179 # so we must make sure it's initialized before we add to it. 

180 if cls.__dict__.get('__annotations__') is None: 1ABCDbcuvdefgtaEFGHhiwxjklmIJKLnoyzpqrs

181 cls.__annotations__ = {} 1ABCDtEFGHIJKL

182 cls.__annotations__[field_name] = annotations[field_name] 1ABCDbcuvdefgtaEFGHhiwxjklmIJKLnoyzpqrs

183 

184 def create_dataclass(cls: type[Any]) -> type[PydanticDataclass]: 1ABCDbcuvdefgtaEFGHhiwxjklmUVOPQRSTMNIJKLnoyzpqrs

185 """Create a Pydantic dataclass from a regular dataclass. 

186 

187 Args: 

188 cls: The class to create the Pydantic dataclass from. 

189 

190 Returns: 

191 A Pydantic dataclass. 

192 """ 

193 from ._internal._utils import is_model_class 1ABCDbcuvdefgtaEFGHhiwxjklmUVOPQRSTMNIJKLnoyzpqrs

194 

195 if is_model_class(cls): 1ABCDbcuvdefgtaEFGHhiwxjklmUVOPQRSTMNIJKLnoyzpqrs

196 raise PydanticUserError( 1ABCDbcuvdefgtaEFGHhiwxjklmIJKLnoyzpqrs

197 f'Cannot create a Pydantic dataclass from {cls.__name__} as it is already a Pydantic model', 

198 code='dataclass-on-model', 

199 ) 

200 

201 original_cls = cls 1ABCDbcuvdefgtaEFGHhiwxjklmUVOPQRSTMNIJKLnoyzpqrs

202 

203 config_dict = config 1ABCDbcuvdefgtaEFGHhiwxjklmUVOPQRSTMNIJKLnoyzpqrs

204 if config_dict is None: 1ABCDbcuvdefgtaEFGHhiwxjklmUVOPQRSTMNIJKLnoyzpqrs

205 # if not explicitly provided, read from the type 

206 cls_config = getattr(cls, '__pydantic_config__', None) 1ABCDbcuvdefgtaEFGHhiwxjklmUVOPQRSTMNIJKLnoyzpqrs

207 if cls_config is not None: 1ABCDbcuvdefgtaEFGHhiwxjklmUVOPQRSTMNIJKLnoyzpqrs

208 config_dict = cls_config 1ABCDbcuvdefgtaEFGHhiwxjklmIJKLnoyzpqrs

209 config_wrapper = _config.ConfigWrapper(config_dict) 1ABCDbcuvdefgtaEFGHhiwxjklmUVOPQRSTMNIJKLnoyzpqrs

210 decorators = _decorators.DecoratorInfos.build(cls) 1ABCDbcuvdefgtaEFGHhiwxjklmUVOPQRSTMNIJKLnoyzpqrs

211 

212 # Keep track of the original __doc__ so that we can restore it after applying the dataclasses decorator 

213 # Otherwise, classes with no __doc__ will have their signature added into the JSON schema description, 

214 # since dataclasses.dataclass will set this as the __doc__ 

215 original_doc = cls.__doc__ 1ABCDbcuvdefgtaEFGHhiwxjklmUVOPQRSTMNIJKLnoyzpqrs

216 

217 if _pydantic_dataclasses.is_builtin_dataclass(cls): 1ABCDbcuvdefgtaEFGHhiwxjklmUVOPQRSTMNIJKLnoyzpqrs

218 # Don't preserve the docstring for vanilla dataclasses, as it may include the signature 

219 # This matches v1 behavior, and there was an explicit test for it 

220 original_doc = None 1ABCDbcuvdefgtaEFGHhiwxjklmIJKLnoyzpqrs

221 

222 # We don't want to add validation to the existing std lib dataclass, so we will subclass it 

223 # If the class is generic, we need to make sure the subclass also inherits from Generic 

224 # with all the same parameters. 

225 bases = (cls,) 1ABCDbcuvdefgtaEFGHhiwxjklmIJKLnoyzpqrs

226 if issubclass(cls, Generic): 1ABCDbcuvdefgtaEFGHhiwxjklmIJKLnoyzpqrs

227 generic_base = Generic[cls.__parameters__] # type: ignore 1ABCDbcuvdefgtaEFGHhiwxjklmIJKLnoyzpqrs

228 bases = bases + (generic_base,) 1ABCDbcuvdefgtaEFGHhiwxjklmIJKLnoyzpqrs

229 cls = types.new_class(cls.__name__, bases) 1ABCDbcuvdefgtaEFGHhiwxjklmIJKLnoyzpqrs

230 

231 make_pydantic_fields_compatible(cls) 1ABCDbcuvdefgtaEFGHhiwxjklmUVOPQRSTMNIJKLnoyzpqrs

232 

233 cls = dataclasses.dataclass( # type: ignore[call-overload] 1ABCDbcuvdefgtaEFGHhiwxjklmUVOPQRSTMNIJKLnoyzpqrs

234 cls, 

235 # the value of init here doesn't affect anything except that it makes it easier to generate a signature 

236 init=True, 

237 repr=repr, 

238 eq=eq, 

239 order=order, 

240 unsafe_hash=unsafe_hash, 

241 frozen=frozen, 

242 **kwargs, 

243 ) 

244 

245 cls.__pydantic_decorators__ = decorators # type: ignore 1ABCDbcuvdefgtaEFGHhiwxjklmUVOPQRSTMNIJKLnoyzpqrs

246 cls.__doc__ = original_doc 1ABCDbcuvdefgtaEFGHhiwxjklmUVOPQRSTMNIJKLnoyzpqrs

247 cls.__module__ = original_cls.__module__ 1ABCDbcuvdefgtaEFGHhiwxjklmUVOPQRSTMNIJKLnoyzpqrs

248 cls.__qualname__ = original_cls.__qualname__ 1ABCDbcuvdefgtaEFGHhiwxjklmUVOPQRSTMNIJKLnoyzpqrs

249 pydantic_complete = _pydantic_dataclasses.complete_dataclass( 1ABCDbcuvdefgtaEFGHhiwxjklmUVOPQRSTMNIJKLnoyzpqrs

250 cls, config_wrapper, raise_errors=False, types_namespace=None 

251 ) 

252 cls.__pydantic_complete__ = pydantic_complete # type: ignore 1ABCDbcuvdefgtaEFGHhiwxjklmUVOPQRSTMNIJKLnoyzpqrs

253 return cls 1ABCDbcuvdefgtaEFGHhiwxjklmUVOPQRSTMNIJKLnoyzpqrs

254 

255 if _cls is None: 1ABCDbcuvdefgtaEFGHhiwxjklmUVOPQRSTMNIJKLnoyzpqrs

256 return create_dataclass 1ABCDbcuvdefgtaEFGHhiwxjklmUVOPQRSTMNIJKLnoyzpqrs

257 

258 return create_dataclass(_cls) 1ABCDbcuvdefgtaEFGHhiwxjklmUVOPQRSTMNIJKLnoyzpqrs

259 

260 

261__getattr__ = getattr_migration(__name__) 1ABCDbcuvdefgtaEFGHhiwxjklmUVOPQRSTMNIJKLnoyzpqrs

262 

263if (3, 8) <= sys.version_info < (3, 11): 1ABCDbcuvdefgtaEFGHhiwxjklmUVOPQRSTMNIJKLnoyzpqrs

264 # Monkeypatch dataclasses.InitVar so that typing doesn't error if it occurs as a type when evaluating type hints 

265 # Starting in 3.11, typing.get_type_hints will not raise an error if the retrieved type hints are not callable. 

266 

267 def _call_initvar(*args: Any, **kwargs: Any) -> NoReturn: 1ABCDbctaEFGHhiUVOPQRSIJKLno

268 """This function does nothing but raise an error that is as similar as possible to what you'd get 

269 if you were to try calling `InitVar[int]()` without this monkeypatch. The whole purpose is just 

270 to ensure typing._type_check does not error if the type hint evaluates to `InitVar[<parameter>]`. 

271 """ 

272 raise TypeError("'InitVar' object is not callable") 1ABCDbctaEFGHhiIJKLno

273 

274 dataclasses.InitVar.__call__ = _call_initvar 1ABCDbctaEFGHhiUVOPQRSIJKLno

275 

276 

277def rebuild_dataclass( 1ABCDbcuvdefgtaEFGHhiwxjklmUVOPQRSTMNIJKLnoyzpqrs

278 cls: type[PydanticDataclass], 

279 *, 

280 force: bool = False, 

281 raise_errors: bool = True, 

282 _parent_namespace_depth: int = 2, 

283 _types_namespace: dict[str, Any] | None = None, 

284) -> bool | None: 

285 """Try to rebuild the pydantic-core schema for the dataclass. 

286 

287 This may be necessary when one of the annotations is a ForwardRef which could not be resolved during 

288 the initial attempt to build the schema, and automatic rebuilding fails. 

289 

290 This is analogous to `BaseModel.model_rebuild`. 

291 

292 Args: 

293 cls: The class to rebuild the pydantic-core schema for. 

294 force: Whether to force the rebuilding of the schema, defaults to `False`. 

295 raise_errors: Whether to raise errors, defaults to `True`. 

296 _parent_namespace_depth: The depth level of the parent namespace, defaults to 2. 

297 _types_namespace: The types namespace, defaults to `None`. 

298 

299 Returns: 

300 Returns `None` if the schema is already "complete" and rebuilding was not required. 

301 If rebuilding _was_ required, returns `True` if rebuilding was successful, otherwise `False`. 

302 """ 

303 if not force and cls.__pydantic_complete__: 1ABCDbcuvdefgtaEFGHhiwxjklmIJKLnoyzpqrs

304 return None 1ABCDbcuvdefgtaEFGHhiwxjklmIJKLnoyzpqrs

305 else: 

306 if _types_namespace is not None: 1ABCDbcuvdefgtaEFGHhiwxjklmIJKLnoyzpqrs

307 types_namespace: dict[str, Any] | None = _types_namespace.copy() 1ABCDbcuvdefgtaEFGHhiwxjklmIJKLnoyzpqrs

308 else: 

309 if _parent_namespace_depth > 0: 1ABCDbcuvdefgtaEFGHhiwxjklmIJKLnoyzpqrs

310 frame_parent_ns = _typing_extra.parent_frame_namespace(parent_depth=_parent_namespace_depth) or {} 1ABCDbcuvdefgtaEFGHhiwxjklmIJKLnoyzpqrs

311 # Note: we may need to add something similar to cls.__pydantic_parent_namespace__ from BaseModel 

312 # here when implementing handling of recursive generics. See BaseModel.model_rebuild for reference. 

313 types_namespace = frame_parent_ns 1ABCDbcuvdefgtaEFGHhiwxjklmIJKLnoyzpqrs

314 else: 

315 types_namespace = {} 1ABCDbcuvdefgtaEFGHhiwxjklmIJKLnoyzpqrs

316 

317 types_namespace = _typing_extra.get_cls_types_namespace(cls, types_namespace) 1ABCDbcuvdefgtaEFGHhiwxjklmIJKLnoyzpqrs

318 return _pydantic_dataclasses.complete_dataclass( 1ABCDbcuvdefgtaEFGHhiwxjklmIJKLnoyzpqrs

319 cls, 

320 _config.ConfigWrapper(cls.__pydantic_config__, check=False), 

321 raise_errors=raise_errors, 

322 types_namespace=types_namespace, 

323 ) 

324 

325 

326def is_pydantic_dataclass(class_: type[Any], /) -> TypeGuard[type[PydanticDataclass]]: 1ABCDbcuvdefgtaEFGHhiwxjklmUVOPQRSTMNIJKLnoyzpqrs

327 """Whether a class is a pydantic dataclass. 

328 

329 Args: 

330 class_: The class. 

331 

332 Returns: 

333 `True` if the class is a pydantic dataclass, `False` otherwise. 

334 """ 

335 try: 1ABCDbcuvdefgtaEFGHhiwxjklmUVOPQRSTMNIJKLnoyzpqrs

336 return '__pydantic_validator__' in class_.__dict__ and dataclasses.is_dataclass(class_) 1ABCDbcuvdefgtaEFGHhiwxjklmUVOPQRSTMNIJKLnoyzpqrs

337 except AttributeError: 

338 return False