@@ -229,51 +229,54 @@ def log_bug_report(level=logging.DEBUG) -> None:
229229 bug_logger .log (level , str_stream .getvalue ())
230230
231231
232- def find_file (filename , path = None , silent = False ):
232+ def find_file (
233+ filename : str ,
234+ path : Iterable [Path | str ] | None = None ,
235+ silent : bool = False ,
236+ ) -> str | None :
233237 """Find a file in search path.
234238
239+ First check whether `filename` exists as (relative) path. In
240+ particular, this finds files that are present in the user's current
241+ working directory. If `filename` is not found in this way it is looked
242+ for in the search path, `rc.__search_path__`.
243+
235244 Parameters
236245 ----------
237246 filename : str
238247 name of a file to look for
239248 path : list
240- list of directories to search (default: ['./'] )
249+ list of directories to search (default: `rc.__search_path__` )
241250 silent : bool
242251 if True, remain silent when file is not found
243252
244253 Returns
245254 -------
246- Absolute path of the file
255+ Absolute path of the file (str) or None
247256 """
248257 if filename is None or filename .lower () == "none" :
249258 return None
250259
251260 if filename .startswith ("!" ):
252- raise ValueError (f "!-string filename should be resolved upstream: "
261+ raise ValueError ("!-string filename should be resolved upstream: "
253262 f"{ filename } " )
254- # filename = from_currsys(filename)
263+
255264 # Turn into pathlib.Path object for better manipulation afterwards
256265 filename = Path (filename )
257266
267+ if filename .exists ():
268+ # file exists; assume user wants to override search path
269+ return str (filename )
270+
258271 if path is None :
259272 path = rc .__search_path__
260273
261- if filename .is_absolute ():
262- # absolute path: only path to try
263- trynames = [filename ]
264- else :
265- # try to find the file in a search path
266- trynames = [Path (trydir , filename )
267- for trydir in path if trydir is not None ]
274+ # try to find the file in a search path
275+ trynames = [Path (trydir , filename )
276+ for trydir in path if trydir is not None ]
268277
269278 for fname in trynames :
270279 if fname .exists (): # success
271- # strip leading ./
272- # Path should take care of this automatically!
273- # while fname[:2] == './':
274- # fname = fname[2:]
275- # Nevertheless, make sure this is actually the case...
276- assert not str (fname ).startswith ("./" )
277280 # HACK: Turn Path object back into string, because not everything
278281 # that depends on this function can handle Path objects (yet)
279282 return str (fname )
@@ -282,10 +285,8 @@ def find_file(filename, path=None, silent=False):
282285 msg = f"File cannot be found: { filename } "
283286 if not silent :
284287 logger .error (msg )
285-
286- # TODO: Not sure what to do here
287288 if from_currsys ("!SIM.file.error_on_missing_file" ):
288- raise ValueError (msg )
289+ raise FileNotFoundError (msg )
289290
290291 return None
291292
0 commit comments