nanoutils.utils

General utility functions.

Index

PartialPrepend

A partial() subclass where the *args are appended rather than prepended.

SetAttr(obj, name, value)

A context manager for temporarily changing an attribute's value.

VersionInfo(major[, minor, micro])

A namedtuple() representing the version of a package.

group_by_values(iterable)

Take an iterable, yielding 2-tuples, and group all first elements by the second.

get_importable(string[, validate])

Get an importable object.

construct_api_doc(glob_dict[, decorators])

Format a Nano-Utils module-level docstring.

split_dict(dct[, preserve_order, keep_keys, ...])

Pop all items from dct which are in not in keep_keys and use them to construct a new dictionary.

get_func_name(func[, prepend_module, ...])

Extract and return the name of func.

set_docstring(docstring)

A decorator for assigning docstrings.

raise_if(exception)

A decorator which raises the passed exception whenever calling the decorated function.

ignore_if(exception[, warn])

A decorator which, if an exception is passed, ignores calls to the decorated function.

SequenceView(sequence)

A read-only view of an underlying Sequence.

CatchErrors(*exceptions)

A re-usable context manager for catching and storing all exceptions of a given type.

LazyImporter(module, imports)

A class for lazilly importing objects.

MutableLazyImporter(module, imports)

A subclass of LazyImporter with mutable imports.

positional_only(func)

A decorator for converting mangled parameters to positional-only.

UserMapping([iterable])

Base class for user-defined immutable mappings.

MutableUserMapping([iterable])

Base class for user-defined mutable mappings.

warning_filter(action[, message, category, ...])

A decorator for wrapping function calls with warnings.filterwarnings().

API

class nanoutils.PartialPrepend[source]

A partial() subclass where the *args are appended rather than prepended.

Examples

>>> from functools import partial
>>> from nanoutils import PartialPrepend

>>> func1 = partial(isinstance, 1)  # isinstance(1, ...)
>>> func2 = PartialPrepend(isinstance, float)  # isinstance(..., float)

>>> func1(int)  # isinstance(1, int)
True

>>> func2(1.0)  # isinstance(1.0, float)
True
class nanoutils.SetAttr(obj, name, value)[source]

A context manager for temporarily changing an attribute’s value.

The SetAttr context manager is thread-safe, reusable and reentrant.

Warning

Note that while SetAttr.__enter__() and SetAttr.__exit__() are thread-safe, the same does not hold for SetAttr.__init__().

Examples

>>> from nanoutils import SetAttr

>>> class Test:
...     a = False

>>> print(Test.a)
False

>>> set_attr = SetAttr(Test, 'a', True)
>>> with set_attr:
...     print(Test.a)
True
property obj

Get the to-be modified object.

Type:

object

property name

Get the name of the to-be modified attribute.

Type:

str

property value

Get the value to-be assigned to the name attribute of SetAttr.obj.

Type:

object

property attr

Get or set the name attribute of SetAttr.obj.

Type:

object

class nanoutils.VersionInfo(major, minor=0, micro=0)[source]

A namedtuple() representing the version of a package.

Examples

>>> from nanoutils import VersionInfo

>>> version = '0.8.2'
>>> VersionInfo.from_str(version)
VersionInfo(major=0, minor=8, micro=2)
major

The semantic major version.

Type:

int

minor

The semantic minor version.

Type:

int

micro

The semantic micro version.

Type:

int

property patch

An alias for VersionInfo.micro.

Type:

int

property maintenance

An alias for VersionInfo.micro.

Type:

int

property bug

An alias for VersionInfo.micro.

Type:

int

classmethod from_str(version, *, fullmatch=True)[source]

Construct a VersionInfo from a string.

Parameters:
  • version (str) – A PEP 440-compatible version string(e.g. version = "0.8.2"). Note that version representations are truncated at up to three integers.

  • fullmatch (bool) – Whether to perform a full or partial match on the passed string.

Returns:

A new VersionInfo instance.

Return type:

nanoutils.VersionInfo

See also

PEP 440

This PEP describes a scheme for identifying versions of Python software distributions, and declaring dependencies on particular versions.

nanoutils.group_by_values(iterable)[source]

Take an iterable, yielding 2-tuples, and group all first elements by the second.

Examples

>>> str_list: list = ['a', 'a', 'a', 'a', 'a', 'b', 'b', 'b', 'c']
>>> iterator = enumerate(str_list, 1)

>>> new_dict: dict = group_by_values(iterator)
>>> print(new_dict)
{'a': [1, 2, 3, 4, 5], 'b': [6, 7, 8], 'c': [9]}
Parameters:

