4444from pathlib import Path , PureWindowsPath
4545from typing import TYPE_CHECKING , Any
4646
47- from west .util import WEST_DIR , PathType , WestNotFound , west_dir
47+ from west .util import WEST_DIR , PathType , WestNotFound , paths_to_str , west_dir
4848
4949
5050class MalformedConfig (Exception ):
@@ -70,19 +70,36 @@ def parse_key(dotted_name: str):
7070 return section_child
7171
7272 @staticmethod
73- def from_path (path : Path | None ) -> '_InternalCF | None' :
74- return _InternalCF (path ) if path and path .exists () else None
75-
76- def __init__ (self , path : Path ):
77- self .path = path
73+ def from_path (path : Path | list [Path ] | None ) -> '_InternalCF | None' :
74+ if not path :
75+ return None
76+
77+ # Normalize to a list of existing paths
78+ paths = path
79+ if isinstance (paths , Path ):
80+ paths = [Path (p ) for p in str (paths ).split (os .pathsep )]
81+ paths = [p for p in paths if p .exists ()]
82+ return _InternalCF (paths ) if paths else None
83+
84+ def __init__ (self , paths : list [Path ]):
7885 self .cp = _configparser ()
79- read_files = self .cp .read (path , encoding = 'utf-8' )
80- if len (read_files ) != 1 :
81- raise FileNotFoundError (path )
86+ self .paths = paths
87+ read_files = self .cp .read (self .paths , encoding = 'utf-8' )
88+ if len (read_files ) != len (self .paths ):
89+ raise WestNotFound (f"Error while reading one of '{ paths_to_str (paths )} '" )
90+
91+ def _write (self ):
92+ if not self .paths :
93+ raise WestNotFound ('No config file exists that can be written' )
94+ if len (self .paths ) > 1 :
95+ raise WestNotFound (
96+ f'Cannot write if multiple configs in use: { paths_to_str (self .paths )} '
97+ )
98+ with open (self .paths [0 ], 'w' , encoding = 'utf-8' ) as f :
99+ self .cp .write (f )
82100
83101 def __contains__ (self , option : str ) -> bool :
84102 section , key = _InternalCF .parse_key (option )
85-
86103 return section in self .cp and key in self .cp [section ]
87104
88105 def get (self , option : str ):
@@ -97,37 +114,31 @@ def getint(self, option: str):
97114 def getfloat (self , option : str ):
98115 return self ._get (option , self .cp .getfloat )
99116
100- def _get (self , option , getter ):
117+ def _get (self , option , config_getter ):
101118 section , key = _InternalCF .parse_key (option )
102-
103- try :
104- return getter ( section , key )
105- except ( configparser . NoOptionError , configparser . NoSectionError ) as err :
106- raise KeyError ( option ) from err
119+ if section in self . cp and key in self . cp [ section ]:
120+ getter = config_getter
121+ else :
122+ raise KeyError ( option )
123+ return getter ( section , key )
107124
108125 def set (self , option : str , value : Any ):
109126 section , key = _InternalCF .parse_key (option )
110-
111127 if section not in self .cp :
112128 self .cp [section ] = {}
113-
114129 self .cp [section ][key ] = value
115-
116- with open (self .path , 'w' , encoding = 'utf-8' ) as f :
117- self .cp .write (f )
130+ self ._write ()
118131
119132 def delete (self , option : str ):
120133 section , key = _InternalCF .parse_key (option )
121-
122- if section not in self .cp :
134+ if option not in self :
123135 raise KeyError (option )
124136
125137 del self .cp [section ][key ]
126138 if not self .cp [section ].items ():
127139 del self .cp [section ]
128140
129- with open (self .path , 'w' , encoding = 'utf-8' ) as f :
130- self .cp .write (f )
141+ self ._write ()
131142
132143
133144class ConfigFile (Enum ):
@@ -186,11 +197,11 @@ def __init__(self, topdir: PathType | None = None):
186197 def get_paths (self , location : ConfigFile = ConfigFile .ALL ):
187198 ret = []
188199 if self ._global and location in [ConfigFile .GLOBAL , ConfigFile .ALL ]:
189- ret .append (self ._global .path )
200+ ret .extend (self ._global .paths )
190201 if self ._system and location in [ConfigFile .SYSTEM , ConfigFile .ALL ]:
191- ret .append (self ._system .path )
202+ ret .extend (self ._system .paths )
192203 if self ._local and location in [ConfigFile .LOCAL , ConfigFile .ALL ]:
193- ret .append (self ._local .path )
204+ ret .extend (self ._local .paths )
194205 return ret
195206
196207 def get (
@@ -282,7 +293,6 @@ def set(self, option: str, value: Any, configfile: ConfigFile = ConfigFile.LOCAL
282293 :param value: value to set option to
283294 :param configfile: type of config file to set the value in
284295 '''
285-
286296 if configfile == ConfigFile .ALL :
287297 # We need a real configuration file; ALL doesn't make sense here.
288298 raise ValueError (configfile )
0 commit comments