Reference
*********

This section offers an in-depth description of factory_boy features.

For internals and customization points, please refer to the Internals
section.


The "Factory" class
===================


Meta options
------------

class factory.FactoryOptions

   New in version 2.4.0.

   A "Factory"’s behaviour can be tuned through a few settings.

   For convenience, they are declared in a single "class Meta"
   attribute:

      class MyFactory(factory.Factory):
          class Meta:
              model = MyObject
              abstract = False

   model

      This optional attribute describes the class of objects to
      generate.

      If unset, it will be inherited from parent "Factory" subclasses.

      New in version 2.4.0.

   get_model_class()

      Returns the actual model class ("FactoryOptions.model" might be
      the path to the class; this function will always return a proper
      class).

   abstract

      This attribute indicates that the "Factory" subclass should not
      be used to generate objects, but instead provides some extra
      defaults.

      It will be automatically set to "True" if neither the "Factory"
      subclass nor its parents define the "model" attribute.

      Warning: This flag is reset to "False" when a "Factory"
        subclasses another one if a "model" is set.

      New in version 2.4.0.

   inline_args

      Some factories require non-keyword arguments to their
      "__init__()". They should be listed, in order, in the
      "inline_args" attribute:

         class UserFactory(factory.Factory):
             class Meta:
                 model = User
                 inline_args = ('login', 'email')

             login = 'john'
             email = factory.LazyAttribute(lambda o: '%s@example.com' % o.login)
             firstname = "John"

         >>> UserFactory()
         <User: john>
         >>> User('john', 'john@example.com', firstname="John")  # actual call

      New in version 2.4.0.

   exclude

      While writing a "Factory" for some object, it may be useful to
      have general fields helping defining others, but that should not
      be passed to the model class; for instance, a field named ‘now’
      that would hold a reference time used by other objects.

      Factory fields whose name are listed in "exclude" will be
      removed from the set of args/kwargs passed to the underlying
      class; they can be any valid factory_boy declaration:

         class OrderFactory(factory.Factory):
             class Meta:
                 model = Order
                 exclude = ('now',)

             now = factory.LazyFunction(datetime.datetime.utcnow)
             started_at = factory.LazyAttribute(lambda o: o.now - datetime.timedelta(hours=1))
             paid_at = factory.LazyAttribute(lambda o: o.now - datetime.timedelta(minutes=50))

         >>> OrderFactory()    # The value of 'now' isn't passed to Order()
         <Order: started 2013-04-01 12:00:00, paid 2013-04-01 12:10:00>

         >>> # An alternate value may be passed for 'now'
         >>> OrderFactory(now=datetime.datetime(2013, 4, 1, 10))
         <Order: started 2013-04-01 09:00:00, paid 2013-04-01 09:10:00>

      New in version 2.4.0.

   rename

      Sometimes, a model expects a field with a name already used by
      one of "Factory"’s methods.

      In this case, the "rename" attributes allows to define renaming
      rules: the keys of the "rename" dict are those used in the
      "Factory" declarations, and their values the new name:

         class ImageFactory(factory.Factory):
             # The model expects "attributes"
             form_attributes = ['thumbnail', 'black-and-white']

             class Meta:
                 model = Image
                 rename = {'form_attributes': 'attributes'}

   strategy

      Use this attribute to change the strategy used by a "Factory".
      The default is "CREATE_STRATEGY".


Attributes and methods
----------------------

