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] (deprecated as of 2023-02-10) and its successor platformdirs [PlatDirs].

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

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:

str | List[str] | None

SeeAlso:

shutil.which() - which is available in Python 3.3+.

Note

This is essentially the which UNIX command

References

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] | None, 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:

str

SeeAlso:

get_app_cache_dir()

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:

str

SeeAlso:

get_app_config_dir()

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:

str

SeeAlso:

get_app_data_dir()

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:

str

Returns:

dpath - writable cache directory for this application

Return type:

str

SeeAlso:

ensure_app_cache_dir()

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:

str

SeeAlso:

ensure_app_config_dir()

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:

str

SeeAlso:

ensure_app_data_dir()

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:

str

ubelt.util_platform.platform_config_dir()[source]

Returns a directory which should be writable for any application This should be used for persistent configuration files.

Returns:

path to the cache dir used by the current operating system

Return type:

str

ubelt.util_platform.platform_data_dir()[source]

Returns path for user-specific data files

Returns:

path to the data dir used by the current operating system

Return type:

str