Coverage for pydantic/dataclasses.py: 97.79%

98 statements  

« prev     ^ index     » next       coverage.py v7.6.12, created at 2025-02-13 19:35 +0000

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

2 

3from __future__ import annotations as _annotations 1ABbcuvdefgtaCDhiwxjklmMKLGHIJEFnoyzpqrs

4 

5import dataclasses 1ABbcuvdefgtaCDhiwxjklmMKLGHIJEFnoyzpqrs

6import sys 1ABbcuvdefgtaCDhiwxjklmMKLGHIJEFnoyzpqrs

7import types 1ABbcuvdefgtaCDhiwxjklmMKLGHIJEFnoyzpqrs

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

9from warnings import warn 1ABbcuvdefgtaCDhiwxjklmMKLGHIJEFnoyzpqrs

10 

11from typing_extensions import TypeGuard, dataclass_transform 1ABbcuvdefgtaCDhiwxjklmMKLGHIJEFnoyzpqrs

12 

13from ._internal import _config, _decorators, _namespace_utils, _typing_extra 1ABbcuvdefgtaCDhiwxjklmMKLGHIJEFnoyzpqrs

14from ._internal import _dataclasses as _pydantic_dataclasses 1ABbcuvdefgtaCDhiwxjklmMKLGHIJEFnoyzpqrs

15from ._migration import getattr_migration 1ABbcuvdefgtaCDhiwxjklmMKLGHIJEFnoyzpqrs

16from .config import ConfigDict 1ABbcuvdefgtaCDhiwxjklmMKLGHIJEFnoyzpqrs

17from .errors import PydanticUserError 1ABbcuvdefgtaCDhiwxjklmMKLGHIJEFnoyzpqrs

18from .fields import Field, FieldInfo, PrivateAttr 1ABbcuvdefgtaCDhiwxjklmMKLGHIJEFnoyzpqrs

19 

20if TYPE_CHECKING: 1ABbcuvdefgtaCDhiwxjklmMKLGHIJEFnoyzpqrs

21 from ._internal._dataclasses import PydanticDataclass 

22 from ._internal._namespace_utils import MappingNamespace 

23 

24__all__ = 'dataclass', 'rebuild_dataclass' 1ABbcuvdefgtaCDhiwxjklmMKLGHIJEFnoyzpqrs

25 

26_T = TypeVar('_T') 1ABbcuvdefgtaCDhiwxjklmMKLGHIJEFnoyzpqrs

27 

28if sys.version_info >= (3, 10): 1ABbcuvdefgtaCDhiwxjklmMKLGHIJEFnoyzpqrs

29 

30 @dataclass_transform(field_specifiers=(dataclasses.field, Field, PrivateAttr)) 1bcuvdefgahiwxjklmKLGHIJnoyzpqrs

31 @overload 1bcuvdefgahiwxjklmKLGHIJnoyzpqrs

32 def dataclass( 1bcuvdefgahiwxjklmKLGHIJnoyzpqrs

33 *, 

34 init: Literal[False] = False, 1bcuvdefgahiwxjklmKLGHIJnoyzpqrs

35 repr: bool = True, 1bcuvdefgahiwxjklmKLGHIJnoyzpqrs

36 eq: bool = True, 1bcuvdefgahiwxjklmKLGHIJnoyzpqrs

37 order: bool = False, 1bcuvdefgahiwxjklmKLGHIJnoyzpqrs

38 unsafe_hash: bool = False, 1bcuvdefgahiwxjklmKLGHIJnoyzpqrs

39 frozen: bool = False, 1bcuvdefgahiwxjklmKLGHIJnoyzpqrs

40 config: ConfigDict | type[object] | None = None, 1bcuvdefgahiwxjklmKLGHIJnoyzpqrs

41 validate_on_init: bool | None = None, 1bcuvdefgahiwxjklmKLGHIJnoyzpqrs

42 kw_only: bool = ..., 1bcuvdefgahiwxjklmKLGHIJnoyzpqrs

43 slots: bool = ..., 1bcuvdefgahiwxjklmKLGHIJnoyzpqrs

44 ) -> Callable[[type[_T]], type[PydanticDataclass]]: # type: ignore 1defgajklmGHIJpqrs

45 ... 

46 

47 @dataclass_transform(field_specifiers=(dataclasses.field, Field, PrivateAttr)) 1bcuvdefgahiwxjklmKLGHIJnoyzpqrs

48 @overload 1bcuvdefgahiwxjklmKLGHIJnoyzpqrs

