@@ -117,7 +117,7 @@ def __init__(self, isolated: bool, load_only: Kind | None = None) -> None:
117117 self ._parsers : dict [Kind , list [tuple [str , RawConfigParser ]]] = {
118118 variant : [] for variant in OVERRIDE_ORDER
119119 }
120- self ._config : dict [Kind , dict [str , Any ]] = {
120+ self ._config : dict [Kind , dict [str , dict [ str , Any ] ]] = {
121121 variant : {} for variant in OVERRIDE_ORDER
122122 }
123123 self ._modified_parsers : list [tuple [str , RawConfigParser ]] = []
@@ -148,7 +148,10 @@ def get_value(self, key: str) -> Any:
148148 orig_key = key
149149 key = _normalize_name (key )
150150 try :
151- return self ._dictionary [key ]
151+ clean_config : dict [str , Any ] = {}
152+ for file_values in self ._dictionary .values ():
153+ clean_config .update (file_values )
154+ return clean_config [key ]
152155 except KeyError :
153156 # disassembling triggers a more useful error message than simply
154157 # "No such key" in the case that the key isn't in the form command.option
@@ -171,7 +174,8 @@ def set_value(self, key: str, value: Any) -> None:
171174 parser .add_section (section )
172175 parser .set (section , name , value )
173176
174- self ._config [self .load_only ][key ] = value
177+ self ._config [self .load_only ].setdefault (fname , {})
178+ self ._config [self .load_only ][fname ][key ] = value
175179 self ._mark_as_modified (fname , parser )
176180
177181 def unset_value (self , key : str ) -> None :
@@ -181,11 +185,14 @@ def unset_value(self, key: str) -> None:
181185 self ._ensure_have_load_only ()
182186
183187 assert self .load_only
184- if key not in self ._config [self .load_only ]:
185- raise ConfigurationError (f"No such key - { orig_key } " )
186-
187188 fname , parser = self ._get_parser_to_modify ()
188189
190+ if (
191+ key not in self ._config [self .load_only ][fname ]
192+ and key not in self ._config [self .load_only ]
193+ ):
194+ raise ConfigurationError (f"No such key - { orig_key } " )
195+
189196 if parser is not None :
190197 section , name = _disassemble_key (key )
191198 if not (
@@ -200,8 +207,10 @@ def unset_value(self, key: str) -> None:
200207 if not parser .items (section ):
201208 parser .remove_section (section )
202209 self ._mark_as_modified (fname , parser )
203-
204- del self ._config [self .load_only ][key ]
210+ try :
211+ del self ._config [self .load_only ][fname ][key ]
212+ except KeyError :
213+ del self ._config [self .load_only ][key ]
205214
206215 def save (self ) -> None :
207216 """Save the current in-memory state."""
@@ -233,7 +242,7 @@ def _ensure_have_load_only(self) -> None:
233242 logger .debug ("Will be working with %s variant only" , self .load_only )
234243
235244 @property
236- def _dictionary (self ) -> dict [str , Any ]:
245+ def _dictionary (self ) -> dict [str , dict [ str , Any ] ]:
237246 """A dictionary representing the loaded configuration."""
238247 # NOTE: Dictionaries are not populated if not loaded. So, conditionals
239248 # are not needed here.
@@ -273,7 +282,8 @@ def _load_file(self, variant: Kind, fname: str) -> RawConfigParser:
273282
274283 for section in parser .sections ():
275284 items = parser .items (section )
276- self ._config [variant ].update (self ._normalized_keys (section , items ))
285+ self ._config [variant ].setdefault (fname , {})
286+ self ._config [variant ][fname ].update (self ._normalized_keys (section , items ))
277287
278288 return parser
279289
@@ -300,7 +310,8 @@ def _construct_parser(self, fname: str) -> RawConfigParser:
300310
301311 def _load_environment_vars (self ) -> None :
302312 """Loads configuration from environment variables"""
303- self ._config [kinds .ENV_VAR ].update (
313+ self ._config [kinds .ENV_VAR ].setdefault (":env:" , {})
314+ self ._config [kinds .ENV_VAR ][":env:" ].update (
304315 self ._normalized_keys (":env:" , self .get_environ_vars ())
305316 )
306317
0 commit comments