|
""" |
|
utils: |
|
- provides utility wrappers to run asynchronous functions in a blocking environment. |
|
- vendor functions from ipython_genutils that should be retired at some point. |
|
""" |
|
from __future__ import annotations |
|
|
|
import os |
|
from typing import Sequence |
|
|
|
from jupyter_core.utils import ensure_async, run_sync |
|
|
|
from .session import utcnow |
|
|
|
|
|
def _filefind(filename: str, path_dirs: str | Sequence[str] | None = None) -> str: |
|
"""Find a file by looking through a sequence of paths. |
|
|
|
This iterates through a sequence of paths looking for a file and returns |
|
the full, absolute path of the first occurrence of the file. If no set of |
|
path dirs is given, the filename is tested as is, after running through |
|
:func:`expandvars` and :func:`expanduser`. Thus a simple call:: |
|
|
|
filefind('myfile.txt') |
|
|
|
will find the file in the current working dir, but:: |
|
|
|
filefind('~/myfile.txt') |
|
|
|
Will find the file in the users home directory. This function does not |
|
automatically try any paths, such as the cwd or the user's home directory. |
|
|
|
Parameters |
|
---------- |
|
filename : str |
|
The filename to look for. |
|
path_dirs : str, None or sequence of str |
|
The sequence of paths to look for the file in. If None, the filename |
|
need to be absolute or be in the cwd. If a string, the string is |
|
put into a sequence and the searched. If a sequence, walk through |
|
each element and join with ``filename``, calling :func:`expandvars` |
|
and :func:`expanduser` before testing for existence. |
|
|
|
Returns |
|
------- |
|
Raises :exc:`IOError` or returns absolute path to file. |
|
""" |
|
|
|
|
|
filename = filename.strip('"').strip("'") |
|
|
|
if os.path.isabs(filename) and os.path.isfile(filename): |
|
return filename |
|
|
|
if path_dirs is None: |
|
path_dirs = ("",) |
|
elif isinstance(path_dirs, str): |
|
path_dirs = (path_dirs,) |
|
|
|
for path in path_dirs: |
|
if path == ".": |
|
path = os.getcwd() |
|
testname = _expand_path(os.path.join(path, filename)) |
|
if os.path.isfile(testname): |
|
return os.path.abspath(testname) |
|
msg = f"File {filename!r} does not exist in any of the search paths: {path_dirs!r}" |
|
raise OSError(msg) |
|
|
|
|
|
def _expand_path(s: str) -> str: |
|
"""Expand $VARS and ~names in a string, like a shell |
|
|
|
:Examples: |
|
|
|
In [2]: os.environ['FOO']='test' |
|
|
|
In [3]: expand_path('variable FOO is $FOO') |
|
Out[3]: 'variable FOO is test' |
|
""" |
|
|
|
|
|
|
|
|
|
|
|
if os.name == "nt": |
|
s = s.replace("$\\", "IPYTHON_TEMP") |
|
s = os.path.expandvars(os.path.expanduser(s)) |
|
if os.name == "nt": |
|
s = s.replace("IPYTHON_TEMP", "$\\") |
|
return s |
|
|