types¶
Module with general purpose types.
-
nutils.types.
argument_canonicalizer
(signature)¶ Returns a function that converts arguments matching
signature
to canonical positional and keyword arguments. If possible, an argument is added to the list of positional arguments, otherwise to the keyword arguments dictionary. The returned arguments include default values.Parameters: signature ( inspect.Signature
) – The signature of a function to generate canonical arguments for.Returns: A function that returns a tuple
of atuple
of positional arguments and adict
of keyword arguments.Return type: callable
Examples
Consider the following function.
>>> def f(a, b=4, *, c): pass
The
argument_canonicalizer
forf
is generated as follows:>>> canon = argument_canonicalizer(inspect.signature(f))
Calling
canon
with parameterb
passed as keyword returns arguments with parameterb
as positional argument:>>> canon(1, c=3, b=2) ((1, 2), {'c': 3})
When calling
canon
without parameterb
the default value is added to the positional arguments:>>> canon(1, c=3) ((1, 4), {'c': 3})
-
nutils.types.
nutils_hash
(data)¶ Compute a stable hash of immutable object
data
. The hash is not affected by Python’s hash randomization (seeobject.__hash__()
).Parameters: data – An immutable object of type bool
,int
,float
,complex
,str
,bytes
,tuple
,frozenset
, orEllipsis
orNone
, or the type itself, or an object with a__nutils_hash__
attribute.Returns: The hash of data
.Return type: 40 bytes
-
class
nutils.types.
Immutable
(*args, **kwargs)¶ Bases:
object
Base class for immutable types. This class adds equality tests, traditional hashing (
hash()
), nutils hashing (nutils_hash()
) and pickling, all based solely on the (positional) intialization arguments,args
for future reference. Keyword-only arguments are not supported. All arguments should be hashable bynutils_hash()
.Positional and keyword initialization arguments are canonicalized automatically (by
argument_canonicalizer()
).Examples
Consider the following class.
>>> class Plain(Immutable): ... def __init__(self, a, b): ... pass
Calling
Plain
with equivalent positional or keyword arguments produces equal instances:>>> Plain(1, 2) == Plain(a=1, b=2) True
Passing unhashable values to
Plain
will fail:>>> Plain([1, 2], [3, 4]) # doctest: +IGNORE_EXCEPTION_DETAIL Traceback (most recent call last): ... TypeError: unhashable type: 'list'
-
__weakref__
¶ list of weak references to the object (if defined)
-
-
class
nutils.types.
Singleton
(*args, **kwargs)¶ Bases:
nutils.types.Immutable
Subclass of
Immutable
that creates a single instance per unique set of initialization arguments.Examples
Consider the following class.
>>> class Plain(Singleton): ... def __init__(self, a, b): ... pass
Calling
Plain
with equivalent positional or keyword arguments produces one instance:>>> Plain(1, 2) is Plain(a=1, b=2) True
-
__eq__
¶ Return self==value.
-
-
class
nutils.types.
arraydata
(dtype, shape, bytes)¶ Bases:
nutils.types.Singleton
hashable array container.
The container can be used for fast equality checks and for dictionary keys. Data is copied at construction and canonicalized by casting it to the platform’s primary data representation (e.g. int64 i/o int32). It can be retrieved via
numpy.asarray()
. Additionally thearraydata
object provides direct access to the array’s shape, dtype and bytes.Example
>>> a = numpy.array([1,2,3]) >>> w = arraydata(a) >>> w == arraydata([1,2,4]) # NOTE: equality only if entire array matches False >>> numpy.asarray(w) array([1, 2, 3])
-
class
nutils.types.
frozendict
(base)¶ Bases:
collections.abc.Mapping
An immutable version of
dict
. Thefrozendict
is hashable and both the keys and values should be hashable as well.Examples
>>> d = frozendict({'spam': 0.0}) >>> d['spam'] 0.0 >>> d['spam'] = 1.0 Traceback (most recent call last): ... TypeError: 'frozendict' object does not support item assignment
-
__weakref__
¶ list of weak references to the object (if defined)
-
-
class
nutils.types.
frozenmultiset
(items)¶ Bases:
collections.abc.Container
An immutable multiset. A multiset is a generalization of a set: items may occur more than once. Two mutlisets are equal if they have the same set of items and the same item multiplicities.
A custom item constructor can be supplied via the notation
frozenmultiset[I]
, withI
the item constructor. This is shorthand forlambda items: frozenmultiset(map(I, items))
. The item constructor should be any callable that takes one argument.Examples
>>> a = frozenmultiset(['spam', 'bacon', 'spam']) >>> b = frozenmultiset(['sausage', 'spam'])
The
frozenmultiset
objects support+
,-
and&
operators:>>> a + b frozenmultiset(['spam', 'bacon', 'spam', 'sausage', 'spam']) >>> a - b frozenmultiset(['bacon', 'spam']) >>> a & b frozenmultiset(['spam'])
The order of the items is irrelevant:
>>> frozenmultiset(['spam', 'spam', 'eggs']) == frozenmultiset(['spam', 'eggs', 'spam']) True
The multiplicities, however, are not:
>>> frozenmultiset(['spam', 'spam', 'eggs']) == frozenmultiset(['spam', 'eggs']) False
-
__and__
(self, other)¶ Return a
frozenmultiset
with elements from the left and right hand sides with strict positive multiplicity, where the multiplicity is the minimum of multiplicitie of the left and right hand side.
-
__add__
(self, other)¶ Return a
frozenmultiset
with elements from the left and right hand sides with a multiplicity equal to the sum of the left and right hand sides.
-
__sub__
(self, other)¶ Return a
frozenmultiset
with elements from the left hand sides with a multiplicity equal to the difference of the multiplicity of the left and right hand sides, truncated to zero. Elements with multiplicity zero are omitted.
-
__weakref__
¶ list of weak references to the object (if defined)
-
-
nutils.types.
frozenarray
(arg, *, copy=True, dtype=None)¶ Create read-only Numpy array.
Parameters: - arg (
numpy.ndarray
or array_like) – Input data. - copy (
bool
) – If True (the default), do not modify the argument in place. No copy is ever forced if the argument is already immutable. - dtype (
numpy.dtype
or dtype_like, optional) – The desired data-type for the array.
Returns: Return type: - arg (
-
nutils.types.
lru_cache
(func)¶ Buffer-aware cache.
Returns values from a cache for previously seen arguments. Arguments must be hasheable objects or immutable Numpy arrays, the latter identified by the underlying buffer. Destruction of the buffer triggers a callback that removes the corresponding cache entry.
At present, any writeable array will silently disable caching. This bevaviour is transitional, with future versions requiring that all arrays be immutable.
Caution
When a decorated function returns an object that references its argument (for instance, by returning the argument itself), the cached value keeps an argument’s reference count from falling to zero, causing the object to remain in cache indefinitely. For this reason, care must be taken that the decorator is only applied to functions that return objects with no references to its arguments.
-
class
nutils.types.
attributes
(**args)¶ Bases:
object
Dictionary-like container with attributes instead of keys, instantiated using keyword arguments:
>>> A = attributes(foo=10, bar=True) >>> A attributes(bar=True, foo=10) >>> A.foo 10
-
__weakref__
¶ list of weak references to the object (if defined)
-
-
nutils.types.
hashable_function
(identifier)¶ Decorator that wraps the decorated function and adds a Nutils hash.
Return a decorator that wraps the decorated function and adds a Nutils hash based solely on the given
identifier
. The identifier can be anything that has a Nutils hash. The identifier should represent the behavior of the function and should be changed when the behavior of the function changes.If used on methods, this decorator behaves like
staticmethod()
.Examples
Make some function
func
hashable:>>> @hashable_function('func v1') ... def func(a, b): ... return a + b ...
The Nutils hash can be obtained by calling
nutils_hash
onfunc
:>>> nutils_hash(func).hex() 'b7fed72647f6a88dd3ce3808b2710eede7d7b5a5'
Note that the hash is based solely on the identifier passed to the decorator. If we create another function
other
with the same identifier asfunc
, then both have the same hash, despite returning different values.>>> @hashable_function('func v1') ... def other(a, b): ... return a * b ... >>> nutils_hash(other) == nutils_hash(func) True >>> func(1, 2) == other(1, 2) False
The decorator can also be applied on methods:
>>> class Spam: ... @hashable_function('Spam.eggs v1') ... def eggs(a, b): ... # NOTE: `self` is absent because `hashable_function` behaves like `staticmethod`. ... return a + b ...
The hash of
eggs
accessed via the class or an instance is the same:>>> spam = Spam() >>> nutils_hash(Spam.eggs).hex() 'dfdbb0ce20b617b17c3b854c23b2b9f7deb94cc6' >>> nutils_hash(spam.eggs).hex() 'dfdbb0ce20b617b17c3b854c23b2b9f7deb94cc6'