49 def dataclass( 1bcuvdefgahiwxjklmKLGHIJnoyzpqrs

50 _cls: type[_T], # type: ignore 1defgajklmGHIJpqrs

51 *, 

52 init: Literal[False] = False, 1bcuvdefgahiwxjklmKLGHIJnoyzpqrs

53 repr: bool = True, 1bcuvdefgahiwxjklmKLGHIJnoyzpqrs

54 eq: bool = True, 1bcuvdefgahiwxjklmKLGHIJnoyzpqrs

55 order: bool = False, 1bcuvdefgahiwxjklmKLGHIJnoyzpqrs

56 unsafe_hash: bool = False, 1bcuvdefgahiwxjklmKLGHIJnoyzpqrs

57 frozen: bool | None = None, 1bcuvdefgahiwxjklmKLGHIJnoyzpqrs

58 config: ConfigDict | type[object] | None = None, 1bcuvdefgahiwxjklmKLGHIJnoyzpqrs

59 validate_on_init: bool | None = None, 1bcuvdefgahiwxjklmKLGHIJnoyzpqrs

60 kw_only: bool = ..., 1bcuvdefgahiwxjklmKLGHIJnoyzpqrs

61 slots: bool = ..., 1bcuvdefgahiwxjklmKLGHIJnoyzpqrs

62 ) -> type[PydanticDataclass]: ... 1defgajklmGHIJpqrs

63 

64else: 

65 

66 @dataclass_transform(field_specifiers=(dataclasses.field, Field, PrivateAttr)) 1ABtCDMEF

67 @overload 1ABtCDMEF