iterable (Iterable[tuple[VT, KT]]) – An iterable yielding 2 elements upon iteration (e.g. dict.items() or enumerate()). The second element must be Hashable and will be used as key in the to-be returned mapping.

Returns:

A grouped dictionary.

Return type:

dict[KT, list[VT]]

nanoutils.get_importable(string, validate=None)[source]

Get an importable object.

Examples

>>> from inspect import isclass
>>> from nanoutils import get_importable

>>> dict_type = get_importable('builtins.dict', validate=isclass)
>>> print(dict_type)
<class 'dict'>
Parameters:
  • string (str) – A string representing an importable object. Note that the string must contain the object’s module.

  • validate (Callable, optional) – A callable for validating the imported object. Will raise a RuntimeError if its output evaluates to False.

Returns:

The imported object

Return type:

object

nanoutils.construct_api_doc(glob_dict, decorators=frozenset({}))[source]

Format a Nano-Utils module-level docstring.

Examples

>>> __doc__ = """
... Index
... -----
... .. autosummary::
... {autosummary}
...
... API
... ---
... {autofunction}
...
... """

>>> from nanoutils import construct_api_doc

>>> __all__ = ['obj', 'func', 'Class']

>>> obj = ...

>>> def func(obj: object) -> None:
...     pass

>>> class Class(object):
...     pass

>>> doc = construct_api_doc(locals())
>>> print(doc)

Index
-----
.. autosummary::
    obj
    func
    Class

API
---
.. autodata:: obj
.. autofunction:: func
.. autoclass:: Class
    :members:

Parameters:
  • glob_dict (Mapping[str, object]) – A mapping containg a module-level namespace. Note that the mapping must contain the "__doc__" and "__all__" keys.

  • decorators (Container[str]) – A container with the names of all decorators. If not specified, all functions will use the Sphinx autofunction domain.

Returns:

The formatted string.

Return type:

str

nanoutils.split_dict(dct, preserve_order=False, *, keep_keys=None, disgard_keys=None)[source]

Pop all items from dct which are in not in keep_keys and use them to construct a new dictionary.

Note that, by popping its keys, the passed dct will also be modified inplace.

Examples

>>> from nanoutils import split_dict

>>> dict1 = {1: 'a', 2: 'b', 3: 'c', 4: 'd'}
>>> dict2 = split_dict(dict1, keep_keys={1, 2})

>>> print(dict1, dict2, sep='\n')
{1: 'a', 2: 'b'}
{3: 'c', 4: 'd'}

>>> dict3 = split_dict(dict1, disgard_keys={1, 2})
>>> print(dict1, dict3, sep='\n')
{}
{1: 'a', 2: 'b'}
Parameters:
  • dct (MutableMapping[KT, VT]) – A mutable mapping.

  • preserve_order (bool) – If True, preserve the order of the items in dct. Note that preserve_order = False is generally faster.

  • keep_keys (Iterable[KT], keyword-only) – An iterable with keys that should remain in dct. Note that keep_keys and disgard_keys are mutually exclusive.

  • disgard_keys (Iterable[KT], keyword-only) – An iterable with keys that should be removed from dct. Note that disgard_keys and keep_keys are mutually exclusive.

Returns:

A new dictionaries with all key/value pairs from dct not specified in keep_keys.

Return type:

dict[KT, VT]

nanoutils.get_func_name(func, prepend_module=False, repr_fallback=False)[source]

Extract and return the name of func.

A total of three attempts are performed at retrieving the passed functions name:

  1. Return the functions qualified name (__qualname__).

  2. Return the functions name (__name__).

  3. Return the (called) name of the functions type.

Examples

>>> from functools import partial
>>> from nanoutils import get_func_name

>>> def func1():
...     pass

>>> class Class():
...     def func2(self):
...         pass

>>> func3 = partial(len)

>>> get_func_name(func1)
'func1'

>>> get_func_name(func1, prepend_module=True)  
'__main__.func1'

>>> get_func_name(Class.func2)
'Class.func2'

>>> get_func_name(func3)
'partial(...)'

>>> get_func_name(func3, repr_fallback=True)
'functools.partial(<built-in function len>)'
Parameters:
  • func (Callable) – A callable object.

  • prepend_module (bool) – If True prepend the objects module (__module__), if available, to the to-be returned string.

  • repr_fallback (bool) – By default, when the passed function has neither a __qualname__ or __name__ attribute the (called) name of the functions class is returned. If True then use repr() instead.