class factory.Factory

   **Class-level attributes:**

   Meta

   _meta

      New in version 2.4.0.

      The "FactoryOptions" instance attached to a "Factory" class is
      available as a "_meta" attribute.

   Params

      New in version 2.7.0.

      The extra parameters attached to a "Factory" are declared
      through a "Params" class. See the “Parameters” section for more
      information.

   _options_class

      New in version 2.4.0.

      If a "Factory" subclass needs to define additional, extra
      options, it has to provide a custom "FactoryOptions" subclass.

      A pointer to that custom class should be provided as
      "_options_class" so that the "Factory"-building metaclass can
      use it instead.

   **Base functions:**

   The "Factory" class provides a few methods for getting objects; the
   usual way being to simply call the class:

      >>> UserFactory()               # Calls UserFactory.create()
      >>> UserFactory(login='john')   # Calls UserFactory.create(login='john')

   Under the hood, factory_boy will define the "Factory" "__new__()"
   method to call the default strategy of the "Factory".

   A specific strategy for getting instance can be selected by calling
   the adequate method:

   classmethod build(cls, **kwargs)

      Provides a new object, using the ‘build’ strategy.

   classmethod build_batch(cls, size, **kwargs)

      Provides a list of "size" instances from the "Factory", through
      the ‘build’ strategy.

   classmethod create(cls, **kwargs)

      Provides a new object, using the ‘create’ strategy.

   classmethod create_batch(cls, size, **kwargs)

      Provides a list of "size" instances from the "Factory", through
      the ‘create’ strategy.

   classmethod stub(cls, **kwargs)

      Provides a new stub

   classmethod stub_batch(cls, size, **kwargs)

      Provides a list of "size" stubs from the "Factory".

   classmethod generate(cls, strategy, **kwargs)

      Provide a new instance, with the provided "strategy".

   classmethod generate_batch(cls, strategy, size, **kwargs)

      Provides a list of "size" instances using the specified
      strategy.

   classmethod simple_generate(cls, create, **kwargs)

      Provide a new instance, either built ("create=False") or created
      ("create=True").

   classmethod simple_generate_batch(cls, create, size, **kwargs)

      Provides a list of "size" instances, either built or created
      according to "create".

   **Extension points:**

   A "Factory" subclass may override a couple of class methods to
   adapt its behaviour:

   classmethod _adjust_kwargs(cls, **kwargs)

      The "_adjust_kwargs()" extension point allows for late fields
      tuning.

      It is called once keyword arguments have been resolved and post-
      generation items removed, but before the "inline_args"
      extraction phase.

         class UserFactory(factory.Factory):

             @classmethod
             def _adjust_kwargs(cls, **kwargs):
                 # Ensure ``lastname`` is upper-case.
                 kwargs['lastname'] = kwargs['lastname'].upper()
                 return kwargs

   classmethod _setup_next_sequence(cls)

      This method will compute the first value to use for the sequence
      counter of this factory.

      It is called when the first instance of the factory (or one of
      its subclasses) is created.

      Subclasses may fetch the next free ID from the database, for
      instance.

   classmethod _build(cls, model_class, *args, **kwargs)

      This class method is called whenever a new instance needs to be
      built. It receives the model class (provided to "model"), and
      the positional and keyword arguments to use for the class once
      all has been computed.

      Subclasses may override this for custom APIs.

   classmethod _create(cls, model_class, *args, **kwargs)

      The "_create()" method is called whenever an instance needs to
      be created. It receives the same arguments as "_build()".

      Subclasses may override this for specific persistence backends:

         class BaseBackendFactory(factory.Factory):
             class Meta:
                 abstract = True  # Optional

             def _create(cls, model_class, *args, **kwargs):
                 obj = model_class(*args, **kwargs)
                 obj.save()
                 return obj

   classmethod _after_postgeneration(cls, obj, create, results=None)

      Parameters:
         * **obj** (*object*) – The object just generated

         * **create** (*bool*) – Whether the object was ‘built’ or
           ‘created’

         * **results** (*dict*) – Map of post-generation declaration
           name to call result

      The "_after_postgeneration()" is called once post-generation
      declarations have been handled.

      Its arguments allow to handle specifically some post-generation
      return values, for instance.

   **Advanced functions:**

   classmethod reset_sequence(cls, value=None, force=False)

      Parameters:
         * **value** (*int*) – The value to reset the sequence to

         * **force** (*bool*) – Whether to force-reset the sequence

      Allows to reset the sequence counter for a "Factory". The new
      value can be passed in as the "value" argument:

         >>> SomeFactory.reset_sequence(4)
         >>> SomeFactory._next_sequence
         4

      Since subclasses of a non-"abstract" "Factory" share the same
      sequence counter, special care needs to be taken when resetting
      the counter of such a subclass.

      By default, "reset_sequence()" will raise a "ValueError" when
      called on a subclassed "Factory" subclass. This can be avoided
      by passing in the "force=True" flag:

         >>> InheritedFactory.reset_sequence()
         Traceback (most recent call last):
           File "factory_boy/tests/test_base.py", line 179, in test_reset_sequence_subclass_parent
             SubTestObjectFactory.reset_sequence()
           File "factory_boy/factory/base.py", line 250, in reset_sequence
             "Cannot reset the sequence of a factory subclass. "
         ValueError: Cannot reset the sequence of a factory subclass. Please call reset_sequence() on the root factory, or call reset_sequence(forward=True).

         >>> InheritedFactory.reset_sequence(force=True)
         >>>

      This is equivalent to calling "reset_sequence()" on the base
      factory in the chain.


Parameters
----------

New in version 2.7.0.

Some models have many fields that can be summarized by a few
parameters; for instance, a train with many cars — each complete with
serial number, manufacturer, …; or an order that can be
pending/shipped/received, with a few fields to describe each step.

When building instances of such models, a couple of parameters can be
enough to determine all other fields; this is handled by the "Params"
section of a "Factory" declaration.


Simple parameters
~~~~~~~~~~~~~~~~~

Some factories only need little data:

   class ConferenceFactory(factory.Factory):
       class Meta:
           model = Conference

       class Params:
           duration = 'short' # Or 'long'

       start_date = factory.fuzzy.FuzzyDate()
       end_date = factory.LazyAttribute(
           lambda o: o.start_date + datetime.timedelta(days=2 if o.duration == 'short' else 7)
       )
       sprints_start = factory.LazyAttribute(
           lambda o: o.end_date - datetime.timedelta(days=0 if o.duration == 'short' else 1)
       )

   >>> Conference(duration='short')
   <Conference: DUTH 2015 (2015-11-05 - 2015-11-08, sprints 2015-11-08)>
   >>> Conference(duration='long')
   <Conference: DjangoConEU 2016 (2016-03-30 - 2016-04-03, sprints 2016-04-02)>

Any simple parameter provided to the "Factory.Params" section is
available to the whole factory, but not passed to the final class
(similar to the "exclude" behavior).


Traits
~~~~~~

class factory.Trait(**kwargs)

   New in version 2.7.0.

   A trait’s parameters are the fields it should alter when enabled.

For more complex situations, it is helpful to override a few fields at
once:

   class OrderFactory(factory.Factory):
       class Meta:
           model = Order

       state = 'pending'
       shipped_on = None
       shipped_by = None

       class Params:
           shipped = factory.Trait(
               state='shipped',
               shipped_on=datetime.date.today(),
               shipped_by=factory.SubFactory(EmployeeFactory),
           )

Such a "Trait" is activated or disabled by a single boolean field:

   >>> OrderFactory()
   <Order: pending>
   Order(state='pending')
   >>> OrderFactory(shipped=True)
   <Order: shipped by John Doe on 2016-04-02>

A "Trait" can be enabled/disabled by a "Factory" subclass:

   class ShippedOrderFactory(OrderFactory):
       shipped = True

Values set in a "Trait" can be overridden by call-time values:

   >>> OrderFactory(shipped=True, shipped_on=last_year)
   <Order: shipped by John Doe on 2015-04-20>

"Traits" can be chained:

   class OrderFactory(factory.Factory):
       class Meta:
           model = Order

       # Can be pending/shipping/received
       state = 'pending'
       shipped_on = None
       shipped_by = None
       received_on = None
       received_by = None

       class Params:
           shipped = factory.Trait(
               state='shipped',
               shipped_on=datetime.date.today,
               shipped_by=factory.SubFactory(EmployeeFactory),
           )
           received = factory.Trait(
               shipped=True,
               state='received',
               shipped_on=datetime.date.today - datetime.timedelta(days=4),
               received_on=datetime.date.today,
               received_by=factory.SubFactory(CustomerFactory),
           )

   >>> OrderFactory(received=True)
   <Order: shipped by John Doe on 2016-03-20, received by Joan Smith on 2016-04-02>

