From 8a43e71051a219723548dcc27313b22e71a4b83a Mon Sep 17 00:00:00 2001 From: joncrall Date: Sun, 8 Sep 2024 16:13:29 -0400 Subject: [PATCH] Documentation improvements --- ubelt/_win32_links.py | 10 +++--- ubelt/util_arg.py | 13 +++++--- ubelt/util_dict.py | 6 ++-- ubelt/util_download.py | 47 ++++++++++++++++----------- ubelt/util_download_manager.py | 3 +- ubelt/util_func.py | 8 ++--- ubelt/util_hash.py | 2 +- ubelt/util_import.py | 2 +- ubelt/util_indexable.py | 5 +-- ubelt/util_links.py | 6 ++-- ubelt/util_list.py | 59 +++++++++++++++++++++------------- ubelt/util_platform.py | 13 ++++---- ubelt/util_str.py | 4 +-- 13 files changed, 103 insertions(+), 75 deletions(-) diff --git a/ubelt/_win32_links.py b/ubelt/_win32_links.py index 1c948adaa..6e739fc5e 100644 --- a/ubelt/_win32_links.py +++ b/ubelt/_win32_links.py @@ -38,17 +38,17 @@ __win32_can_symlink__ = None # type: bool | None -def _win32_can_symlink(verbose=0, force=0, testing=0): +def _win32_can_symlink(verbose=0, force=False, testing=False): """ Args: - verbose (int, default=0): flag - force (int, default=0): flag - testing (int, default=0): flag + verbose (int): verbosity level + force (bool): flag + testing (bool): flag Example: >>> # xdoctest: +REQUIRES(WIN32) >>> import ubelt as ub - >>> _win32_can_symlink(verbose=3, force=1, testing=1) + >>> _win32_can_symlink(verbose=3, force=True, testing=True) """ global __win32_can_symlink__ if verbose: diff --git a/ubelt/util_arg.py b/ubelt/util_arg.py index 2680d0a21..378d6c502 100644 --- a/ubelt/util_arg.py +++ b/ubelt/util_arg.py @@ -33,14 +33,15 @@ def argval(key, default=util_const.NoParam, argv=None): string or tuple of strings. Each key should be prefixed with two hyphens (i.e. ``--``) - default (T | NoParamType, default=NoParam): + default (Any | NoParamType): a value to return if not specified. - argv (List[str] | None, default=None): - uses ``sys.argv`` if unspecified + argv (List[str] | None): + The command line arguments to parse. + If unspecified, uses ``sys.argv`` directly. Returns: - str | T: + str | Any: value - the value specified after the key. It they key is specified multiple times, then the first value is returned. @@ -112,7 +113,9 @@ def argflag(key, argv=None): string or tuple of strings. Each key should be prefixed with two hyphens (i.e. ``--``). - argv (List[str] | None, default=None): overrides ``sys.argv`` if specified + argv (List[str] | None): + The command line arguments to parse. + If unspecified, uses ``sys.argv`` directly. Returns: bool: flag - True if the key (or any of the keys) was specified diff --git a/ubelt/util_dict.py b/ubelt/util_dict.py index 3aff25e5d..2509da55c 100644 --- a/ubelt/util_dict.py +++ b/ubelt/util_dict.py @@ -652,7 +652,7 @@ def sorted_values(dict_, key=None, reverse=False, cls=OrderedDict): If given as a callable, customizes the sorting by ordering using transformed values. - reverse (bool, default): + reverse (bool): If True returns in descending order. Defaults to False. cls (type): Specifies the dict return type. Default to OrderedDict. @@ -2018,7 +2018,7 @@ def sorted_keys(self, key=None, reverse=False): If given as a callable, customizes the sorting by ordering using transformed keys. - reverse (bool, default=False): + reverse (bool): if True returns in descending order Returns: @@ -2044,7 +2044,7 @@ def sorted_values(self, key=None, reverse=False): If given as a callable, customizes the sorting by ordering using transformed values. - reverse (bool, default=False): + reverse (bool): if True returns in descending order Returns: diff --git a/ubelt/util_download.py b/ubelt/util_download.py index d98034df8..9a2c4196f 100644 --- a/ubelt/util_download.py +++ b/ubelt/util_download.py @@ -2,11 +2,11 @@ Helpers for downloading data The :func:`download` function access the network and requests the content at a -specific url using :mod:`urllib` or :mod:`urllib2`. You can either specify -where the data goes or download it to the default location in ubelt cache. -Either way this function returns the location of the downloaded data. You can -also specify the expected hash in order to check the validity of the data. By -default downloading is verbose. +specific url using :mod:`urllib`. You can either specify where the data goes or +download it to the default location in ubelt cache. Either way this function +returns the location of the downloaded data. You can also specify the expected +hash in order to check the validity of the data. By default downloading is +verbose. The :func:`grabdata` function is almost identitcal to :func:`download`, but it checks if the data already exists in the download location, and only downloads @@ -38,9 +38,9 @@ def download(url, fpath=None, dpath=None, fname=None, appname=None, fpath (str | PathLike | io.BytesIO | None): The path to download to. Defaults to basename of url and ubelt's - application cache. If this is a io.BytesIO object then information - is directly written to this object (note this prevents the use of - temporary files). + application cache. If this is a :class:`io.BytesIO` object then + information is directly written to this object (note this prevents + the use of temporary files). dpath (str | PathLike | None): where to download the file. If unspecified `appname` is used to @@ -122,6 +122,20 @@ def download(url, fpath=None, dpath=None, fname=None, appname=None, Example: >>> # xdoctest: +REQUIRES(--network) + >>> # To ensure you get the file you are expecting, it is a good idea + >>> # to specify a hash that will be checked. + >>> import ubelt as ub + >>> url = 'http://i.imgur.com/rqwaDag.png' + >>> fpath = ub.download(url, hasher='sha1', hash_prefix='f79ea24571da6ddd2ba12e3d57b515249ecb8a35') + >>> print(ub.Path(fpath).name) + Downloading url='http://i.imgur.com/rqwaDag.png' to fpath=...rqwaDag.png + ... + ...1233/1233... rate=... Hz, eta=..., total=... + rqwaDag.png + + Example: + >>> # xdoctest: +REQUIRES(--network) + >>> # You can save directly to bytes in memory using a BytesIO object. >>> import ubelt as ub >>> import io >>> url = 'http://i.imgur.com/rqwaDag.png' @@ -133,14 +147,8 @@ def download(url, fpath=None, dpath=None, fname=None, appname=None, Example: >>> # xdoctest: +REQUIRES(--network) - >>> url = 'http://i.imgur.com/rqwaDag.png' - >>> fpath = download(url, hasher='sha1', hash_prefix='f79ea24571da6ddd2ba12e3d57b515249ecb8a35') - Downloading url='http://i.imgur.com/rqwaDag.png' to fpath=...rqwaDag.png - ... - ...1233/1233... rate=... Hz, eta=..., total=... - - Example: - >>> # xdoctest: +REQUIRES(--network) + >>> # Bad hashes will raise a RuntimeError, which could indicate + >>> # corrupted data or a security issue. >>> import pytest >>> import ubelt as ub >>> url = 'http://i.imgur.com/rqwaDag.png' @@ -185,6 +193,7 @@ def download(url, fpath=None, dpath=None, fname=None, appname=None, url, fpath)) requestkw = requestkw or {} + requestkw['headers'] = {'User-Agent': 'Mozilla/5.0'} req = Request(url, **requestkw) urldata = urlopen(req, timeout=timeout) @@ -358,8 +367,8 @@ def grabdata(url, fpath=None, dpath=None, fname=None, redo=False, seconds to wait before the cache should expire. **download_kw: additional kwargs to pass to - :func:`ubelt.util_download.download`. This includes `chunksize`, - `filesize`, `timeout`, `progkw`, and `requestkw`. + :func:`ubelt.util_download.download`. This includes ``chunksize``, + ``filesize``, ``timeout``, ``progkw``, and ``requestkw``. Ignore: # helper logic to determine what needs to be documented for download_kw @@ -368,7 +377,7 @@ def grabdata(url, fpath=None, dpath=None, fname=None, redo=False, grabdata_sig = inspect.signature(ub.grabdata) download_sig = inspect.signature(ub.download) extra = ub.udict(download_sig.parameters) - ub.udict(grabdata_sig.parameters) - print(', '.join([f'`{k}`' for k in extra.keys()])) + print(', '.join([f'``{k}``' for k in extra.keys()])) Returns: str | PathLike: fpath - path to downloaded or cached file. diff --git a/ubelt/util_download_manager.py b/ubelt/util_download_manager.py index 8f9c12afe..abf25f9c2 100644 --- a/ubelt/util_download_manager.py +++ b/ubelt/util_download_manager.py @@ -94,8 +94,9 @@ def submit(self, url, dst=None, hash_prefix=None, hasher='sha256'): If unspecified, the destination name is derived from the url. hash_prefix (str | None): If specified, verifies that the hash of the downloaded file starts with this. - hasher (str, default='sha256'): + hasher (str): hashing algorithm to use if hash_prefix is specified. + Defaults to ``'sha256'``. Returns: concurrent.futures.Future : diff --git a/ubelt/util_func.py b/ubelt/util_func.py index 92252297d..1e47acd03 100644 --- a/ubelt/util_func.py +++ b/ubelt/util_func.py @@ -34,7 +34,7 @@ def identity(arg=None, *args, **kwargs): assigning it to a value. Args: - arg (Any | None, default=None): The value to return unchanged. + arg (Any | None): The value to return unchanged. *args: Ignored **kwargs: Ignored @@ -71,9 +71,9 @@ def inject_method(self, func, name=None): func (Callable[..., Any]): The function to inject (must contain an arg for self). - name (str | None, default=None): - Name of the method. optional. If not specified the name of the - function is used. + name (str | None): + Specify the name of the new method. + If not specified the name of the function is used. Example: >>> import ubelt as ub diff --git a/ubelt/util_hash.py b/ubelt/util_hash.py index 9616f7e00..6355f2fc8 100644 --- a/ubelt/util_hash.py +++ b/ubelt/util_hash.py @@ -1187,7 +1187,7 @@ def hash_data(data, hasher=NoParam, base=NoParam, types=False, convert=False, If True data types are included in the hash, otherwise only the raw data is hashed. Defaults to False. - convert (bool, default=True): + convert (bool): if True, try and convert the data to json an the json is hashed instead. This can improve runtime in some instances, however the hash may differ from the case where convert=False. diff --git a/ubelt/util_import.py b/ubelt/util_import.py index 0a7fd691a..907c5e4cf 100644 --- a/ubelt/util_import.py +++ b/ubelt/util_import.py @@ -948,7 +948,7 @@ def is_modname_importable(modname, sys_path=None, exclude=None): Args: modname (str): name of module to check - sys_path (list | None, default=None): if specified overrides ``sys.path`` + sys_path (list | None): if specified overrides ``sys.path`` exclude (list | None): list of directory paths. if specified prevents these directories from being searched. diff --git a/ubelt/util_indexable.py b/ubelt/util_indexable.py index 0014db0d8..edf2bc113 100644 --- a/ubelt/util_indexable.py +++ b/ubelt/util_indexable.py @@ -372,7 +372,8 @@ def allclose(self, other, rel_tol=1e-9, abs_tol=0.0, equal_nan=False, return_inf equal_nan (bool): if True, numpy must be available, and consider nans as equal. - return_info (bool, default=False): if true, return extra info dict + return_info (bool): + if True, return extra info dict. Defaults to False. Returns: bool | Tuple[bool, Dict] : @@ -689,7 +690,7 @@ def indexable_allclose(items1, items2, rel_tol=1e-9, abs_tol=0.0, return_info=Fa maximum difference for being considered "close", regardless of the magnitude of the input values - return_info (bool, default=False): if true, return extra info + return_info (bool): if True, return extra info. Defaults to False. Returns: bool | Tuple[bool, Dict] : diff --git a/ubelt/util_links.py b/ubelt/util_links.py index a34ec701a..017737d69 100644 --- a/ubelt/util_links.py +++ b/ubelt/util_links.py @@ -49,13 +49,13 @@ def symlink(real_path, link_path, overwrite=False, verbose=0): link_path (str | PathLike): path to desired location for symlink - overwrite (bool, default=False): overwrite existing symlinks. + overwrite (bool): overwrite existing symlinks. This will not overwrite real files on systems with proper symlinks. However, on older versions of windows junctions are indistinguishable from real files, so we cannot make this - guarantee. + guarantee. Defaults to False. - verbose (int, default=0): verbosity level + verbose (int): verbosity level. Defaults to 0. Returns: str | PathLike: link path diff --git a/ubelt/util_list.py b/ubelt/util_list.py index c682f4649..d7bac2003 100644 --- a/ubelt/util_list.py +++ b/ubelt/util_list.py @@ -316,8 +316,9 @@ def iterable(obj, strok=False): Args: obj (object): a scalar or iterable input - strok (bool, default=False): - if True allow strings to be interpreted as iterable + strok (bool): + if True allow strings to be interpreted as iterable. + Defaults to False. Returns: bool: True if the input is iterable @@ -355,8 +356,10 @@ def take(items, indices, default=util_const.NoParam): indices (Iterable[int | KT]): A sequence of indexes into ``items``. - default (Any, default=NoParam): - if specified ``items`` must support the ``get`` method. + + default (Any | NoParamType): + if specified ``items`` must support the ``get`` method and + this will be used as the default value. Yields: VT: a selected item within the list @@ -467,8 +470,10 @@ def unique(items, key=None): Args: items (Iterable[T]): list of items - key (Callable[[T], Any] | None, default=None): custom normalization function. - If specified returns items where ``key(item)`` is unique. + key (Callable[[T], Any] | None): + Custom normalization function. + If specified, this function generates items where ``key(item)`` is + unique. Yields: T: @@ -512,8 +517,10 @@ def argunique(items, key=None): Args: items (Sequence[VT]): indexable collection of items - key (Callable[[VT], Any] | None, default=None): custom normalization function. - If specified returns items where ``key(item)`` is unique. + key (Callable[[VT], Any] | None): + Custom normalization function. + If specified, this function generates indexes where + ``key(item[index])`` is unique. Returns: Iterator[int] : indices of the unique items @@ -540,9 +547,10 @@ def unique_flags(items, key=None): Args: items (Sequence[VT]): indexable collection of items - key (Callable[[VT], Any] | None, default=None): custom normalization - function. If specified returns items where ``key(item)`` is - unique. + key (Callable[[VT], Any] | None): + Custom normalization function. + If specified generates True if ``key(item)`` is unique and False + otherwise. Returns: List[bool] : flags the items that are unique @@ -609,11 +617,15 @@ def iter_window(iterable, size=2, step=1, wrap=False): Args: iterable (Iterable[T]): an iterable sequence - size (int, default=2): sliding window size + size (int): Sliding window size. Defaults to 2. - step (int, default=1): sliding step size + step (int): Sliding step size. Default to 1. - wrap (bool, default=False): wraparound flag + wrap (bool): + If True, the last window will "wrap-around" to include items from + the start of the input sequence in order to always produce + consistently sized chunks. Otherwise, the last chunk may be smaller + if there are not enough items in the sequence.. Defaults to False. Returns: Iterable[T]: returns a possibly overlapping windows in a sequence @@ -687,8 +699,9 @@ def allsame(iterable, eq=operator.eq): iterable (Iterable[T]): items to determine if they are all the same - eq (Callable[[T, T], bool], default=operator.eq): - function used to test for equality + eq (Callable[[T, T], bool]): + function used to test for equality. + Defaults to :func:`operator.eq`. Returns: bool: True if all items are equal, otherwise False @@ -731,10 +744,10 @@ def argsort(indexable, key=None, reverse=False): Args: indexable (Iterable[VT] | Mapping[KT, VT]): indexable to sort by - key (Callable[[VT], VT] | None, default=None): - customizes the ordering of the indexable + key (Callable[[VT], VT] | None): + If specified, customizes the ordering of the indexable. - reverse (bool, default=False): if True returns in descending order + reverse (bool): if True returns in descending order. Default to False. Returns: List[int] | List[KT]: @@ -788,8 +801,8 @@ def argmax(indexable, key=None): Args: indexable (Iterable[VT] | Mapping[KT, VT]): indexable to sort by - key (Callable[[VT], Any] | None, default=None): - customizes the ordering of the indexable + key (Callable[[VT], Any] | None): + If specified, customizes the ordering of the indexable Returns: int | KT: the index of the item with the maximum value. @@ -824,8 +837,8 @@ def argmin(indexable, key=None): Args: indexable (Iterable[VT] | Mapping[KT, VT]): indexable to sort by - key (Callable[[VT], VT] | None, default=None): - customizes the ordering of the indexable + key (Callable[[VT], VT] | None): + If specified, customizes the ordering of the indexable. Returns: int | KT: the index of the item with the minimum value. diff --git a/ubelt/util_platform.py b/ubelt/util_platform.py index 9f3ce053b..9940a8df8 100644 --- a/ubelt/util_platform.py +++ b/ubelt/util_platform.py @@ -305,11 +305,12 @@ def find_exe(name, multi=False, path=None): Args: name (str | PathLike): globstr of matching filename - multi (bool, default=False): + multi (bool): if True return all matches instead of just the first. + Defaults to False. - path (str | PathLike | Iterable[str | PathLike] | None, default=None): - overrides the system PATH variable. + path (str | PathLike | Iterable[str | PathLike] | None): + If specified, overrides the system PATH variable. Returns: str | List[str] | None: returns matching executable(s). @@ -381,12 +382,12 @@ def find_path(name, path=None, exact=False): 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): + path (str | Iterable[str | PathLike] | 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. + exact (bool): if True, only returns exact matches. Defaults to False. Yields: str: candidate - a path that matches ``name`` @@ -397,7 +398,7 @@ def find_path(name, path=None, exact=False): Note: For recursive behavior set ``path=(d for d, _, _ in os.walk('.'))``, - where '.' might be replaced by the root directory of interest. + where ``'.'`` might be replaced by the root directory of interest. Example: >>> # xdoctest: +IGNORE_WANT diff --git a/ubelt/util_str.py b/ubelt/util_str.py index 4a78adb9e..14bf80c3d 100644 --- a/ubelt/util_str.py +++ b/ubelt/util_str.py @@ -25,7 +25,7 @@ def indent(text, prefix=' '): Args: text (str): text to indent - prefix (str, default = ' '): prefix to add to each line + prefix (str): prefix to add to each line. Defaults to ``' '`` Returns: str: indented text @@ -123,7 +123,7 @@ def hzcat(args, sep=''): Args: args (List[str]): strings to concatenate - sep (str, default=''): separator + sep (str): separator. Defaults to ``''``. Example1: >>> import ubelt as ub