I came up with this in the end:
class DeferredAll(Deferred):
def __init__(self, deferreds):
super(DeferredAll, self).__init__()
assert deferreds, 'Need at least one deferred for DeferredAll'
self.deferreds = deferreds
self._results = []
self.finished_count = 0
for d in self.deferreds:
d.addCallbacks(self._success, self._fail)
def _success(self, result):
self.finished_count += 1
# print('_success {}/{} {}'.format(self.finished_count, len(self.deferreds), result))
self._results.append(result)
if self.finished_count == len(self.deferreds):
self.callback(self._results)
def _fail(self, *args, **kwargs):
# print('_fail {} {}'.format(str(args), str(kwargs)))
if not self.called: # this property is True if callback()/errback() has already been called
self.failed = True
self.errback()