A "Trait" might be overridden in "Factory" subclasses:

   class LocalOrderFactory(OrderFactory):

       class Params:
           received = factory.Trait(
               shipped=True,
               state='received',
               shipped_on=datetime.date.today - datetime.timedelta(days=1),
               received_on=datetime.date.today,
               received_by=factory.SubFactory(CustomerFactory),
           )

   >>> LocalOrderFactory(received=True)
   <Order: shipped by John Doe on 2016-04-01, received by Joan Smith on 2016-04-02>

Note: When overriding a "Trait", the whole declaration **MUST** be
  replaced.


Strategies
----------

factory_boy supports two main strategies for generating instances,
plus stubs.

factory.BUILD_STRATEGY

   The ‘build’ strategy is used when an instance should be created,
   but not persisted to any datastore.

   It is usually a simple call to the "__init__()" method of the
   "model" class.

factory.CREATE_STRATEGY

   The ‘create’ strategy builds and saves an instance into its
   appropriate datastore.

   This is the default strategy of factory_boy; it would typically
   instantiate an object, then save it:

      >>> obj = self._associated_class(*args, **kwargs)
      >>> obj.save()
      >>> return obj

   Warning: For backward compatibility reasons, the default
     behaviour of factory_boy is to call
     "MyClass.objects.create(*args, **kwargs)" when using the "create"
     strategy.That policy will be used if the "associated class" has
     an "objects" attribute *and* the "_create()" classmethod of the
     "Factory" wasn’t overridden.

factory.use_strategy(strategy)

   *Decorator*

   Change the default strategy of the decorated "Factory" to the
   chosen "strategy":

      @use_strategy(factory.BUILD_STRATEGY)
      class UserBuildingFactory(UserFactory):
          pass

factory.STUB_STRATEGY

   The ‘stub’ strategy is an exception in the factory_boy world: it
   doesn’t return an instance of the "model" class, and actually
   doesn’t require one to be present.

   Instead, it returns an instance of "StubObject" whose attributes
   have been set according to the declarations.

class factory.StubObject(object)

   A plain, stupid object. No method, no helpers, simply a bunch of
   attributes.

   It is typically instantiated, then has its attributes set:

      >>> obj = StubObject()
      >>> obj.x = 1
      >>> obj.y = 2

class factory.StubFactory(Factory)

   An "abstract" "Factory", with a default strategy set to
   "STUB_STRATEGY".

factory.debug(logger='factory', stream=None)

   Parameters:
      * **logger** (*str*) – The name of the logger to enable debug
        for

      * **stream** (*file*) – The stream to send debug output to,
        defaults to "sys.stderr"

   Context manager to help debugging factory_boy behavior. It will
   temporarily put the target logger (e.g "'factory'") in debug mode,
   sending all output to :obj`~sys.stderr`; upon leaving the context,
   the logging levels are reset.

   A typical use case is to understand what happens during a single
   factory call:

      with factory.debug():
          obj = TestModel2Factory()

   This will yield messages similar to those (artificial indentation):

      BaseFactory: Preparing tests.test_using.TestModel2Factory(extra={})
        LazyStub: Computing values for tests.test_using.TestModel2Factory(two=<OrderedDeclarationWrapper for <factory.declarations.SubFactory object at 0x1e15610>>)
          SubFactory: Instantiating tests.test_using.TestModelFactory(__containers=(<LazyStub for tests.test_using.TestModel2Factory>,), one=4), create=True
          BaseFactory: Preparing tests.test_using.TestModelFactory(extra={'__containers': (<LazyStub for tests.test_using.TestModel2Factory>,), 'one': 4})
            LazyStub: Computing values for tests.test_using.TestModelFactory(one=4)
            LazyStub: Computed values, got tests.test_using.TestModelFactory(one=4)
          BaseFactory: Generating tests.test_using.TestModelFactory(one=4)
        LazyStub: Computed values, got tests.test_using.TestModel2Factory(two=<tests.test_using.TestModel object at 0x1e15410>)
      BaseFactory: Generating tests.test_using.TestModel2Factory(two=<tests.test_using.TestModel object at 0x1e15410>)


Declarations
============


Faker
-----

class factory.Faker(provider, locale=None, **kwargs)

   In order to easily define realistic-looking factories, use the
   "Faker" attribute declaration.

   This is a wrapper around faker; its argument is the name of a
   "faker" provider:

      class UserFactory(factory.Factory):
          class Meta:
              model = User

          name = factory.Faker('name')

      >>> user = UserFactory()
      >>> user.name
      'Lucy Cechtelar'

   locale

      If a custom locale is required for one specific field, use the
      "locale" parameter:

         class UserFactory(factory.Factory):
             class Meta:
                 model = User

             name = factory.Faker('name', locale='fr_FR')

         >>> user = UserFactory()
         >>> user.name
         'Jean Valjean'

   classmethod override_default_locale(cls, locale)

      If the locale needs to be overridden for a whole test, use
      "override_default_locale()":

         >>> with factory.Faker.override_default_locale('de_DE'):
         ...     UserFactory()
         <User: Johannes Brahms>

   classmethod add_provider(cls, locale=None)

      Some projects may need to fake fields beyond those provided by
      "faker"; in such cases, use "factory.Faker.add_provider()" to
      declare additional providers for those fields:

         factory.Faker.add_provider(SmileyProvider)

         class FaceFactory(factory.Factory):
             class Meta:
                 model = Face

             smiley = factory.Faker('smiley')


LazyFunction
------------

class factory.LazyFunction(method_to_call)

The "LazyFunction" is the simplest case where the value of an
attribute does not depend on the object being built.

It takes as argument a method to call (function, lambda…); that method
should not take any argument, though keyword arguments are safe but
unused, and return a value.

   class LogFactory(factory.Factory):
       class Meta:
           model = models.Log

       timestamp = factory.LazyFunction(datetime.now)

   >>> LogFactory()
   <Log: log at 2016-02-12 17:02:34>

   >>> # The LazyFunction can be overriden
   >>> LogFactory(timestamp=now - timedelta(days=1))
   <Log: log at 2016-02-11 17:02:34>

