rez.utils.scope

class rez.utils.scope.RecursiveAttribute(data=None, read_only=False)[source]

Bases: collections.UserDict, rez.utils.formatting.StringFormatMixin

An object that can have new attributes added recursively:

>>> a = RecursiveAttribute()
>>> a.foo.bah = 5
>>> a.foo['eek'] = 'hey'
>>> a.fee = 1

>>> print(a.to_dict())
{'foo': {'bah': 5, 'eek': 'hey'}, 'fee': 1}

A recursive attribute can also be created from a dict, and made read-only:

>>> d = {'fee': {'fi': {'fo': 'fum'}}, 'ho': 'hum'}
>>> a = RecursiveAttribute(d, read_only=True)
>>> print(str(a))
{'fee': {'fi': {'fo': 'fum'}}, 'ho': 'hum'}
>>> print(a.ho)
hum
>>> a.new = True
AttributeError: 'RecursiveAttribute' object has no attribute 'new'
copy()[source]
format_expand = <StringFormatType.unchanged: 3>
to_dict()[source]

Get an equivalent dict representation.

update(data)[source]

Dict-like update operation.

class rez.utils.scope.ScopeContext[source]

Bases: object

A context manager for creating nested dictionaries:

>>> scope = ScopeContext()
>>>
>>> with scope("animal"):
>>>     count = 2
>>>     with scope("cat"):
>>>         friendly = False
>>>     with scope("dog") as d:
>>>         friendly = True
>>>         d.num_legs = 4
>>>         d.breed.sub_breed = 'yorkshire terrier'
>>> with scope("animal"):
>>>     count = 3
>>>     with scope("cat"):
>>>         num_legs = 4
>>>     with scope("ostrich"):
>>>         friendly = False
>>>         num_legs = 2

The dictionaries can then be retrieved:

>>> print(pprint.pformat(scope.to_dict()))
{'animal': {'count': 3,
            'cat': {'friendly': False,
                    'num_legs': 4},
            'dog': {'breed': {'sub_breed': 'yorkshire terrier'},
                    'friendly': True,
                    'num_legs': 4},
            'ostrich': {'friendly': False,
                        'num_legs': 2}}}

Note that scopes and recursive attributes can be referenced multiple times, and the assigned properties will be merged. If the same property is set multiple times, it will be overwritten.

to_dict()[source]

Get an equivalent dict representation.

rez.utils.scope.scoped_format(txt, **objects)[source]

Format a string with respect to a set of objects’ attributes.

Example

>>> Class Foo(object):
>>>     def __init__(self):
>>>         self.name = "Dave"
>>> print(scoped_format("hello {foo.name}", foo=Foo()))
hello Dave
Parameters
  • objects (dict) – Dict of objects to format with. If a value is a dict, its values, and any further neted dicts, will also format with dot notation.

  • pretty (bool) – See ObjectStringFormatter.

  • expand (bool) – See ObjectStringFormatter.

rez.utils.scope.scoped_formatter(**objects)[source]

Format a string with respect to a set of objects’ attributes.

Use this rather than scoped_format when you need to reuse the formatter.