68 def dataclass( 1ABtCDMEF

69 *, 

70 init: Literal[False] = False, 1ABtCDMEF

71 repr: bool = True, 1ABtCDMEF

72 eq: bool = True, 1ABtCDMEF

73 order: bool = False, 1ABtCDMEF

74 unsafe_hash: bool = False, 1ABtCDMEF

75 frozen: bool | None = None, 1ABtCDMEF

76 config: ConfigDict | type[object] | None = None, 1ABtCDMEF

77 validate_on_init: bool | None = None, 1ABtCDMEF

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

79 ... 

80 

81 @dataclass_transform(field_specifiers=(dataclasses.field, Field, PrivateAttr)) 1ABtCDMEF

82 @overload 1ABtCDMEF

83 def dataclass( 1ABtCDMEF

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

85 *, 

86 init: Literal[False] = False, 1ABtCDMEF

87 repr: bool = True, 1ABtCDMEF

88 eq: bool = True, 1ABtCDMEF

89 order: bool = False, 1ABtCDMEF

90 unsafe_hash: bool = False, 1ABtCDMEF

91 frozen: bool | None = None, 1ABtCDMEF

92 config: ConfigDict | type[object] | None = None, 1ABtCDMEF

93 validate_on_init: bool | None = None, 1ABtCDMEF

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

95 

96 

97@dataclass_transform(field_specifiers=(dataclasses.field, Field, PrivateAttr)) 1ABbcuvdefgtaCDhiwxjklmMKLGHIJEFnoyzpqrs

98def dataclass( 1ABbcuvdefgCDhiwxjklmMKLGHIJEFnoyzpqrs

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

100 *, 

101 init: Literal[False] = False, 

102 repr: bool = True, 

103 eq: bool = True, 

104 order: bool = False, 

105 unsafe_hash: bool = False, 

106 frozen: bool | None = None, 

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

108 validate_on_init: bool | None = None, 

109 kw_only: bool = False, 

110 slots: bool = False, 

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

112 """!!! abstract "Usage Documentation" 

113 [`dataclasses`](../concepts/dataclasses.md) 

114 

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

116 but with added validation. 

117 

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

119 

120 Args: 

121 _cls: The target `dataclass`. 

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

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

124 own `__init__` function. 

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

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

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

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

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

130 attributes to be modified after it has been initialized. If not set, the value from the provided `config` argument will be used (and will default to `False` otherwise). 

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

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

133 are validated on init. 

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

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

136 new attributes after instantiation. 

137 

138 Returns: 

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

140 

141 Raises: 

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

143 """ 

144 assert init is False, 'pydantic.dataclasses.dataclass only supports init=False' 1ABbcuvdefgtaCDhiwxjklmMKLGHIJEFnoyzpqrs

145 assert validate_on_init is not False, 'validate_on_init=False is no longer supported' 1ABbcuvdefgtaCDhiwxjklmMKLGHIJEFnoyzpqrs

146 

147 if sys.version_info >= (3, 10): 1ABbcuvdefgtaCDhiwxjklmMKLGHIJEFnoyzpqrs

148 kwargs = {'kw_only': kw_only, 'slots': slots} 1bcuvdefgahiwxjklmKLGHIJnoyzpqrs

149 else: 

150 kwargs = {} 1ABtCDMEF

151 

152 def make_pydantic_fields_compatible(cls: type[Any]) -> None: 1ABbcuvdefgtaCDhiwxjklmMKLGHIJEFnoyzpqrs

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

154 To do that, we simply change 

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

156 into 

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

158 """ 

159 for annotation_cls in cls.__mro__: 1ABbcuvdefgtaCDhiwxjklmMKLGHIJEFnoyzpqrs

160 annotations: dict[str, Any] = getattr(annotation_cls, '__annotations__', {}) 1ABbcuvdefgtaCDhiwxjklmMKLGHIJEFnoyzpqrs

161 for field_name in annotations: 1ABbcuvdefgtaCDhiwxjklmMKLGHIJEFnoyzpqrs

162 field_value = getattr(cls, field_name, None) 1ABbcuvdefgtaCDhiwxjklmMKLGHIJEFnoyzpqrs

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

164 if not isinstance(field_value, FieldInfo): 1ABbcuvdefgtaCDhiwxjklmMKLGHIJEFnoyzpqrs

165 continue 1ABbcuvdefgtaCDhiwxjklmMKLGHIJEFnoyzpqrs

166 

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

168 field_args: dict = {'default': field_value} 1ABbcuvdefgtaCDhiwxjklmEFnoyzpqrs

169 

170 # Handle `kw_only` for Python 3.10+ 

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

172 field_args['kw_only'] = True 1bcuvdefgahiwxjklmnoyzpqrs

173 

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

175 if field_value.repr is not True: 1ABbcuvdefgtaCDhiwxjklmEFnoyzpqrs

176 field_args['repr'] = field_value.repr 1ABbcuvdefgtaCDhiwxjklmEFnoyzpqrs

177 

178 setattr(cls, field_name, dataclasses.field(**field_args)) 1ABbcuvdefgtaCDhiwxjklmEFnoyzpqrs

179 # In Python 3.9, when subclassing, information is pulled from cls.__dict__['__annotations__'] 

180 # for annotations, so we must make sure it's initialized before we add to it. 

181 if cls.__dict__.get('__annotations__') is None: 1ABbcuvdefgtaCDhiwxjklmEFnoyzpqrs

182 cls.__annotations__ = {} 1ABtCDEF

183 cls.__annotations__[field_name] = annotations[field_name] 1ABbcuvdefgtaCDhiwxjklmEFnoyzpqrs

184 

185 def create_dataclass(cls: type[Any]) -> type[PydanticDataclass]: 1ABbcuvdefgtaCDhiwxjklmMKLGHIJEFnoyzpqrs

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

187 

188 Args: 

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

190 

191 Returns: 

192 A Pydantic dataclass. 

193 """ 

194 from ._internal._utils import is_model_class 1ABbcuvdefgtaCDhiwxjklmMKLGHIJEFnoyzpqrs

195 

196 if is_model_class(cls): 1ABbcuvdefgtaCDhiwxjklmMKLGHIJEFnoyzpqrs

197 raise PydanticUserError( 1ABbcuvdefgtaCDhiwxjklmEFnoyzpqrs

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

199 code='dataclass-on-model', 

200 ) 

201 

202 original_cls = cls 1ABbcuvdefgtaCDhiwxjklmMKLGHIJEFnoyzpqrs

203 

204 # we warn on conflicting config specifications, but only if the class doesn't have a dataclass base 

205 # because a dataclass base might provide a __pydantic_config__ attribute that we don't want to warn about 

206 has_dataclass_base = any(dataclasses.is_dataclass(base) for base in cls.__bases__) 1ABbcuvdefgtaCDhiwxjklmMKLGHIJEFnoyzpqrs

207 if not has_dataclass_base and config is not None and hasattr(cls, '__pydantic_config__'): 1ABbcuvdefgtaCDhiwxjklmMKLGHIJEFnoyzpqrs

208 warn( 1ABbcuvdefgtaCDhiwxjklmEFnoyzpqrs

209 f'`config` is set via both the `dataclass` decorator and `__pydantic_config__` for dataclass {cls.__name__}. ' 

210 f'The `config` specification from `dataclass` decorator will take priority.', 

211 category=UserWarning, 

212 stacklevel=2, 

213 ) 

214 

215 # if config is not explicitly provided, try to read it from the type 

216 config_dict = config if config is not None else getattr(cls, '__pydantic_config__', None) 1ABbcuvdefgtaCDhiwxjklmMKLGHIJEFnoyzpqrs

217 config_wrapper = _config.ConfigWrapper(config_dict) 1ABbcuvdefgtaCDhiwxjklmMKLGHIJEFnoyzpqrs

218 decorators = _decorators.DecoratorInfos.build(cls) 1ABbcuvdefgtaCDhiwxjklmMKLGHIJEFnoyzpqrs

219 

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

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

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

223 original_doc = cls.__doc__ 1ABbcuvdefgtaCDhiwxjklmMKLGHIJEFnoyzpqrs

224 

225 if _pydantic_dataclasses.is_builtin_dataclass(cls): 1ABbcuvdefgtaCDhiwxjklmMKLGHIJEFnoyzpqrs

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

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

228 original_doc = None 1ABbcuvdefgtaCDhiwxjklmEFnoyzpqrs

229 

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

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

232 # with all the same parameters. 

233 bases = (cls,) 1ABbcuvdefgtaCDhiwxjklmEFnoyzpqrs

234 if issubclass(cls, Generic): 1ABbcuvdefgtaCDhiwxjklmEFnoyzpqrs

235 generic_base = Generic[cls.__parameters__] # type: ignore 1ABbcuvdefgtaCDhiwxjklmEFnoyzpqrs

236 bases = bases + (generic_base,) 1ABbcuvdefgtaCDhiwxjklmEFnoyzpqrs

237 cls = types.new_class(cls.__name__, bases) 1ABbcuvdefgtaCDhiwxjklmEFnoyzpqrs

238 

239 make_pydantic_fields_compatible(cls) 1ABbcuvdefgtaCDhiwxjklmMKLGHIJEFnoyzpqrs

240 

241 # Respect frozen setting from dataclass constructor and fallback to config setting if not provided 

242 if frozen is not None: 1ABbcuvdefgtaCDhiwxjklmMKLGHIJEFnoyzpqrs

243 frozen_ = frozen 1ABbcuvdefgtaCDhiwxjklmEFnoyzpqrs

244 if config_wrapper.frozen: 1ABbcuvdefgtaCDhiwxjklmEFnoyzpqrs

245 # It's not recommended to define both, as the setting from the dataclass decorator will take priority. 

246 warn( 1ABbcuvdefgtaCDhiwxjklmEFnoyzpqrs

247 f'`frozen` is set via both the `dataclass` decorator and `config` for dataclass {cls.__name__!r}.' 

248 'This is not recommended. The `frozen` specification on `dataclass` will take priority.', 

249 category=UserWarning, 

250 stacklevel=2, 

251 ) 

252 else: 

253 frozen_ = config_wrapper.frozen or False 1ABbcuvdefgtaCDhiwxjklmMKLGHIJEFnoyzpqrs

254 

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

256 cls, 

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

258 init=True, 

259 repr=repr, 

260 eq=eq, 

261 order=order, 

262 unsafe_hash=unsafe_hash, 

263 frozen=frozen_, 

264 **kwargs, 

265 ) 

266 

267 # This is an undocumented attribute to distinguish stdlib/Pydantic dataclasses. 

268 # It should be set as early as possible: 

269 cls.__is_pydantic_dataclass__ = True 1ABbcuvdefgtaCDhiwxjklmMKLGHIJEFnoyzpqrs

270 

271 cls.__pydantic_decorators__ = decorators # type: ignore 1ABbcuvdefgtaCDhiwxjklmMKLGHIJEFnoyzpqrs

272 cls.__doc__ = original_doc 1ABbcuvdefgtaCDhiwxjklmMKLGHIJEFnoyzpqrs

273 cls.__module__ = original_cls.__module__ 1ABbcuvdefgtaCDhiwxjklmMKLGHIJEFnoyzpqrs

274 cls.__qualname__ = original_cls.__qualname__ 1ABbcuvdefgtaCDhiwxjklmMKLGHIJEFnoyzpqrs

275 cls.__pydantic_complete__ = False # `complete_dataclass` will set it to `True` if successful. 1ABbcuvdefgtaCDhiwxjklmMKLGHIJEFnoyzpqrs

276 # TODO `parent_namespace` is currently None, but we could do the same thing as Pydantic models: 

277 # fetch the parent ns using `parent_frame_namespace` (if the dataclass was defined in a function), 

278 # and possibly cache it (see the `__pydantic_parent_namespace__` logic for models). 

279 _pydantic_dataclasses.complete_dataclass(cls, config_wrapper, raise_errors=False) 1ABbcuvdefgtaCDhiwxjklmMKLGHIJEFnoyzpqrs

280 return cls 1ABbcuvdefgtaCDhiwxjklmMKLGHIJEFnoyzpqrs

281 

282 return create_dataclass if _cls is None else create_dataclass(_cls) 1ABbcuvdefgtaCDhiwxjklmMKLGHIJEFnoyzpqrs

283 

284 

285__getattr__ = getattr_migration(__name__) 1ABbcuvdefgtaCDhiwxjklmMKLGHIJEFnoyzpqrs

286 

287if sys.version_info < (3, 11): 1ABbcuvdefgtaCDhiwxjklmMKLGHIJEFnoyzpqrs

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

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

290 

291 def _call_initvar(*args: Any, **kwargs: Any) -> NoReturn: 1ABbctaCDhiMKEFno

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

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

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

295 """ 

296 raise TypeError("'InitVar' object is not callable") 1ABbctaCDhiEFno

297 

298 dataclasses.InitVar.__call__ = _call_initvar 1ABbctaCDhiMKEFno

299 

300 

301def rebuild_dataclass( 1ABbcuvdefgtaCDhiwxjklmMKLGHIJEFnoyzpqrs

302 cls: type[PydanticDataclass], 

303 *, 

304 force: bool = False, 

305 raise_errors: bool = True, 

306 _parent_namespace_depth: int = 2, 

307 _types_namespace: MappingNamespace | None = None, 

308) -> bool | None: 

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

310 

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

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

313 

314 This is analogous to `BaseModel.model_rebuild`. 

315 

316 Args: 

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

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

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

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

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

322 

323 Returns: 

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

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

326 """ 

327 if not force and cls.__pydantic_complete__: 1ABbcuvdefgtaCDhiwxjklmEFnoyzpqrs

328 return None 1ABbcuvdefgtaCDhiwxjklmEFnoyzpqrs

329 

330 for attr in ('__pydantic_core_schema__', '__pydantic_validator__', '__pydantic_serializer__'): 1ABbcuvdefgtaCDhiwxjklmEFnoyzpqrs

331 if attr in cls.__dict__: 331 ↛ 330line 331 didn't jump to line 330 because the condition on line 331 was always true1ABbcuvdefgtaCDhiwxjklmEFnoyzpqrs

332 # Deleting the validator/serializer is necessary as otherwise they can get reused in 

333 # pycantic-core. Same applies for the core schema that can be reused in schema generation. 

334 delattr(cls, attr) 1ABbcuvdefgtaCDhiwxjklmEFnoyzpqrs

335 

336 cls.__pydantic_complete__ = False 1ABbcuvdefgtaCDhiwxjklmEFnoyzpqrs

337 

338 if _types_namespace is not None: 1ABbcuvdefgtaCDhiwxjklmEFnoyzpqrs

339 rebuild_ns = _types_namespace 1ABbcuvdefgtaCDhiwxjklmEFnoyzpqrs

340 elif _parent_namespace_depth > 0: 1ABbcuvdefgtaCDhiwxjklmEFnoyzpqrs

341 rebuild_ns = _typing_extra.parent_frame_namespace(parent_depth=_parent_namespace_depth, force=True) or {} 1ABbcuvdefgtaCDhiwxjklmEFnoyzpqrs

342 else: 

343 rebuild_ns = {} 1ABbcuvdefgtaCDhiwxjklmEFnoyzpqrs

344 

345 ns_resolver = _namespace_utils.NsResolver( 1ABbcuvdefgtaCDhiwxjklmEFnoyzpqrs

346 parent_namespace=rebuild_ns, 

347 ) 

348 

349 return _pydantic_dataclasses.complete_dataclass( 1ABbcuvdefgtaCDhiwxjklmEFnoyzpqrs

350 cls, 

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

352 raise_errors=raise_errors, 

353 ns_resolver=ns_resolver, 

354 # We could provide a different config instead (with `'defer_build'` set to `True`) 

355 # of this explicit `_force_build` argument, but because config can come from the 

356 # decorator parameter or the `__pydantic_config__` attribute, `complete_dataclass` 

357 # will overwrite `__pydantic_config__` with the provided config above: 

358 _force_build=True, 

359 ) 

360 

361 

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

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

364 

365 Args: 

366 class_: The class. 

367 

368 Returns: 

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

370 """ 

371 try: 1ABbcuvdefgtaCDhiwxjklmMKLGHIJEFnoyzpqrs

372 return '__is_pydantic_dataclass__' in class_.__dict__ and dataclasses.is_dataclass(class_) 1ABbcuvdefgtaCDhiwxjklmMKLGHIJEFnoyzpqrs

373 except AttributeError: 

374 return False