rez.utils.data_utils#

Utilities related to managing data types.

class rez.utils.data_utils.ModifyList#

Bases: object

List modifier, used in deep_update.

This can be used in configs to add to list-based settings, rather than overwriting them.

__init__(append=None, prepend=None)#
apply(v)#
class rez.utils.data_utils.DelayLoad#

Bases: object

Used in config to delay load a config value from anothe file.

Supported formats:

  • yaml (*.yaml, *.yml)

  • json (*.json)

__init__(filepath)#
get_value()#
rez.utils.data_utils.remove_nones(**kwargs)#

Return diict copy with nones removed.

rez.utils.data_utils.deep_update(dict1, dict2)#

Perform a deep merge of dict2 into dict1.

Note that dict2 and any nested dicts are unchanged.

Supports ModifyList instances.

rez.utils.data_utils.deep_del(data, fn)#

Create dict copy with removed items.

Recursively remove items where fn(value) is True.

Returns:

New dict with matching items removed.

Return type:

dict

rez.utils.data_utils.get_dict_diff(d1, d2)#

Get added/removed/changed keys between two dicts.

Each key in the return value is a list, which is the namespaced key that was affected.

Returns:

3-tuple: - list of added keys; - list of removed key; - list of changed keys.

Return type:

tuple

rez.utils.data_utils.get_dict_diff_str(d1, d2, title)#

Returns same as get_dict_diff, but as a readable string.

class rez.utils.data_utils.cached_property#

Bases: object

Simple property caching descriptor.

Example

>>> class Foo(object):
>>>     @cached_property
>>>     def bah(self):
>>>         print('bah')
>>>         return 1
>>>
>>> f = Foo()
>>> f.bah
bah
1
>>> f.bah
1
__init__(func, name=None)#
classmethod uncache(instance, name)#
class rez.utils.data_utils.cached_class_property#

Bases: object

Simple class property caching descriptor.

Example

>>> class Foo(object):
>>>     @cached_class_property
>>>     def bah(cls):
>>>         print('bah')
>>>         return 1
>>>
>>> Foo.bah
bah
1
>>> Foo.bah
1
__init__(func, name=None)#
class rez.utils.data_utils.LazySingleton#

Bases: object

A threadsafe singleton that initialises when first referenced.

__init__(instance_class, *nargs, **kwargs)#
class rez.utils.data_utils.AttrDictWrapper#

Bases: MutableMapping

Wrap a custom dictionary with attribute-based lookup:

>>> d = {'one': 1}
>>> dd = AttrDictWrapper(d)
>>> assert dd.one == 1
>>> ddd = dd.copy()
>>> ddd.one = 2
>>> assert ddd.one == 2
>>> assert dd.one == 1
>>> assert d['one'] == 1
__init__(data=None)#
copy()#
clear() None.  Remove all items from D.#
get(k[, d]) D[k] if k in D, else d.  d defaults to None.#
items() a set-like object providing a view on D's items#
keys() a set-like object providing a view on D's keys#
pop(k[, d]) v, remove specified key and return the corresponding value.#

If key is not found, d is returned if given, otherwise KeyError is raised.

popitem() (k, v), remove and return some (key, value) pair#

as a 2-tuple; but raise KeyError if D is empty.

setdefault(k[, d]) D.get(k,d), also set D[k]=d if k not in D#
update([E, ]**F) None.  Update D from mapping/iterable E and F.#

If E present and has a .keys() method, does: for k in E: D[k] = E[k] If E present and lacks .keys() method, does: for (k, v) in E: D[k] = v In either case, this is followed by: for k, v in F.items(): D[k] = v

values() an object providing a view on D's values#
class rez.utils.data_utils.RO_AttrDictWrapper#

Bases: AttrDictWrapper

Read-only version of AttrDictWrapper.

__init__(data=None)#
clear() None.  Remove all items from D.#
copy()#
get(k[, d]) D[k] if k in D, else d.  d defaults to None.#
items() a set-like object providing a view on D's items#
keys() a set-like object providing a view on D's keys#
pop(k[, d]) v, remove specified key and return the corresponding value.#

If key is not found, d is returned if given, otherwise KeyError is raised.

