diff options
author | Raphaël Barrois <raphael.barrois@polytechnique.org> | 2015-05-24 18:21:04 +0200 |
---|---|---|
committer | Raphaël Barrois <raphael.barrois@polytechnique.org> | 2015-05-24 18:21:04 +0200 |
commit | ebc89520d3f7589da35d4e7b78637fbe7d4d664a (patch) | |
tree | 99f2d3a171444ffcf2150b89bf2355a1f70036ff /factory | |
parent | 6f37f9be2d2e1bc75340068911db18b2bbcbe722 (diff) | |
download | factory-boy-ebc89520d3f7589da35d4e7b78637fbe7d4d664a.tar factory-boy-ebc89520d3f7589da35d4e7b78637fbe7d4d664a.tar.gz |
Add lazy loading to factory.Iterator.
factory.Iterator no longers begins iteration of its argument
on declaration, since this behavior may trigger database query
when that argument is, for instance, a Django queryset.
The ``factory.Iterator``'s argument will only be called when
the containing ``Factory`` is first evaluated; this means that
factories using ``factory.Iterator(models.MyThingy.objects.all())``
will no longer call the database at import time.
Diffstat (limited to 'factory')
-rw-r--r-- | factory/declarations.py | 11 |
1 files changed, 9 insertions, 2 deletions
diff --git a/factory/declarations.py b/factory/declarations.py index 8f2314a..f0dbfe5 100644 --- a/factory/declarations.py +++ b/factory/declarations.py @@ -160,12 +160,19 @@ class Iterator(OrderedDeclaration): def __init__(self, iterator, cycle=True, getter=None): super(Iterator, self).__init__() self.getter = getter + self.iterator = None if cycle: - iterator = itertools.cycle(iterator) - self.iterator = utils.ResetableIterator(iterator) + self.iterator_builder = lambda: utils.ResetableIterator(itertools.cycle(iterator)) + else: + self.iterator_builder = lambda: utils.ResetableIterator(iterator) def evaluate(self, sequence, obj, create, extra=None, containers=()): + # Begin unrolling as late as possible. + # This helps with ResetableIterator(MyModel.objects.all()) + if self.iterator is None: + self.iterator = self.iterator_builder() + logger.debug("Iterator: Fetching next value from %r", self.iterator) value = next(iter(self.iterator)) if self.getter is None: |