I'm not sure if this is async safe, or if everything happens up front at startup anyway:
|
class ObjectAggregator: |
|
""" |
|
Provides a single object interface that combines many smaller objects. |
|
|
|
Attribute access on the aggregate object acts on the first sub-object |
|
that has that attribute. |
|
""" |
|
|
|
def __init__(self, *objects): |
|
self.__dict__['_objects'] = objects |
|
|
|
def _object_with_attr(self, name): |
|
""" |
|
Returns the first object that has the attribute `name` |
|
|
|
:param name: the attribute to filter by |
|
:type name: `str` |
|
:raises AttributeError: when no object has the named attribute |
|
""" |
|
for obj in self._objects: |
|
if hasattr(obj, name): |
|
return obj |
|
|
|
raise AttributeError(f"No object has attribute {name!r}") |
|
|
|
def __getattr__(self, name): |
|
return getattr(self._object_with_attr(name), name) |
|
|
|
def __setattr__(self, name, value): |
|
setattr(self._object_with_attr(name), name, value) |
|
|
|
def __delattr__(self, name): |
|
delattr(self._object_with_attr(name), name) |
|
|
|
|
|
# Cache of Mixologist generated classes |
|
_CLASS_CACHE = {} |
|
_CLASS_CACHE_LOCK = threading.RLock() |
We need to make it async-safe for ASGI style deployments.
Open question: Is this used anywhere at all? It looks like it might no longer be called anywhere other than its own tests.
I'm not sure if this is async safe, or if everything happens up front at startup anyway:
XBlock/xblock/runtime.py
Lines 1189 to 1226 in 77bfe4d
We need to make it async-safe for ASGI style deployments.
Open question: Is this used anywhere at all? It looks like it might no longer be called anywhere other than its own tests.