utils.objects

Object related utilities, including introspection, etc.

Module Contents

Classes

Bunch(self,**kwargs) Object that enables you to modify attributes.
FallbackContext(self,provided,fallback,*fb_args,**fb_kwargs) Context workaround.
getitem_property(self,keypath,doc=None) Attribute -> dict key descriptor.

Functions

mro_lookup(cls,attr,stop=set,monkey_patched=list) Return the first node by MRO order that defines an attribute.
class Bunch(**kwargs)

Object that enables you to modify attributes.

__init__(**kwargs)
mro_lookup(cls, attr, stop=set, monkey_patched=list)

Return the first node by MRO order that defines an attribute.

Arguments:

cls (Any): Child class to traverse. attr (str): Name of attribute to find. stop (Set[Any]): A set of types that if reached will stop

the search.
monkey_patched (Sequence): Use one of the stop classes
if the attributes module origin isn’t in this list. Used to detect monkey patched attributes.
Returns:
Any: The attribute value, or None if not found.
class FallbackContext(provided, fallback, *fb_args, **fb_kwargs)

Context workaround.

The built-in @contextmanager utility does not work well when wrapping other contexts, as the traceback is wrong when the wrapped context raises.

This solves this problem and can be used instead of @contextmanager in this example:

@contextmanager
def connection_or_default_connection(connection=None):
    if connection:
        # user already has a connection, shouldn't close
        # after use
        yield connection
    else:
        # must've new connection, and also close the connection
        # after the block returns
        with create_new_connection() as connection:
            yield connection

This wrapper can be used instead for the above like this:

def connection_or_default_connection(connection=None):
    return FallbackContext(connection, create_new_connection)
__init__(provided, fallback, *fb_args, **fb_kwargs)
__enter__()
__exit__(*exc_info)
class getitem_property(keypath, doc=None)

Attribute -> dict key descriptor.

The target object must support __getitem__, and optionally __setitem__.

Example:
>>> from collections import defaultdict
>>> class Me(dict):
...     deep = defaultdict(dict)
...
...     foo = _getitem_property('foo')
...     deep_thing = _getitem_property('deep.thing')
>>> me = Me()
>>> me.foo
None
>>> me.foo = 10
>>> me.foo
10
>>> me['foo']
10
>>> me.deep_thing = 42
>>> me.deep_thing
42
>>> me.deep
defaultdict(<type 'dict'>, {'thing': 42})
__init__(keypath, doc=None)
_path(obj)
__get__(obj, type=None)
__set__(obj, value)