1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166
|
Factory Configuration
=====================
Factories can be configured by setting special dunder (double underscore) class attributes.
You can read the reference for these in the API reference for
:class:`BaseFactory <polyfactory.factories.base.BaseFactory>`. Below we discuss some configuration options in some depth.
Seeding Randomness
------------------
.. literalinclude:: /examples/configuration/test_example_1.py
:caption: Seeding the factory's 'random.Random'
:language: python
Seeding randomness allows you to control the random generation of values produced by the factory. This affects all :class:`random.Random`
methods as well as faker.
Setting Random
--------------
.. literalinclude:: /examples/configuration/test_example_2.py
:caption: Setting the factory's 'random.Random'
:language: python
This configuration option is functionally identical to the previous, with the difference being that here we are setting
the actual instance of :class:`random.Random`. This is useful when embedding factories inside more complex logic, such as in
other libraries, as well as when factories are being dynamically generated.
Setting Faker
-------------
.. literalinclude:: /examples/configuration/test_example_3.py
:caption: Setting the factory's 'Faker'
:language: python
In the above example we are setting the factory's instance of ``Faker`` and configure its locale to Spanish. Because
we are also setting the random seed value, the results of the test are deterministic.
.. note::
To understand why we are using a classmethod here, see the documentation about :doc:`factory fields </usage/fields>`.
Persistence Handlers
--------------------
Factory classes have four optional persistence methods:
- ``.create_sync(**kwargs)`` - builds and persists a single instance of the factory's model synchronously
- ``.create_batch_sync(size: int, **kwargs)`` - builds and persists a list of size n instances synchronously
- ``.create_async(**kwargs)`` - builds and persists a single instance of the factory's model asynchronously
- ``.create_batch_async(size: int, **kwargs)`` - builds and persists a list of size n instances asynchronously
To use these methods, you must first specify a sync and/or async persistence handlers for the factory:
.. literalinclude:: /examples/configuration/test_example_4.py
:caption: Defining and using persistence handlers.
:language: python
With the persistence handlers in place, you can now use all persistence methods.
.. note::
You do not need to define both persistence handlers. If you will only use sync or async persistence, you only need
to define the respective handler to use these methods.
Defining Default Factories
--------------------------
As explained in the section about dynamic factory generation in :doc:`declaring factories </usage/declaring_factories>`,
factories generate new factories for supported types dynamically. This process requires no intervention from the user.
Once a factory is generated, it is then cached and reused - when the same type is used.
For example, when build is called for the ``PersonFactory`` below, a ``PetFactory`` will be dynamically generated and reused:
.. literalinclude:: /examples/declaring_factories/test_example_5.py
:caption: Dynamic factory generation
:language: python
You can also control the default factory for a type by declaring a factory as the type default:
.. literalinclude:: /examples/configuration/test_example_5.py
:caption: Setting a factory as a type default.
:language: python
Randomized Collection Length
----------------------------
Set of fields that allow you to generate a collection with random lengths. By default only one item is generated.
.. literalinclude:: /examples/configuration/test_example_6.py
:caption: Randomized collection length
:language: python
Allow None Optionals
--------------------
Allow `None` to be generated as a value for types marked as optional. When set to `True`, the outputted value will be randomly chosen between `None` and other allowed types. By default, this is set to `True`.
By setting to `False`, then optional types will always be treated as the wrapped type:
.. literalinclude:: /examples/configuration/test_example_7.py
:caption: Disable Allow None Optionals
:language: python
Check Factory Fields
--------------------
When `__check_model__` is set to `True`, declaring fields on the factory that don't exist on the model will trigger an exception.
This is only true when fields are declared with ``Use``, ``PostGenerated``, ``Ignore`` and ``Require``.
Any other field definition will not be checked.
.. literalinclude:: /examples/configuration/test_example_8.py
:caption: Enable Check Factory Fields
:language: python
.. note::
The default for `__check_model__` is changed to `True` in v3. Set explicitly to disable this check.
Use Default Values
------------------
If ``__use_defaults__`` is set to ``True``, then the default value will be used instead of creating a random value
for a given field, provided there's a default value for that field.
By default, ``__use_defaults__`` is set to ``False.`` If you need more fine grained control, you can override the
:meth:`~polyfactory.factories.base.BaseFactory.should_use_default_value` classmethod.
.. note::
Setting ``__use_defaults__`` has no effect for ``TypedDictFactory`` since you cannot set default values for
``TypedDict``.
.. literalinclude:: /examples/configuration/test_example_9.py
:caption: Use Default Values
:language: python
Use Example Values (Pydantic >= V2)
-----------------------------------
If ``__use_examples__`` is set to ``True``, then a random value from examples attribute will be used for a given field,
provided there's a non-empty list of examples defined for that field.
By default, ``__use_examples__`` is set to ``False.``
.. literalinclude:: /examples/configuration/test_example_10.py
:caption: Use Examples Values
:language: python
Forward References
------------------
The ``__forward_references__`` configuration allows you to resolve forward references in type annotations.
This is useful when dealing with recursive types that cannot be resolved automatically.
By default, ``__forward_references__`` is set to an empty dictionary. You can provide a mapping of
forward reference names to their resolved types.
.. literalinclude:: /examples/configuration/test_example_11.py
:caption: Forward References Configuration
:language: python
.. note::
The Pydantic ModelFactory has a default forward reference mapping for ``JsonValue`` to resolve to ``str``
to avoid recursive issues with Pydantic's JsonValue type.
|