ubelt.util_platform module¶
The goal of this module is to provide an idiomatic cross-platform pattern of accessing platform dependent file systems.
Standard application directory structure: cache, config, and other XDG
standards [XDG_Spec]. This is similar to the more focused appdirs
module [AS_appdirs]. In the future ubelt may directly use appdirs
.
Note
Table mapping the type of directory to the system default environment variable. Inspired by [SO_43853548], [SO_11113974], and [harawata_appdirs].
| Linux | Win32 | Darwin
data | $XDG_DATA_HOME | %APPDATA% | ~/Library/Application Support
config | $XDG_CONFIG_HOME | %APPDATA% | ~/Library/Application Support
cache | $XDG_CACHE_HOME | %LOCALAPPDATA% | ~/Library/Caches
If an environment variable is not specified the defaults are:
APPDATA = ~/AppData/Roaming
LOCALAPPDATA = ~/AppData/Local
XDG_DATA_HOME = ~/.local/share
XDG_CACHE_HOME = ~/.cache
XDG_CONFIG_HOME = ~/.config
References
- XDG_Spec
https://specifications.freedesktop.org/basedir-spec/basedir-spec-latest.html
- SO_43853548
- SO_11113974
https://stackoverflow.com/questions/11113974/cross-plat-path
- harawata_appdirs
- AS_appdirs
- ubelt.util_platform.find_exe(name, multi=False, path=None)[source]¶
Locate a command.
Search your local filesystem for an executable and return the first matching file with executable permission.
- Parameters
name (str | PathLike) – globstr of matching filename
multi (bool, default=False) – if True return all matches instead of just the first.
path (str | PathLike | Iterable[str | PathLike] | None, default=None) – overrides the system PATH variable.
- Returns
returns matching executable(s).
- Return type
- SeeAlso:
shutil.which()
- which is available in Python 3.3+.
Note
This is essentially the
which
UNIX commandReferences
- SO_377017
https://stackoverflow.com/questions/377017/test-if-executable-exists-in-python/377028#377028
- shutil_which
https://docs.python.org/dev/library/shutil.html#shutil.which
Example
>>> # The following are programs commonly exposed via the PATH variable. >>> # Exact results may differ between machines. >>> # xdoctest: +IGNORE_WANT >>> import ubelt as ub >>> print(ub.find_exe('ls')) >>> print(ub.find_exe('ping')) >>> print(ub.find_exe('which')) >>> print(ub.find_exe('which', multi=True)) >>> print(ub.find_exe('ping', multi=True)) >>> print(ub.find_exe('noexist', multi=True)) /usr/bin/ls /usr/bin/ping /usr/bin/which ['/usr/bin/which', '/bin/which'] ['/usr/bin/ping', '/bin/ping'] []
Example
>>> import ubelt as ub >>> assert not ub.find_exe('!noexist', multi=False) >>> assert ub.find_exe('ping', multi=False) or ub.find_exe('ls', multi=False) >>> assert not ub.find_exe('!noexist', multi=True) >>> assert ub.find_exe('ping', multi=True) or ub.find_exe('ls', multi=True)
Benchmark
>>> # xdoctest: +IGNORE_WANT >>> import ubelt as ub >>> import shutil >>> from timerit import Timerit >>> for timer in Timerit(1000, bestof=10, label='ub.find_exe'): >>> ub.find_exe('which') >>> for timer in Timerit(1000, bestof=10, label='shutil.which'): >>> shutil.which('which') Timed best=25.339 µs, mean=25.809 ± 0.3 µs for ub.find_exe Timed best=28.600 µs, mean=28.986 ± 0.3 µs for shutil.which
- ubelt.util_platform.find_path(name, path=None, exact=False)[source]¶
Search for a file or directory on your local filesystem by name (file must be in a directory specified in a PATH environment variable)
- Parameters
name (str | PathLike) – file name to match. If exact is False this may be a glob pattern
path (str | Iterable[str | PathLike], default=None) – list of directories to search either specified as an
os.pathsep
separated string or a list of directories. Defaults to environment PATH.exact (bool, default=False) – if True, only returns exact matches.
- Yields
str – candidate - a path that matches
name
Note
Running with
name=''
(i.e.ub.find_path('')
) will simply yield all directories in your PATH.Note
For recursive behavior set
path=(d for d, _, _ in os.walk('.'))
, where ‘.’ might be replaced by the root directory of interest.Example
>>> # xdoctest: +IGNORE_WANT >>> import ubelt as ub >>> print(list(ub.find_path('ping', exact=True))) >>> print(list(ub.find_path('bin'))) >>> print(list(ub.find_path('gcc*'))) >>> print(list(ub.find_path('cmake*'))) ['/usr/bin/ping', '/bin/ping'] [] [... '/usr/bin/gcc-11', '/usr/bin/gcc-ranlib', ...] [... '/usr/bin/cmake-gui', '/usr/bin/cmake', ...]
Example
>>> import ubelt as ub >>> from os.path import dirname >>> path = dirname(dirname(ub.util_platform.__file__)) >>> res = sorted(ub.find_path('ubelt/util_*.py', path=path)) >>> assert len(res) >= 10 >>> res = sorted(ub.find_path('ubelt/util_platform.py', path=path, exact=True)) >>> print(res) >>> assert len(res) == 1
- ubelt.util_platform.ensure_app_cache_dir(appname, *args)[source]¶
Calls
get_app_cache_dir()
but ensures the directory exists.Note
New applications should prefer
ubelt.util_path.Path.appdir()
i.e.ubelt.Path.appdir(appname, *args, type='cache').ensuredir()
.- Parameters
appname (str) – the name of the application
*args – any other subdirectories may be specified
- Returns
the path to the ensured directory
- Return type
- SeeAlso:
Example
>>> import ubelt as ub >>> dpath = ub.ensure_app_cache_dir('ubelt') >>> assert exists(dpath)
- ubelt.util_platform.ensure_app_config_dir(appname, *args)[source]¶
Calls
get_app_config_dir()
but ensures the directory exists.Note
New applications should prefer
ubelt.util_path.Path.appdir()
i.e.ubelt.Path.appdir(appname, *args, type='config').ensuredir()
.- Parameters
appname (str) – the name of the application
*args – any other subdirectories may be specified
- Returns
the path to the ensured directory
- Return type
- SeeAlso:
Example
>>> import ubelt as ub >>> dpath = ub.ensure_app_config_dir('ubelt') >>> assert exists(dpath)
- ubelt.util_platform.ensure_app_data_dir(appname, *args)[source]¶
Calls
get_app_data_dir()
but ensures the directory exists.Note
New applications should prefer
ubelt.util_path.Path.appdir()
i.e.ubelt.Path.appdir(appname, *args, type='data').ensuredir()
.- Parameters
appname (str) – the name of the application
*args – any other subdirectories may be specified
- Returns
the path to the ensured directory
- Return type
- SeeAlso:
Example
>>> import ubelt as ub >>> dpath = ub.ensure_app_data_dir('ubelt') >>> assert exists(dpath)
- ubelt.util_platform.get_app_cache_dir(appname, *args)[source]¶
Returns a writable directory for an application. This should be used for temporary deletable data.
Note
New applications should prefer
ubelt.util_path.Path.appdir()
i.e.ubelt.Path.appdir(appname, *args, type='cache')
.- Parameters
appname (str) – the name of the application
*args – any other subdirectories may be specified
- Returns
the path to the ensured directory
- Return type
- Returns
dpath - writable cache directory for this application
- Return type
- SeeAlso:
- ubelt.util_platform.get_app_config_dir(appname, *args)[source]¶
Returns a writable directory for an application This should be used for persistent configuration files.
Note
New applications should prefer
ubelt.util_path.Path.appdir()
i.e.ubelt.Path.appdir(appname, *args, type='config')
.- Parameters
appname (str) – the name of the application
*args – any other subdirectories may be specified
- Returns
dpath - writable config directory for this application
- Return type
- SeeAlso:
- ubelt.util_platform.get_app_data_dir(appname, *args)[source]¶
Returns a writable directory for an application. This should be used for temporary deletable data.
Note
New applications should prefer
ubelt.util_path.Path.appdir()
i.e.ubelt.Path.appdir(appname, *args, type='data')
.- Parameters
appname (str) – the name of the application
*args – any other subdirectories may be specified
- Returns
dpath - writable data directory for this application
- Return type
- SeeAlso:
- ubelt.util_platform.platform_cache_dir()[source]¶
Returns a directory which should be writable for any application This should be used for temporary deletable data.
- Returns
path to the cache dir used by the current operating system
- Return type