"LazyFunction" is also useful for assigning copies of mutable objects
(like lists) to an object’s property. Example:

   DEFAULT_TEAM = ['Player1', 'Player2']

   class TeamFactory(factory.Factory):
       class Meta:
           model = models.Team

       teammates = factory.LazyFunction(lambda: list(DEFAULT_TEAM))


Decorator
~~~~~~~~~

The class "LazyFunction" does not provide a decorator.

For complex cases, use "LazyAttribute.lazy_attribute()" directly.


LazyAttribute
-------------

class factory.LazyAttribute(method_to_call)

The "LazyAttribute" is a simple yet extremely powerful building brick
for extending a "Factory".

It takes as argument a method to call (usually a lambda); that method
should accept the object being built as sole argument, and return a
value.

   class UserFactory(factory.Factory):
       class Meta:
           model = User

       username = 'john'
       email = factory.LazyAttribute(lambda o: '%s@example.com' % o.username)

   >>> u = UserFactory()
   >>> u.email
   'john@example.com'

   >>> u = UserFactory(username='leo')
   >>> u.email
   'leo@example.com'

The object passed to "LazyAttribute" is not an instance of the target
class, but instead a "Resolver": a temporary container that computes
the value of all declared fields.


Decorator
~~~~~~~~~

factory.lazy_attribute()

If a simple lambda isn’t enough, you may use the "lazy_attribute()"
decorator instead.

This decorates an instance method that should take a single argument,
"self"; the name of the method will be used as the name of the
attribute to fill with the return value of the method:

   class UserFactory(factory.Factory)
       class Meta:
           model = User

       name = u"Jean"

       @factory.lazy_attribute
       def email(self):
           # Convert to plain ascii text
           clean_name = (unicodedata.normalize('NFKD', self.name)
                           .encode('ascii', 'ignore')
                           .decode('utf8'))
           return u'%s@example.com' % clean_name

   >>> joel = UserFactory(name=u"Joël")
   >>> joel.email
   u'joel@example.com'


Sequence
--------

class factory.Sequence(lambda, type=int)

If a field should be unique, and thus different for all built
instances, use a "Sequence".

This declaration takes a single argument, a function accepting a
single parameter - the current sequence counter - and returning the
related value.

Note: An extra kwarg argument, "type", may be provided. This feature
  was deprecated in 1.3.0 and will be removed in 2.0.0.

   class UserFactory(factory.Factory)
       class Meta:
           model = User

       phone = factory.Sequence(lambda n: '123-555-%04d' % n)

   >>> UserFactory().phone
   '123-555-0001'
   >>> UserFactory().phone
   '123-555-0002'


Decorator
~~~~~~~~~

factory.sequence()

As with "lazy_attribute()", a decorator is available for complex
situations.

"sequence()" decorates an instance method, whose "self" method will
actually be the sequence counter - this might be confusing:

   class UserFactory(factory.Factory)
       class Meta:
           model = User

       @factory.sequence
       def phone(n):
           a = n // 10000
           b = n % 10000
           return '%03d-555-%04d' % (a, b)

   >>> UserFactory().phone
   '000-555-9999'
   >>> UserFactory().phone
   '001-555-0000'


Sharing
~~~~~~~

The sequence counter is shared across all "Sequence" attributes of the
"Factory":

   class UserFactory(factory.Factory):
       class Meta:
           model = User

       phone = factory.Sequence(lambda n: '%04d' % n)
       office = factory.Sequence(lambda n: 'A23-B%03d' % n)

   >>> u = UserFactory()
   >>> u.phone, u.office
   '0041', 'A23-B041'
   >>> u2 = UserFactory()
   >>> u2.phone, u2.office
   '0042', 'A23-B042'


Inheritance
~~~~~~~~~~~

When a "Factory" inherits from another "Factory" and the *model* of
the subclass inherits from the *model* of the parent, the sequence
counter is shared across the "Factory" classes:

   class UserFactory(factory.Factory):
       class Meta:
           model = User

       phone = factory.Sequence(lambda n: '123-555-%04d' % n)


   class EmployeeFactory(UserFactory):
       office_phone = factory.Sequence(lambda n: '%04d' % n)

   >>> u = UserFactory()
   >>> u.phone
   '123-555-0001'

   >>> e = EmployeeFactory()
   >>> e.phone, e.office_phone
   '123-555-0002', '0002'

   >>> u2 = UserFactory()
   >>> u2.phone
   '123-555-0003'


Forcing a sequence counter
~~~~~~~~~~~~~~~~~~~~~~~~~~

If a specific value of the sequence counter is required for one
instance, the "__sequence" keyword argument should be passed to the
factory method.

This will force the sequence counter during the call, without altering
the class-level value.

   class UserFactory(factory.Factory):
       class Meta:
           model = User

       uid = factory.Sequence(int)

   >>> UserFactory()
   <User: 0>
   >>> UserFactory()
   <User: 1>
   >>> UserFactory(__sequence=42)
   <User: 42>

Warning: The impact of setting "__sequence=n" on a "_batch" call is
  undefined. Each generated instance may share a same counter, or use
  incremental values starting from the forced value.


LazyAttributeSequence
---------------------

class factory.LazyAttributeSequence(method_to_call)

The "LazyAttributeSequence" declaration merges features of "Sequence"
and "LazyAttribute".

It takes a single argument, a function whose two parameters are, in
order:

* The object being built

* The sequence counter

   class UserFactory(factory.Factory):
       class Meta:
           model = User

       login = 'john'
       email = factory.LazyAttributeSequence(lambda o, n: '%s@s%d.example.com' % (o.login, n))

   >>> UserFactory().email
   'john@s1.example.com'
   >>> UserFactory(login='jack').email
   'jack@s2.example.com'


Decorator
~~~~~~~~~

factory.lazy_attribute_sequence(method_to_call)