Returns:

A string representation of the name of func.

Return type:

str

@nanoutils.set_docstring[source]

A decorator for assigning docstrings.

Examples

>>> from nanoutils import set_docstring

>>> number = "#10"

>>> @set_docstring(f"Fancy docstring {number}.")
... def func():
...     pass

>>> print(func.__doc__)
Fancy docstring #10.
Parameters:

docstring (str, optional) – The to-be assigned docstring.

@nanoutils.raise_if[source]

A decorator which raises the passed exception whenever calling the decorated function.

If exception is None then the decorated function will be called as usual.

Examples

>>> from nanoutils import raise_if

>>> ex1 = None
>>> ex2 = TypeError("This is an exception")

>>> @raise_if(ex1)
... def func1() -> bool:
...     return True

>>> @raise_if(ex2)
... def func2() -> bool:
...     return True

>>> func1()
True

>>> func2()
Traceback (most recent call last):
  ...
TypeError: This is an exception
Parameters:

exception (BaseException, optional) – An exception. If None is passed then the decorated function will be called as usual.

See also

nanoutils.ignore_if()

A decorator which, if an exception is passed, ignores calls to the decorated function.

@nanoutils.ignore_if(exception, warn=True)[source]

A decorator which, if an exception is passed, ignores calls to the decorated function.

If exception is None then the decorated function will be called as usual.

Examples

>>> import warnings
>>> from nanoutils import ignore_if

>>> ex1 = None
>>> ex2 = TypeError("This is an exception")

>>> @ignore_if(ex1)
... def func1() -> bool:
...     return True

>>> @ignore_if(ex2)
... def func2() -> bool:
...     return True

>>> func1()
True

>>> func2()

# Catch the warning and a raise it as an exception
>>> with warnings.catch_warnings():
...     warnings.simplefilter("error", UserWarning)
...     func2()
Traceback (most recent call last):
  ...
UserWarning: Skipping call to func2()
Parameters:
  • exception (BaseException, optional) – An exception. If None is passed then the decorated function will be called as usual.

  • warn (bool) – If True issue a UserWarning whenever calling the decorated function

See also

nanoutils.raise_if()

A decorator which raises the passed exception whenever calling the decorated function.

class nanoutils.SequenceView(sequence)[source]

A read-only view of an underlying Sequence.

Examples

>>> from nanoutils import SequenceView

>>> lst = [1, 2, 3]
>>> view = SequenceView(lst)
>>> print(view)
SequenceView([1, 2, 3])

>>> lst.append(4)
>>> print(view)
SequenceView([1, 2, 3, 4])

>>> print(len(view))
4

>>> del view[0]
Traceback (most recent call last):
    ...
TypeError: 'SequenceView' object doesn't support item deletion
pprint_kwargs = {'compact': True, 'sort_dicts': False, 'width': 67}

A class variable containing a dictionary with keyword arguments for pprint.pformat().

index(value, start=0, stop=9223372036854775807, /)[source]

Return the first index of value.

count(value, /)[source]

Return the number of times value occurs in the instance.

class nanoutils.CatchErrors(*exceptions)[source]

A re-usable context manager for catching and storing all exceptions of a given type.

Examples

>>> from nanoutils import CatchErrors

>>> context = CatchErrors(AssertionError)

>>> for i in range(3):
...     with context as exc_view:
...         assert False, i  
...         print(exc_view)
SequenceView([AssertionError(0)])
SequenceView([AssertionError(0), AssertionError(1)])
SequenceView([AssertionError(0), AssertionError(1), AssertionError(2)])

See also

contextlib.suppress

Context manager to suppress specified exceptions.

property exceptions

Get the to-be caught exception types.

property caught_exceptions

Get a read-only view of all caught exceptions.

clear()[source]

Clear all caught exceptions.

class nanoutils.LazyImporter(module, imports)[source]

A class for lazilly importing objects.

Parameters:
  • module (types.ModuleType) – The to-be wrapped module.

  • imports (Mapping[str, str]) – A mapping that maps the names of to-be lazzily imported objects to the names of their modules.

Examples

>>> from nanoutils import LazyImporter

>>> __getattr__ = LazyImporter.from_name("nanoutils", {"Any": "typing"})
>>> print(__getattr__)
LazyImporter(module=nanoutils, imports={'Any': 'typing'})

>>> __getattr__("Any")
typing.Any
property module

Get the wrapped module.

Type:

types.ModuleType

property imports

Get a mapping that maps object names to their module name.

Type:

