@@ -597,8 +597,11 @@ def _field_is_complex(self, field: FieldInfo) -> tuple[bool, bool]:
597
597
598
598
return True , allow_parse_failure
599
599
600
+ # Default value of `case_sensitive` is `None`, because we don't want to break existing behavior.
601
+ # We have to change the method to a non-static method and use
602
+ # `self.case_sensitive` instead in V3.
600
603
@staticmethod
601
- def next_field (field : FieldInfo | Any | None , key : str ) -> FieldInfo | None :
604
+ def next_field (field : FieldInfo | Any | None , key : str , case_sensitive : bool | None = None ) -> FieldInfo | None :
602
605
"""
603
606
Find the field in a sub model by key(env name)
604
607
@@ -623,6 +626,7 @@ class Cfg(BaseSettings):
623
626
Args:
624
627
field: The field.
625
628
key: The key (env name).
629
+ case_sensitive: Whether to search for key case sensitively.
626
630
627
631
Returns:
628
632
Field if it finds the next field otherwise `None`.
@@ -633,11 +637,18 @@ class Cfg(BaseSettings):
633
637
annotation = field .annotation if isinstance (field , FieldInfo ) else field
634
638
if origin_is_union (get_origin (annotation )) or isinstance (annotation , WithArgsTypes ):
635
639
for type_ in get_args (annotation ):
636
- type_has_key = EnvSettingsSource .next_field (type_ , key )
640
+ type_has_key = EnvSettingsSource .next_field (type_ , key , case_sensitive )
637
641
if type_has_key :
638
642
return type_has_key
639
- elif is_model_class (annotation ) and annotation .model_fields .get (key ):
640
- return annotation .model_fields [key ]
643
+ elif is_model_class (annotation ):
644
+ # `case_sensitive is None` is here to be compatible with the old behavior.
645
+ # Has to be removed in V3.
646
+ if (case_sensitive is None or case_sensitive ) and annotation .model_fields .get (key ):
647
+ return annotation .model_fields [key ]
648
+ elif not case_sensitive :
649
+ for field_name , f in annotation .model_fields .items ():
650
+ if field_name .lower () == key .lower ():
651
+ return f
641
652
642
653
return None
643
654
@@ -670,12 +681,12 @@ def explode_env_vars(self, field_name: str, field: FieldInfo, env_vars: Mapping[
670
681
env_var = result
671
682
target_field : FieldInfo | None = field
672
683
for key in keys :
673
- target_field = self .next_field (target_field , key )
684
+ target_field = self .next_field (target_field , key , self . case_sensitive )
674
685
if isinstance (env_var , dict ):
675
686
env_var = env_var .setdefault (key , {})
676
687
677
688
# get proper field with last_key
678
- target_field = self .next_field (target_field , last_key )
689
+ target_field = self .next_field (target_field , last_key , self . case_sensitive )
679
690
680
691
# check if env_val maps to a complex field and if so, parse the env_val
681
692
if (target_field or is_dict ) and env_val :
0 commit comments