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)
property major

The semantic major version.

Type

int

property minor

The semantic minor version.

Type

int

property 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, '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).