types.MappingProxyType[str, str]

classmethod from_name(name, imports)[source]

Construct a new instance from the module name.

Parameters:
  • name (str) – The name of the to-be wrapped module.

  • imports (Mapping[str, str]) – A mapping that maps the names of to-be lazzily imported objects to the names of their modules.

Returns:

A new LazyImporter instance or a subclass thereof.

Return type:

nanoutils.LazyImporter

class nanoutils.MutableLazyImporter(module, imports)[source]

A subclass of LazyImporter with mutable imports.

Parameters:
  • module (types.ModuleType) – The to-be wrapped module.

  • imports (Mapping[str, str]) – A mapping that maps the names of to-be lazzily imported objects to the names of their modules.

Examples

>>> from nanoutils import MutableLazyImporter

>>> __getattr__ = MutableLazyImporter.from_name("nanoutils", {"Any": "typing"})
>>> print(__getattr__)
MutableLazyImporter(module=nanoutils, imports={'Any': 'typing'})

>>> __getattr__("Any")
typing.Any

>>> del __getattr__.imports["Any"]
>>> print(__getattr__)
MutableLazyImporter(module=nanoutils, imports={})

>>> __getattr__.imports = {"Hashable": "collections.abc"}
>>> __getattr__("Hashable")
<class 'collections.abc.Hashable'>
property imports

Get or set the dictionary that maps object names to their module name.

Setting a value will assign it as a copy.

Type:

dict[str, str]

@nanoutils.positional_only[source]

A decorator for converting mangled parameters to positional-only.

Sets the __signature__ attribute of the decorated function.

Examples

>>> from nanoutils import positional_only
>>> import inspect

>>> def func1(__a, b=None):
...     pass

>>> print(inspect.signature(func1))
(__a, b=None)

>>> @positional_only
... def func2(__a, b=None):
...     pass

>>> print(inspect.signature(func2))
(a, /, b=None)
Parameters:

func (Callable) – The to-be decorated function whose __signature__ attribute will be added or updated.

class nanoutils.UserMapping(iterable=None, /, **kwargs)[source]

Base class for user-defined immutable mappings.

copy()[source]

Return a deep copy of this instance.

keys()[source]

Return a set-like object containing all keys.

items()[source]

Return a set-like object containing all key/value pairs.

values()[source]

Return a collection containing all values.

get(key, default=None)[source]

Return the value for key if the key is present, else default.

classmethod fromkeys(iterable, value=None)[source]

Create a new dictionary with keys from iterable and values set to default.

class nanoutils.MutableUserMapping(iterable=None, /, **kwargs)[source]

Base class for user-defined mutable mappings.

clear()[source]

Remove all items from the mapping.

popitem()[source]

Remove and return a (key, value) pair as a 2-tuple.

Pairs are returned in LIFO (last-in, first-out) order. Raises a KeyError if the mapping is empty.

pop(key, default=<object object>)[source]

Remove the specified key and return the corresponding value.

If the key is not found, default is returned if given, otherwise a KeyError is raised.

update(iterable=None, /, **kwargs)[source]

Update the mapping from the passed mapping or iterable.

@nanoutils.warning_filter(action, message='', category=<class 'Warning'>, module='', lineno=0, append=False)[source]

A decorator for wrapping function calls with warnings.filterwarnings().

Examples

>>> from nanoutils import warning_filter
>>> import warnings

>>> @warning_filter("error", category=UserWarning)
... def func():
...     warnings.warn("test", UserWarning)

>>> func()
Traceback (most recent call last):
    ...
UserWarning: test
Parameters:
  • action (str) –

    One of the following strings:

    • "default": Print the first occurrence of matching warnings for each location (module + line number) where the warning is issued

    • "error": Turn matching warnings into exceptions

    • "ignore": Never print matching warnings

    • "always": Always print matching warnings

    • "module": Print the first occurrence of matching warnings for each module where the warning is issued (regardless of line number)

    • "once": Print only the first occurrence of matching warnings, regardless of location

  • message (str, optional) – A string containing a regular expression that the start of the warning message must match. The expression is compiled to always be case-insensitive.

  • category (type[Warning]) – The to-be affected Warning (sub-)class.

  • module (str, optional) – A string containing a regular expression that the module name must match. The expression is compiled to be case-sensitive.

  • lineno (int) – An integer that the line number where the warning occurred must match, or 0 to match all line numbers.

  • append (bool) – Whether the warning entry is inserted at the end.

See also

warnings.filterwarnings()

Insert a simple entry into the list of warnings filters (at the front).