rez.utils.data_utils

Utilities related to managing data types.

class rez.utils.data_utils.AttrDictWrapper(data=None)[source]

Bases: collections.abc.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
copy()[source]
class rez.utils.data_utils.AttributeForwardMeta(name, parents, members)[source]

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

>>> import six
>>>
>>> class Foo(object):
>>>     def __init__(self):
>>>         self.a = "a_from_foo"
>>>         self.b = "b_from_foo"
>>>
>>> class Bah(six.with_metaclass(AttributeForwardMeta, object)):
>>>     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
class rez.utils.data_utils.DelayLoad(filepath)[source]

Bases: object

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

Supported formats:

  • yaml (*.yaml, *.yml)

  • json (*.json)

get_value()[source]
class rez.utils.data_utils.LazyAttributeMeta(name, parents, members)[source]

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.

class rez.utils.data_utils.LazySingleton(instance_class, *nargs, **kwargs)[source]

Bases: object

A threadsafe singleton that initialises when first referenced.

class rez.utils.data_utils.ModifyList(append=None, prepend=None)[source]

Bases: object

List modifier, used in deep_update.

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

apply(v)[source]
class rez.utils.data_utils.RO_AttrDictWrapper(data=None)[source]

Bases: rez.utils.data_utils.AttrDictWrapper

Read-only version of AttrDictWrapper.

class rez.utils.data_utils.cached_class_property(func, name=None)[source]

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
class rez.utils.data_utils.cached_property(func, name=None)[source]

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
classmethod uncache(instance, name)[source]
rez.utils.data_utils.convert_dicts(d, to_class=<class 'rez.utils.data_utils.AttrDictWrapper'>, from_class=<class 'dict'>)[source]

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.convert_json_safe(value)[source]

Convert data to JSON safe values.

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

rez.utils.data_utils.deep_del(data, fn)[source]

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.deep_update(dict1, dict2)[source]

Perform a deep merge of dict2 into dict1.

Note that dict2 and any nested dicts are unchanged.

Supports ModifyList instances.

rez.utils.data_utils.get_dict_diff(d1, d2)[source]

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

  • list of added keys;

  • list of removed key;

  • list of changed keys.

Return type

3-tuple

rez.utils.data_utils.get_dict_diff_str(d1, d2, title)[source]

Returns same as get_dict_diff, but as a readable string.

rez.utils.data_utils.get_object_completions(instance, prefix, types=None, instance_types=None)[source]

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.remove_nones(**kwargs)[source]

Return diict copy with nones removed.