popitem() (k, v), remove and return some (key, value) pair#

as a 2-tuple; but raise KeyError if D is empty.

setdefault(k[, d]) D.get(k,d), also set D[k]=d if k not in D#
update([E, ]**F) None.  Update D from mapping/iterable E and F.#

If E present and has a .keys() method, does: for k in E: D[k] = E[k] If E present and lacks .keys() method, does: for (k, v) in E: D[k] = v In either case, this is followed by: for k, v in F.items(): D[k] = v

values() an object providing a view on D's values#
rez.utils.data_utils.convert_dicts(d, to_class=<class 'rez.utils.data_utils.AttrDictWrapper'>, from_class=<class 'dict'>)#

Recursively convert dict and UserDict types.

Note that d is unchanged.

Parameters:
  • to_class (type) – Dict-like type to convert values to, usually UserDict subclass, or dict.

  • from_class (type) – Dict-like type to convert values from. If a tuple, multiple types are converted.

Returns:

Converted data as to_class instance.

rez.utils.data_utils.get_object_completions(instance, prefix, types=None, instance_types=None)#

Get completion strings based on an object’s attributes/keys.

Completion also works on dynamic attributes (eg implemented via __getattr__) if they are iterable.

Parameters:
  • instance (object) – Object to introspect.

  • prefix (str) – Prefix to match, can be dot-separated to access nested attributes.

  • types (tuple) – Attribute types to match, any if None.

  • instance_types (tuple) – Class types to recurse into when a dotted prefix is given, any if None.

Returns:

List of strings.

rez.utils.data_utils.convert_json_safe(value)#

Convert data to JSON safe values.

Anything not representable (eg python objects) will be stringified.

class rez.utils.data_utils.AttributeForwardMeta#

Bases: type

Metaclass for forwarding attributes of class member wrapped onto the parent class.

If the parent class already contains an attribute of the same name, forwarding is skipped for that attribute. If the wrapped object does not contain an attribute, the forwarded value will be None.

If the parent class contains method ‘_wrap_forwarded’, then forwarded values are passed to this function, and the return value becomes the attribute value.

The class must contain: - keys (list of str): The attributes to be forwarded.

Example

>>> class Foo(object):
>>>     def __init__(self):
>>>         self.a = "a_from_foo"
>>>         self.b = "b_from_foo"
>>>
>>> class Bah(object, metaclass=AttributeForwardMeta):
>>>     keys = ["a", "b", "c"]
>>>
>>>     @property
>>>     def a(self):
>>>         return "a_from_bah"
>>>
>>>     def __init__(self, child):
>>>         self.wrapped = child
>>>
>>> x = Foo()
>>> y = Bah(x)
>>> print(y.a)
a_from_bah
>>> print(y.b)
b_from_foo
>>> print(y.c)
None
static __new__(cls, name, parents, members)#
__init__(*args, **kwargs)#
mro()#

Return a type’s method resolution order.

class rez.utils.data_utils.LazyAttributeMeta#

Bases: type

Metaclass for adding properties to a class for accessing top-level keys in its _data dictionary, and validating them on first reference.

Property names are derived from the keys of the class’s schema object. If a schema key is optional, then the class property will evaluate to None if the key is not present in _data.

The attribute getters created by this metaclass will perform lazy data validation, OR, if the class has a _validate_key method, will call this method, passing the key, key value and key schema.

This metaclass creates the following attributes:
  • for each key in cls.schema, creates an attribute of the same name, unless that attribute already exists;

  • for each key in cls.schema, if the attribute already exists on cls, then creates an attribute with the same name but prefixed with ‘_’;

  • ‘validate_data’ (function): A method that validates all keys;

  • ‘validated_data’ (function): A method that returns the entire validated dict, or None if there is no schema;

  • ‘_validate_key_impl’ (function): Validation function used when ‘_validate_key’ is not provided, it is here so you can use it in your own ‘_validate_key’ function;

  • ‘_schema_keys’ (frozenset): Keys in the schema.

static __new__(cls, name, parents, members)#
__init__(*args, **kwargs)#
mro()#

Return a type’s method resolution order.