@@ -361,3 +361,58 @@ def validate_annotated(value, typehint: type):
361
361
from pydantic import TypeAdapter
362
362
363
363
return TypeAdapter (typehint ).validate_python (value )
364
+
365
+
366
+ def get_pydantic_extra_config (class_type ) -> Optional [str ]:
367
+ """Get the 'extra' configuration from a Pydantic model.
368
+
369
+ Args:
370
+ class_type: The class to check for Pydantic extra configuration.
371
+
372
+ Returns:
373
+ The extra configuration ('allow', 'forbid', 'ignore') or None if not a Pydantic model.
374
+ """
375
+ pydantic_model_version = is_pydantic_model (class_type )
376
+ if not pydantic_model_version :
377
+ return None
378
+
379
+ try :
380
+
381
+ # Handle Pydantic v2 models
382
+ if pydantic_model_version > 1 :
383
+ # Check for model_config attribute (Pydantic v2 style)
384
+ if hasattr (class_type , "model_config" ):
385
+ config = class_type .model_config
386
+ if hasattr (config , "get" ):
387
+ # ConfigDict case
388
+ return config .get ("extra" )
389
+ elif hasattr (config , "extra" ):
390
+ # Direct attribute access
391
+ return config .extra
392
+
393
+ # Check for __config__ attribute (legacy support in v2)
394
+ if hasattr (class_type , "__config__" ):
395
+ config = class_type .__config__
396
+ if hasattr (config , "extra" ):
397
+ return config .extra
398
+
399
+ # Handle Pydantic v1 models (including v1 compatibility mode in v2)
400
+ else :
401
+ if hasattr (class_type , "__config__" ):
402
+ config = class_type .__config__
403
+ if hasattr (config , "extra" ):
404
+ extra_value = config .extra
405
+ # Handle Pydantic v1 Extra enum
406
+ if hasattr (extra_value , "value" ):
407
+ return extra_value .value
408
+ elif isinstance (extra_value , str ):
409
+ return extra_value
410
+ else :
411
+ # Convert enum to string by taking the last part after the dot
412
+ return str (extra_value ).split ("." )[- 1 ]
413
+
414
+ except Exception :
415
+ # If anything goes wrong, return None to fall back to default behavior
416
+ pass
417
+
418
+ return None
0 commit comments