As for "lazy_attribute()" and "sequence()", the
"lazy_attribute_sequence()" handles more complex cases:

   class UserFactory(factory.Factory):
       class Meta:
           model = User

       login = 'john'

       @lazy_attribute_sequence
       def email(self, n):
           bucket = n % 10
           return '%s@s%d.example.com' % (self.login, bucket)


SubFactory
----------

class factory.SubFactory(factory, **kwargs)

This attribute declaration calls another "Factory" subclass, selecting
the same build strategy and collecting extra kwargs in the process.

The "SubFactory" attribute should be called with:

* A "Factory" subclass as first argument, or the fully qualified
  import path to that "Factory" (see Circular imports)

* An optional set of keyword arguments that should be passed when
  calling that factory

Note: When passing an actual "Factory" for the "factory" argument,
  make sure to pass the class and not instance (i.e no "()" after the
  class):

     class FooFactory(factory.Factory):
         class Meta:
             model = Foo

         bar = factory.SubFactory(BarFactory)  # Not BarFactory()


Definition
~~~~~~~~~~

   # A standard factory
   class UserFactory(factory.Factory):
       class Meta:
           model = User

       # Various fields
       first_name = 'John'
       last_name = factory.Sequence(lambda n: 'D%se' % ('o' * n))  # De, Doe, Dooe, Doooe, ...
       email = factory.LazyAttribute(lambda o: '%s.%s@example.org' % (o.first_name.lower(), o.last_name.lower()))

   # A factory for an object with a 'User' field
   class CompanyFactory(factory.Factory):
       class Meta:
           model = Company

       name = factory.Sequence(lambda n: 'FactoryBoyz' + 'z' * n)

       # Let's use our UserFactory to create that user, and override its first name.
       owner = factory.SubFactory(UserFactory, first_name='Jack')


Calling
~~~~~~~

The wrapping factory will call of the inner factory:

   >>> c = CompanyFactory()
   >>> c
   <Company: FactoryBoyz>

   # Notice that the first_name was overridden
   >>> c.owner
   <User: Jack De>
   >>> c.owner.email
   jack.de@example.org

Fields of the "SubFactory" may be overridden from the external
factory:

   >>> c = CompanyFactory(owner__first_name='Henry')
   >>> c.owner
   <User: Henry Doe>

   # Notice that the updated first_name was propagated to the email LazyAttribute.
   >>> c.owner.email
   henry.doe@example.org

   # It is also possible to override other fields of the SubFactory
   >>> c = CompanyFactory(owner__last_name='Jones')
   >>> c.owner
   <User: Henry Jones>
   >>> c.owner.email
   henry.jones@example.org


Strategies
~~~~~~~~~~

The strategy chosen for the external factory will be propagated to all
subfactories:

   >>> c = CompanyFactory()
   >>> c.pk            # Saved to the database
   3
   >>> c.owner.pk      # Saved to the database
   8

   >>> c = CompanyFactory.build()
   >>> c.pk            # Not saved
   None
   >>> c.owner.pk      # Not saved either
   None


Circular imports
~~~~~~~~~~~~~~~~

Some factories may rely on each other in a circular manner. This issue
can be handled by passing the absolute import path to the target
"Factory" to the "SubFactory".

New in version 1.3.0.

   class UserFactory(factory.Factory):
       class Meta:
           model = User

       username = 'john'
       main_group = factory.SubFactory('users.factories.GroupFactory')

   class GroupFactory(factory.Factory):
       class Meta:
           model = Group

       name = "MyGroup"
       owner = factory.SubFactory(UserFactory)

Obviously, such circular relationships require careful handling of
loops:

   >>> owner = UserFactory(main_group=None)
   >>> UserFactory(main_group__owner=owner)
   <john (group: MyGroup)>


SelfAttribute
-------------

class factory.SelfAttribute(dotted_path_to_attribute)

Some fields should reference another field of the object being
constructed, or an attribute thereof.

This is performed by the "SelfAttribute" declaration. That declaration
takes a single argument, a dot-delimited path to the attribute to
fetch:

   class UserFactory(factory.Factory):
       class Meta:
           model = User

       birthdate = factory.Sequence(lambda n: datetime.date(2000, 1, 1) + datetime.timedelta(days=n))
       birthmonth = factory.SelfAttribute('birthdate.month')

   >>> u = UserFactory()
   >>> u.birthdate
   date(2000, 3, 15)
   >>> u.birthmonth
   3


Parents
~~~~~~~

When used in conjunction with "SubFactory", the "SelfAttribute" gains
an “upward” semantic through the double-dot notation, as used in
Python imports.

"factory.SelfAttribute('..country.language')" means “Select the
"language" of the "country" of the "Factory" calling me”.

   class UserFactory(factory.Factory):
       class Meta:
           model = User

       language = 'en'


   class CompanyFactory(factory.Factory):
       class Meta:
           model = Company

       country = factory.SubFactory(CountryFactory)
       owner = factory.SubFactory(UserFactory, language=factory.SelfAttribute('..country.language'))

   >>> company = CompanyFactory()
   >>> company.country.language
   'fr'
   >>> company.owner.language
   'fr'

Obviously, this “follow parents” ability also handles overriding some
attributes on call:

   >>> company = CompanyFactory(country=china)
   >>> company.owner.language
   'cn'

This feature is also available to "LazyAttribute" and
"LazyAttributeSequence", through the "factory_parent" attribute of the
passed-in object:

   class CompanyFactory(factory.Factory):
       class Meta:
           model = Company
       country = factory.SubFactory(CountryFactory)
       owner = factory.SubFactory(UserFactory,
           language=factory.LazyAttribute(lambda user: user.factory_parent.country.language),
       )


Iterator
--------

class factory.Iterator(iterable, cycle=True, getter=None)

   The "Iterator" declaration takes successive values from the given
   iterable. When it is exhausted, it starts again from zero (unless
   "cycle=False").

   cycle

      The "cycle" argument is only useful for advanced cases, where
      the provided iterable has no end (as wishing to cycle it means
      storing values in memory…).

      New in version 1.3.0: The "cycle" argument is available as of
      v1.3.0; previous versions had a behaviour equivalent to
      "cycle=False".

   getter

      A custom function called on each value returned by the iterable.
      See the Getter section for details.

      New in version 1.3.0.

   reset()

      Reset the internal iterator used by the attribute, so that the
      next value will be the first value generated by the iterator.

      May be called several times.

Each call to the factory will receive the next value from the
iterable:

   class UserFactory(factory.Factory)
       lang = factory.Iterator(['en', 'fr', 'es', 'it', 'de'])

   >>> UserFactory().lang
   'en'
   >>> UserFactory().lang
   'fr'

When a value is passed in for the argument, the iterator will *not* be
advanced:

   >>> UserFactory().lang
   'en'
   >>> UserFactory(lang='cn').lang
   'cn'
   >>> UserFactory().lang
   'fr'


Getter
~~~~~~

Some situations may reuse an existing iterable, using only some
component. This is handled by the "getter" attribute: this is a
function that accepts as sole parameter a value from the iterable, and
returns an adequate value.

   class UserFactory(factory.Factory):
       class Meta:
           model = User

       # CATEGORY_CHOICES is a list of (key, title) tuples
       category = factory.Iterator(User.CATEGORY_CHOICES, getter=lambda c: c[0])


Decorator
~~~~~~~~~

factory.iterator(func)

When generating items of the iterator gets too complex for a simple
list comprehension, use the "iterator()" decorator:

Warning: The decorated function takes **no** argument, notably no
  "self" parameter.

   class UserFactory(factory.Factory):
       class Meta:
           model = User

       @factory.iterator
       def name():
           with open('test/data/names.dat', 'r') as f:
               for line in f:
                   yield line

Warning: Values from the underlying iterator are *kept* in memory;
  once the initial iterator has been emptied, saved values are used
  instead of executing the function instead.Use
  "factory.Iterator(my_func, cycle=False)" to disable value recycling.


Resetting
~~~~~~~~~

In order to start back at the first value in an "Iterator", simply
call the "reset()" method of that attribute (accessing it from the
bare "Factory" subclass):

   >>> UserFactory().lang
   'en'
   >>> UserFactory().lang
   'fr'
   >>> UserFactory.lang.reset()
   >>> UserFactory().lang
   'en'


Dict and List
-------------

When a factory expects lists or dicts as arguments, such values can be
generated through the whole range of factory_boy declarations, with
the "Dict" and "List" attributes:

class factory.Dict(params[, dict_factory=factory.DictFactory])

   The "Dict" class is used for dict-like attributes. It receives as
   non-keyword argument a dictionary of fields to define, whose value
   may be any factory-enabled declarations:

      class UserFactory(factory.Factory):
          class Meta:
              model = User

          is_superuser = False
          roles = factory.Dict({
              'role1': True,
              'role2': False,
              'role3': factory.Iterator([True, False]),
              'admin': factory.SelfAttribute('..is_superuser'),
          })

   Note: Declarations used as a "Dict" values are evaluated within
     that "Dict"’s context; this means that you must use the "..foo"
     syntax to access fields defined at the factory level.On the other
     hand, the "Sequence" counter is aligned on the containing
     factory’s one.

   The "Dict" behaviour can be tuned through the following parameters:

   dict_factory

      The actual factory to use for generating the dict can be set as
      a keyword argument, if an exotic dictionary-like object
      (SortedDict, …) is required.

class factory.List(items[, list_factory=factory.ListFactory])

   The "List" can be used for list-like attributes.

   Internally, the fields are converted into a "index=value" dict,
   which makes it possible to override some values at use time:

      class UserFactory(factory.Factory):
          class Meta:
              model = User

          flags = factory.List([
              'user',
              'active',
              'admin',
          ])

      >>> u = UserFactory(flags__2='superadmin')
      >>> u.flags
      ['user', 'active', 'superadmin']

   The "List" behaviour can be tuned through the following parameters:

   list_factory

      The actual factory to use for generating the list can be set as
      a keyword argument, if another type (tuple, set, …) is required.


Maybe
-----

class factory.Maybe(decider, yes_declaration, no_declaration)

Sometimes, the way to build a given field depends on the value of
another, for instance of a parameter.

In those cases, use the "Maybe" declaration: it takes the name of a
“decider” boolean field, and two declarations; depending on the value
of the field whose name is held in the ‘decider’ parameter, it will
apply the effects of one or the other declaration:

   class UserFactory(factory.Factory):
       class Meta:
           model = User

       is_active = True
       deactivation_date = factory.Maybe(
           'is_active',
           yes_declaration=None,
           no_declaration=factory.fuzzy.FuzzyDateTime(timezone.now() - datetime.timedelta(days=10)),
       )

   >>> u = UserFactory(is_active=True)
   >>> u.deactivation_date
   None
   >>> u = UserFactory(is_active=False)
   >>> u.deactivation_date
   datetime.datetime(2017, 4, 1, 23, 21, 23, tzinfo=UTC)

Note: If the condition for the decider is complex, use a
  "LazyAttribute" defined in the "Params" section of your factory to
  handle the computation.


Post-generation hooks
---------------------

Some objects expect additional method calls or complex processing for
proper definition. For instance, a "User" may need to have a related
"Profile", where the "Profile" is built from the "User" object.

To support this pattern, factory_boy provides the following tools:
   * "PostGenerationMethodCall": allows you to hook a particular
     attribute to a function call

   * "PostGeneration": this class allows calling a given function
     with the generated object as argument

   * "post_generation()": decorator performing the same functions as
     "PostGeneration"

   * "RelatedFactory": this builds or creates a given factory
     *after* building/creating the first Factory.

Post-generation hooks are called in the same order they are declared
in the factory class, so that functions can rely on the side effects
applied by the previous post-generation hook.


Extracting parameters
---------------------

All post-building hooks share a common base for picking parameters
from the set of attributes passed to the "Factory".

For instance, a "PostGeneration" hook is declared as "post":

   class SomeFactory(factory.Factory):
       class Meta:
           model = SomeObject

       @post_generation
       def post(obj, create, extracted, **kwargs):
           obj.set_origin(create)

When calling the factory, some arguments will be extracted for this
method:

* If a "post" argument is passed, it will be passed as the
  "extracted" field

* Any argument starting with "post__XYZ" will be extracted, its
  "post__" prefix removed, and added to the kwargs passed to the post-
  generation hook.

Extracted arguments won’t be passed to the "model" class.

Thus, in the following call:

   >>> SomeFactory(
       post=1,
       post_x=2,
       post__y=3,
       post__z__t=42,
   )

The "post" hook will receive "1" as "extracted" and "{'y': 3, 'z__t':
42}" as keyword arguments; "{'post_x': 2}" will be passed to
"SomeFactory._meta.model".


RelatedFactory
--------------

class factory.RelatedFactory(factory, factory_related_name='', **kwargs)

   A "RelatedFactory" behaves mostly like a "SubFactory", with the
   main difference that the related "Factory" will be generated
   *after* the base "Factory".

   factory

      As for "SubFactory", the "factory" argument can be:

      * A "Factory" subclass

      * Or the fully qualified path to a "Factory" subclass (see
        Circular imports for details)

   name

      The generated object (where the "RelatedFactory" attribute will
      set) may be passed to the related factory if the
      "factory_related_name" parameter is set.

      It will be passed as a keyword argument, using the "name" value
      as keyword:

Note: When passing an actual "Factory" for the "factory" argument,
  make sure to pass the class and not instance (i.e no "()" after the
  class):

     class FooFactory(factory.Factory):
         class Meta:
             model = Foo

         bar = factory.RelatedFactory(BarFactory)  # Not BarFactory()

   class CityFactory(factory.Factory):
       class Meta:
           model = City

       capital_of = None
       name = "Toronto"

   class CountryFactory(factory.Factory):
       class Meta:
           model = Country

       lang = 'fr'
       capital_city = factory.RelatedFactory(CityFactory, 'capital_of', name="Paris")

   >>> france = CountryFactory()
   >>> City.objects.get(capital_of=france)
   <City: Paris>

Extra kwargs may be passed to the related factory, through the usual
"ATTR__SUBATTR" syntax:

   >>> england = CountryFactory(lang='en', capital_city__name="London")
   >>> City.objects.get(capital_of=england)
   <City: London>

If a value is passed for the "RelatedFactory" attribute, this disables
"RelatedFactory" generation:

   >>> france = CountryFactory()
   >>> paris = City.objects.get()
   >>> paris
   <City: Paris>
   >>> reunion = CountryFactory(capital_city=paris)
   >>> City.objects.count()  # No new capital_city generated
   1
   >>> guyane = CountryFactory(capital_city=paris, capital_city__name='Kourou')
   >>> City.objects.count()  # No new capital_city generated, ``name`` ignored.
   1

Note: The target of the "RelatedFactory" is evaluated *after* the
  initial factory has been instantiated. However, the build context is
  passed down to that factory; this means that calls to
  "factory.SelfAttribute" *can* go back to the calling factorry’s
  context:

     class CountryFactory(factory.Factory):
         class Meta:
             model = Country

         lang = 'fr'
         capital_city = factory.RelatedFactory(CityFactory, 'capital_of',
             # Would also work with SelfAttribute('capital_of.lang')
             main_lang=factory.SelfAttribute('..lang'),
         )


PostGeneration
--------------

class factory.PostGeneration(callable)

The "PostGeneration" declaration performs actions once the model
object has been generated.

Its sole argument is a callable, that will be called once the base
object has
   been generated.

Once the base object has been generated, the provided callable will be
called as "callable(obj, create, extracted, **kwargs)", where:

* "obj" is the base object previously generated

* "create" is a boolean indicating which strategy was used

* "extracted" is "None" unless a value was passed in for the
  "PostGeneration" declaration at "Factory" declaration time

* "kwargs" are any extra parameters passed as "attr__key=value" when
  calling the "Factory":

   class UserFactory(factory.Factory):
       class Meta:
           model = User

       login = 'john'
       make_mbox = factory.PostGeneration(
               lambda obj, create, extracted, **kwargs: os.makedirs(obj.login))


Decorator
~~~~~~~~~

factory.post_generation()

A decorator is also provided, decorating a single method accepting the
same "obj", "created", "extracted" and keyword arguments as
"PostGeneration".

   class UserFactory(factory.Factory):
       class Meta:
           model = User

       login = 'john'

       @factory.post_generation
       def mbox(self, create, extracted, **kwargs):
           if not create:
               return
           path = extracted or os.path.join('/tmp/mbox/', self.login)
           os.path.makedirs(path)
           return path

   >>> UserFactory.build()                  # Nothing was created
   >>> UserFactory.create()                 # Creates dir /tmp/mbox/john
   >>> UserFactory.create(login='jack')     # Creates dir /tmp/mbox/jack
   >>> UserFactory.create(mbox='/tmp/alt')  # Creates dir /tmp/alt


PostGenerationMethodCall
------------------------

class factory.PostGenerationMethodCall(method_name, *arg, **kwargs)

   The "PostGenerationMethodCall" declaration will call a method on
   the generated object just after instantiation. This declaration
   class provides a friendly means of generating attributes of a
   factory instance during initialization. The declaration is created
   using the following arguments:

   method_name

      The name of the method to call on the "model" object

   arg

      The default, optional, positional argument to pass to the method
      given in "method_name"

   kwargs

      The default set of keyword arguments to pass to the method given
      in "method_name"

Once the factory instance has been generated, the method specified in
"method_name" will be called on the generated object with any
arguments specified in the "PostGenerationMethodCall" declaration, by
default.

For example, to set a default password on a generated User instance
during instantiation, we could make a declaration for a "password"
attribute like below:

   class UserFactory(factory.Factory):
       class Meta:
           model = User

       username = 'user'
       password = factory.PostGenerationMethodCall('set_password',
                                                   'defaultpassword')

When we instantiate a user from the "UserFactory", the factory will
create a password attribute by calling
"User.set_password('defaultpassword')". Thus, by default, our users
will have a password set to "'defaultpassword'".

   >>> u = UserFactory()                             # Calls user.set_password('defaultpassword')
   >>> u.check_password('defaultpassword')
   True

If the "PostGenerationMethodCall" declaration contained no arguments
or one argument, an overriding value can be passed directly to the
method through a keyword argument matching the attribute name. For
example we can override the default password specified in the
declaration above by simply passing in the desired password as a
keyword argument to the factory during instantiation.

   >>> other_u = UserFactory(password='different')   # Calls user.set_password('different')
   >>> other_u.check_password('defaultpassword')
   False
   >>> other_u.check_password('different')
   True

Note: For Django models, unless the object method called by
  "PostGenerationMethodCall" saves the object back to the database, we
  will have to explicitly remember to save the object back if we
  performed a "create()".

     >>> u = UserFactory.create()  # u.password has not been saved back to the database
     >>> u.save()                  # we must remember to do it ourselves

  We can avoid this by subclassing from "DjangoModelFactory", instead,
  e.g.,

     class UserFactory(factory.django.DjangoModelFactory):
         class Meta:
             model = User

         username = 'user'
         password = factory.PostGenerationMethodCall('set_password',
                                                     'defaultpassword')

Warning: In order to keep a consistent and simple API, a
  "PostGenerationMethodCall" allows *at most one* positional argument;
  all other parameters should be passed as keyword arguments.

Keywords extracted from the factory arguments are merged into the
defaults present in the "PostGenerationMethodCall" declaration.

   >>> UserFactory(password__disabled=True)    # Calls user.set_password('', 'sha1', disabled=True)


Module-level functions
======================

Beyond the "Factory" class and the various Declarations classes and
methods, factory_boy exposes a few module-level functions, mostly
useful for lightweight factory generation.


Lightweight factory declaration
-------------------------------

factory.make_factory(klass, **kwargs)

   The "make_factory()" function takes a class, declarations as
   keyword arguments, and generates a new "Factory" for that class
   accordingly:

      UserFactory = make_factory(User,
          login='john',
          email=factory.LazyAttribute(lambda u: '%s@example.com' % u.login),
      )

      # This is equivalent to:

      class UserFactory(factory.Factory):
          class Meta:
              model = User

          login = 'john'
          email = factory.LazyAttribute(lambda u: '%s@example.com' % u.login)

   An alternate base class to "Factory" can be specified in the
   "FACTORY_CLASS" argument:

      UserFactory = make_factory(models.User,
          login='john',
          email=factory.LazyAttribute(lambda u: '%s@example.com' % u.login),
          FACTORY_CLASS=factory.django.DjangoModelFactory,
      )

      # This is equivalent to:

      class UserFactory(factory.django.DjangoModelFactory):
          class Meta:
              model = models.User

          login = 'john'
          email = factory.LazyAttribute(lambda u: '%s@example.com' % u.login)

   New in version 2.0.0: The "FACTORY_CLASS" kwarg was added in 2.0.0.


Instance building
-----------------

The "factory" module provides a bunch of shortcuts for creating a
factory and extracting instances from them:

factory.build(klass, FACTORY_CLASS=None, **kwargs)

factory.build_batch(klass, size, FACTORY_CLASS=None, **kwargs)

   Create a factory for "klass" using declarations passed in kwargs;
   return an instance built from that factory, or a list of "size"
   instances (for "build_batch()").

   Parameters:
      * **klass** (*class*) – Class of the instance to build

      * **size** (*int*) – Number of instances to build

      * **kwargs** – Declarations to use for the generated factory

      * **FACTORY_CLASS** – Alternate base class (instead of
        "Factory")

factory.create(klass, FACTORY_CLASS=None, **kwargs)

factory.create_batch(klass, size, FACTORY_CLASS=None, **kwargs)

   Create a factory for "klass" using declarations passed in kwargs;
   return an instance created from that factory, or a list of "size"
   instances (for "create_batch()").

   Parameters:
      * **klass** (*class*) – Class of the instance to create

      * **size** (*int*) – Number of instances to create

      * **kwargs** – Declarations to use for the generated factory

      * **FACTORY_CLASS** – Alternate base class (instead of
        "Factory")

factory.stub(klass, FACTORY_CLASS=None, **kwargs)

factory.stub_batch(klass, size, FACTORY_CLASS=None, **kwargs)

   Create a factory for "klass" using declarations passed in kwargs;
   return an instance stubbed from that factory, or a list of "size"
   instances (for "stub_batch()").

   Parameters:
      * **klass** (*class*) – Class of the instance to stub

      * **size** (*int*) – Number of instances to stub

      * **kwargs** – Declarations to use for the generated factory

      * **FACTORY_CLASS** – Alternate base class (instead of
        "Factory")

factory.generate(klass, strategy, FACTORY_CLASS=None, **kwargs)

factory.generate_batch(klass, strategy, size, FACTORY_CLASS=None, **kwargs)

   Create a factory for "klass" using declarations passed in kwargs;
   return an instance generated from that factory with the "strategy"
   strategy, or a list of "size" instances (for "generate_batch()").

   Parameters:
      * **klass** (*class*) – Class of the instance to generate

      * **strategy** (*str*) – The strategy to use

      * **size** (*int*) – Number of instances to generate

      * **kwargs** – Declarations to use for the generated factory

      * **FACTORY_CLASS** – Alternate base class (instead of
        "Factory")

factory.simple_generate(klass, create, FACTORY_CLASS=None, **kwargs)

factory.simple_generate_batch(klass, create, size, FACTORY_CLASS=None, **kwargs)

   Create a factory for "klass" using declarations passed in kwargs;
   return an instance generated from that factory according to the
   "create" flag, or a list of "size" instances (for
   "simple_generate_batch()").

   Parameters:
      * **klass** (*class*) – Class of the instance to generate

      * **create** (*bool*) – Whether to build ("False") or create
        ("True") instances

      * **size** (*int*) – Number of instances to generate

      * **kwargs** – Declarations to use for the generated factory

      * **FACTORY_CLASS** – Alternate base class (instead of
        "Factory")
