summaryrefslogtreecommitdiff
path: root/factory/containers.py
diff options
context:
space:
mode:
authorThomas Goirand <thomas@goirand.fr>2013-05-12 05:32:34 +0000
committerThomas Goirand <thomas@goirand.fr>2013-05-12 05:32:34 +0000
commit28991f9514e3cd78a528bbbe956d9b4536c416e0 (patch)
treea3871392d2382f60490824d79058f8a71ae1c34e /factory/containers.py
parent57fa2e21aed37c1af2a87f36a998046b73092a21 (diff)
parent876845102c4a217496d0f6435bfe1e3726d31fe4 (diff)
downloadfactory-boy-28991f9514e3cd78a528bbbe956d9b4536c416e0.tar
factory-boy-28991f9514e3cd78a528bbbe956d9b4536c416e0.tar.gz
Merge tag '2.0.2' into debian/unstable
Release of factory_boy 2.0.2 Conflicts: docs/changelog.rst docs/index.rst docs/subfactory.rst tests/cyclic/bar.py tests/cyclic/foo.py
Diffstat (limited to 'factory/containers.py')
-rw-r--r--factory/containers.py81
1 files changed, 38 insertions, 43 deletions
diff --git a/factory/containers.py b/factory/containers.py
index 946fbd3..c8be431 100644
--- a/factory/containers.py
+++ b/factory/containers.py
@@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2010 Mark Sandstrom
-# Copyright (c) 2011 Raphaël Barrois
+# Copyright (c) 2011-2013 Raphaël Barrois
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
@@ -21,8 +21,8 @@
# THE SOFTWARE.
-from factory import declarations
-from factory import utils
+from . import declarations
+from . import utils
class CyclicDefinitionError(Exception):
@@ -62,7 +62,7 @@ class LazyStub(object):
def __str__(self):
return '<LazyStub for %s with %s>' % (
- self.__target_class.__name__, self.__attrs.keys())
+ self.__target_class.__name__, list(self.__attrs.keys()))
def __fill__(self):
"""Fill this LazyStub, computing values of all defined attributes.
@@ -136,7 +136,7 @@ class DeclarationDict(dict):
Returns a dict containing all remaining elements.
"""
remaining = {}
- for k, v in d.iteritems():
+ for k, v in d.items():
if self.is_declaration(k, v):
self[k] = v
else:
@@ -172,30 +172,6 @@ class LazyValue(object):
raise NotImplementedError("This is an abstract method.")
-class SubFactoryWrapper(LazyValue):
- """Lazy wrapper around a SubFactory.
-
- Attributes:
- subfactory (declarations.SubFactory): the SubFactory being wrapped
- subfields (DeclarationDict): Default values to override when evaluating
- the SubFactory
- create (bool): whether to 'create' or 'build' the SubFactory.
- """
-
- def __init__(self, subfactory, subfields, create, *args, **kwargs):
- super(SubFactoryWrapper, self).__init__(*args, **kwargs)
- self.subfactory = subfactory
- self.subfields = subfields
- self.create = create
-
- def evaluate(self, obj, containers=()):
- expanded_containers = (obj,)
- if containers:
- expanded_containers += tuple(containers)
- return self.subfactory.evaluate(self.create, self.subfields,
- expanded_containers)
-
-
class OrderedDeclarationWrapper(LazyValue):
"""Lazy wrapper around an OrderedDeclaration.
@@ -206,10 +182,12 @@ class OrderedDeclarationWrapper(LazyValue):
declaration
"""
- def __init__(self, declaration, sequence, *args, **kwargs):
- super(OrderedDeclarationWrapper, self).__init__(*args, **kwargs)
+ def __init__(self, declaration, sequence, create, extra=None, **kwargs):
+ super(OrderedDeclarationWrapper, self).__init__(**kwargs)
self.declaration = declaration
self.sequence = sequence
+ self.create = create
+ self.extra = extra
def evaluate(self, obj, containers=()):
"""Lazily evaluate the attached OrderedDeclaration.
@@ -219,7 +197,14 @@ class OrderedDeclarationWrapper(LazyValue):
containers (object list): the chain of containers of the object
being built, its immediate holder being first.
"""
- return self.declaration.evaluate(self.sequence, obj, containers)
+ return self.declaration.evaluate(self.sequence, obj,
+ create=self.create,
+ extra=self.extra,
+ containers=containers,
+ )
+
+ def __repr__(self):
+ return '<%s for %r>' % (self.__class__.__name__, self.declaration)
class AttributeBuilder(object):
@@ -240,33 +225,43 @@ class AttributeBuilder(object):
extra = {}
self.factory = factory
- self._containers = extra.pop('__containers', None)
+ self._containers = extra.pop('__containers', ())
self._attrs = factory.declarations(extra)
- attrs_with_subfields = [k for k, v in self._attrs.items() if self.has_subfields(v)]
+ attrs_with_subfields = [
+ k for k, v in self._attrs.items()
+ if self.has_subfields(v)]
- self._subfields = utils.multi_extract_dict(attrs_with_subfields, self._attrs)
+ self._subfields = utils.multi_extract_dict(
+ attrs_with_subfields, self._attrs)
def has_subfields(self, value):
- return isinstance(value, declarations.SubFactory)
+ return isinstance(value, declarations.ParameteredAttribute)
- def build(self, create):
+ def build(self, create, force_sequence=None):
"""Build a dictionary of attributes.
Args:
create (bool): whether to 'build' or 'create' the subfactories.
+ force_sequence (int or None): if set to an int, use this value for
+ the sequence counter; don't advance the related counter.
"""
# Setup factory sequence.
- self.factory.sequence = self.factory._generate_next_sequence()
+ if force_sequence is None:
+ sequence = self.factory._generate_next_sequence()
+ else:
+ sequence = force_sequence
# Parse attribute declarations, wrapping SubFactory and
# OrderedDeclaration.
wrapped_attrs = {}
- for k, v in self._attrs.iteritems():
- if isinstance(v, declarations.SubFactory):
- v = SubFactoryWrapper(v, self._subfields.get(k, {}), create)
- elif isinstance(v, declarations.OrderedDeclaration):
- v = OrderedDeclarationWrapper(v, self.factory.sequence)
+ for k, v in self._attrs.items():
+ if isinstance(v, declarations.OrderedDeclaration):
+ v = OrderedDeclarationWrapper(v,
+ sequence=sequence,
+ create=create,
+ extra=self._subfields.get(k, {}),
+ )
wrapped_attrs[k] = v
stub = LazyStub(wrapped_attrs, containers=self._containers,