aboutsummaryrefslogtreecommitdiff
path: root/factory
diff options
context:
space:
mode:
authorRaphaël Barrois <raphael.barrois@polytechnique.org>2015-05-24 18:21:04 +0200
committerRaphaël Barrois <raphael.barrois@polytechnique.org>2015-05-24 18:21:04 +0200
commitebc89520d3f7589da35d4e7b78637fbe7d4d664a (patch)
tree99f2d3a171444ffcf2150b89bf2355a1f70036ff /factory
parent6f37f9be2d2e1bc75340068911db18b2bbcbe722 (diff)
downloadfactory-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.py11
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: